Beispiel #1
0
/** De-Initialise the Uart.
 *
 * BLEUART_Deinit()
 *	This function is called by the BLE stack (TRANSPORT layer) to de-initialise
 *	the UART layer. Eventual thread shall be terminated here.
 *	When this function succeed, the UART layer shall be fully de-initialised
 *
 *	This function is called during the BLESTCK_Deinit() process, failure here 
 *	will issue a failure in BLESTCK_Deinit()
 *
 * @todo implement this function
 *
 * @see BLESTCK_Deinit()
 *
 * @return The status of the operation:
 *	- BLESTATUS_SUCCESS indicates to the BLE stack that the UART have been
 *		successfully initialized
 *	- BLESTATUS_FAILED indicates to the BLE stack that the UART could not be
 *		initialized
 *	
 * @author Alexandre GIMARD
 */
BleStatus BLEUART_Deinit(void){
	// Add here specific code to execute during Stack De-Initialisation
	// in order to de-initialise the transport drivers
	//>
	/*close spi interface*/
    if(MQX_OK != fclose(spi_dev))
    {
    #ifdef LOCAL_LOG
        SYSTEM_Log("Unable to close communication channel\n");
    #endif        
        return BLESTATUS_FAILED;
    }
    /*power off em9301 from 74HC595*/
    if(MQX_OK != mux_74hc595_clear_bit(BSP_74HC595_0, BSP_74HC595_VBLE_3V3))
    {
    	return BLESTATUS_FAILED;
    }
    /*disable pin IRQ, destroy spi read task, semaphore*/
    _bsp_int_disable(lwgpio_int_get_vector(&SPI_IRQ_PIN));
    _int_install_isr(lwgpio_int_get_vector(&SPI_IRQ_PIN), _int_get_default_isr(), NULL);
    if(MQX_OK != _task_destroy(_task_get_id_from_name("SPI_READ")))
    {
    	return BLESTATUS_FAILED;
    }

    if(MQX_OK != _lwsem_destroy(&IRQ_SEM))
    {
    	return BLESTATUS_FAILED;
    }
    	//<
	return BLESTATUS_SUCCESS;
}
static void _ki2c_stop_detect_isr
(
    void              *parameter
)
{
    VKI2C_INFO_STRUCT_PTR io_info_ptr = parameter;
    I2C_MemMapPtr         i2c_ptr = io_info_ptr->I2C_PTR;
#if PSP_MQX_CPU_IS_COLDFIRE
    PCTL_MemMapPtr        pctl = (PCTL_MemMapPtr)io_info_ptr->PORT_BASE;
#elif PSP_MQX_CPU_IS_KINETIS
    PORT_MemMapPtr        pctl = (PORT_MemMapPtr)io_info_ptr->PORT_BASE;
#endif

#if PSP_MQX_CPU_IS_COLDFIRE
    pctl->IF |= (1 << io_info_ptr->SDA_PIN_NUM);
#elif PSP_MQX_CPU_IS_KINETIS
    pctl->PCR[io_info_ptr->SDA_PIN_NUM] |= PORT_PCR_ISF_MASK;
#endif
    
    if ((0 == (i2c_ptr->C1 & I2C_C1_MST_MASK)) &&
        (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;
            _bsp_int_disable(io_info_ptr->VECTOR);
            _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
    }
}
Beispiel #3
0
/*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 */
        void                          *io_info_ptr
    )
{
    DSPI_INFO_STRUCT_PTR               dspi_info_ptr = (DSPI_INFO_STRUCT_PTR)io_info_ptr;

    const uint32_t                     *vectors;
    int                                num_vectors;
    int                                i;

    if (NULL == dspi_info_ptr)
    {
        return SPI_ERROR_DEINIT_FAILED;
    }

    _dspi_deinit_low(dspi_info_ptr->DSPI_PTR);

    /* Uninstall interrupt service routines */
    num_vectors = _bsp_get_dspi_vectors(dspi_info_ptr->CHANNEL, &vectors);

    for (i=0; i<num_vectors; i++)
    {
        /* Disable interrupt on vector */
        _bsp_int_disable(vectors[i]);
        /* Install default isr routine */
        _int_install_isr(vectors[i], _int_get_default_isr(), NULL);
    }

    _lwsem_destroy(&dspi_info_ptr->EVENT_IO_FINISHED);

    _mem_free(dspi_info_ptr);
    return SPI_OK;
}
Beispiel #4
0
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)));
   }
}
Beispiel #5
0
_mqx_int _mtim16_timer_install_kernel
(
		/* [IN] the timer to initialize */
		uint8_t    timer,

		/* [IN] ticks per second */
		uint32_t   tickfreq,

		/* [IN] input clock speed in Hz */
		uint32_t   clk,

	    /* [IN] interrupt priority */
	    uint32_t priority,

		/* [IN] unmask the timer after installation */
		bool   unmask_timer
)
{
    uint32_t result;
    uint32_t period;
    _mqx_uint vector = _bsp_get_mtim16_vector(timer);

    if (vector == 0)
    {
        return MQX_INVALID_DEVICE;
    }

    _bsp_int_disable(vector);

    /* Set up tick timer */
    period = _mtim16_timer_init(timer, tickfreq, clk, FALSE);

    /* Install the timer interrupt handler */
    if (_int_install_isr(vector, _mtim16_kernel_isr, NULL) == NULL)
	{
		return MQX_TIMER_ISR_INSTALL_FAIL;
	}

    /* Initialize the timer interrupt */
    _time_set_timer_vector(_bsp_get_mtim16_vector(timer));
    _time_set_hwtick_function(_mtim16_get_hwticks, (void *) timer);
    _time_set_hwticks_per_tick(period);
    _time_set_ticks_per_sec(tickfreq);

    _bsp_int_init(vector, priority, 0, TRUE);
    
    _bsp_int_enable(vector);

    if (unmask_timer) {
    	_mtim16_unmask_int(timer);
    }

    return MQX_OK;

}
Beispiel #6
0
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;
   }
}
Beispiel #7
0
_mqx_int _mtim16_timer_install
(
  /* [IN] the timer to initialize */
  uint8_t    timer,

  /* [IN] ticks per second */
  uint32_t   tickfreq,

  /* [IN] input clock speed in Hz */
  uint32_t   clk,

  /* [IN] interrupt priority */
  uint32_t priority,

  INT_ISR_FPTR isr_ptr,
    
  /* [IN] unmask the timer after installation */
  bool   unmask_timer
)
{
    uint32_t result;
    _mqx_uint vector = _bsp_get_mtim16_vector(timer);

    if (vector == 0)
    {
        return MQX_INVALID_DEVICE;
    }

    _bsp_int_disable(vector);

    /* Set up tick timer */
    _mtim16_timer_init(timer, tickfreq, clk, FALSE);

    /* Install the timer interrupt handler */
    if (_int_install_isr(vector, isr_ptr, NULL) == NULL)
	{
		return MQX_TIMER_ISR_INSTALL_FAIL;
	}

    _bsp_int_init(vector, priority, 0, TRUE);
    
    _bsp_int_enable(vector);

    if (unmask_timer) {
    	_mtim16_unmask_int(timer);
    }
    
    return MQX_OK;
}
Beispiel #8
0
static int sample_timer_deinit()
{
    VQPIT_REG_STRUCT_PTR  qpit_ptr = sample_qpit_ptr;

    /* Stop the timer */
    qpit_ptr->TIMERS[SAMPLE_PIT_CH].TCTRL &= (~ QPIT_TCTRL_TIE);

    _bsp_int_disable(SAMPLE_INT);

    if(_lwevent_destroy(&sample_event) != MQX_OK) {
        return -1;
    }

    return 0;
}
uint32_t _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;
      
   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;
   }

#if BSPCFG_ENABLE_LEGACY_II2C_SLAVE
   /* Disable Stop detection */
   _bsp_int_disable(io_info_ptr->PORT_VECTOR);
   
   /* Install original vectors */
   _int_install_isr(io_info_ptr->PORT_VECTOR, io_info_ptr->OLD_PORT_ISR, io_info_ptr->OLD_PORT_ISR_DATA);
#endif
   
   /* Disable the I2C */
   i2c_ptr->C1 = 0x00;

   /* Clear the I2C events */
   i2c_ptr->S = 0xFF; 
 
   /* Install original vectors */
   _int_install_isr (io_info_ptr->VECTOR, io_info_ptr->OLD_ISR, io_info_ptr->OLD_ISR_DATA);
   
   _lwsem_destroy((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
   
   /* Free info struct */
   _mem_free (int_io_dev_ptr->DEV_INFO_PTR);
   int_io_dev_ptr->DEV_INFO_PTR = NULL;

   return I2C_OK;
} /* Endbody */
Beispiel #10
0
/*!
 * \cond DOXYGEN_PRIVATE
 *
 * \brief Initialization of pit timer module
 *
 * Called by hwtimer_deinit.
 * 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;
    uint32_t pit_hwtimers_array_size;

    PSP_INTERRUPT_TABLE_INDEX    vector;
    uint32_t pit_channel = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]);
    uint32_t pit_number  = GET_PIT_NUMBER_FROM_PITID(hwtimer->ll_context[1]);

    uint32_t pit_channels_count;
    uint32_t 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;
}
/*FUNCTION****************************************************************
* 
* Function Name    :_ki2c_isr
* Returned Value   : none   
*
*END*********************************************************************/
static void _ki2c_isr
   (
      void              *parameter
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR io_info_ptr = parameter;
   I2C_MemMapPtr         i2c_ptr = io_info_ptr->I2C_PTR;
   uint8_t               i2csr;
   volatile uint8_t      tmp;

   i2csr = i2c_ptr->S;
   io_info_ptr->STATISTICS.INTERRUPTS++;
   
   if(I2C_MODE_SLAVE == io_info_ptr->MODE)
      io_info_ptr->OPERATION |= I2C_OPERATION_STARTED;
   
   /* Master */
   if (i2c_ptr->C1 & I2C_C1_MST_MASK)
   {
      i2c_ptr->S |= I2C_S_IICIF_MASK;
      /* Transmit */
      if (i2c_ptr->C1 & I2C_C1_TX_MASK)
      {
         /* Not ack */
         if (i2csr & I2C_S_RXAK_MASK)
         {
            io_info_ptr->STATE = I2C_STATE_FINISHED;
            io_info_ptr->STATISTICS.TX_NAKS++;
            _bsp_int_disable(io_info_ptr->VECTOR);
            _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
         }
         /* Ack */
         else
         {
            /* End of address cycle? */
            if((I2C_STATE_READY == io_info_ptr->STATE) || (I2C_STATE_REPEATED_START == io_info_ptr->STATE))
            {
               /* Transmit operation */
               if(0 == (I2C_OPERATION_READ & io_info_ptr->OPERATION))
               {
                  io_info_ptr->STATE = I2C_STATE_TRANSMIT;
                  // For fwrite(0)
                  if(0 == io_info_ptr->TX_BUFFER_SIZE)
                  {
                     _bsp_int_disable(io_info_ptr->VECTOR);
                     _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
                  }
                  else
                  {
                     /*Transmit first byte*/
                     i2c_ptr->D = io_info_ptr->TX_BUFFER[io_info_ptr->TX_INDEX++];
                     io_info_ptr->STATISTICS.TX_PACKETS++;
                  }
               }
               /* Receive operation */
               else
               {
                  /* Change to receive state */
                  io_info_ptr->STATE = I2C_STATE_RECEIVE;
                  i2c_ptr->C1 &= (~ I2C_C1_TX_MASK);

                  if(1 == io_info_ptr->RX_REQUEST)
                  {
                      /* Send Nack */
                      i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
                  }
                  else
                  {
                      /* Send ack */
                      i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
                  }
                  /* dummy read to clock in 1st byte */
                  tmp = i2c_ptr->D;
               }
            }
            /* Normal i2c transmit */
            else
            {
               /* Anything to transmit? */
               if (io_info_ptr->TX_INDEX < io_info_ptr->TX_BUFFER_SIZE)
               {
                  i2c_ptr->D = io_info_ptr->TX_BUFFER[io_info_ptr->TX_INDEX++];   /*  transmit data */
                  io_info_ptr->STATISTICS.TX_PACKETS++;
               }
               else
               {
                  /* Transmit finish */
                  _bsp_int_disable(io_info_ptr->VECTOR);
                  _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
               }
            }
         }
      }
      /* Receive */
      else
      {
         /* Buffer full */
         if (io_info_ptr->RX_INDEX >= io_info_ptr->RX_BUFFER_SIZE)
         {
            _bsp_int_disable (io_info_ptr->VECTOR);
            _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
         }
         /* Buffer not full */
         else
         {
            /* Receive Finished */
            if (0 == io_info_ptr->RX_REQUEST)
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
               io_info_ptr->STATE = I2C_STATE_FINISHED;
               _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
            }
            else
            {
               /* 2nd last byte to read */
               if (2 == io_info_ptr->RX_REQUEST)
               {
                  i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
               }
               else
               {
                  i2c_ptr->C1 &= (~ I2C_C1_TXAK_MASK);
               }
               tmp = i2c_ptr->D;   /* receive data */
               io_info_ptr->RX_BUFFER[io_info_ptr->RX_INDEX++] = (tmp & I2C_D_DATA_MASK);
               io_info_ptr->RX_REQUEST--;
               io_info_ptr->STATISTICS.RX_PACKETS++;
            }
         }
      }
   }
   /* 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_BUFFER_SIZE != 0))
            {
               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_INDEX++];   /* transmit data */
               io_info_ptr->STATISTICS.TX_PACKETS++;
               _bsp_int_disable (io_info_ptr->VECTOR);
               _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
               _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
            }
         }
         /* 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_INDEX == 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 */
            }
            else
            {
               _bsp_int_disable (io_info_ptr->VECTOR);
               _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
            }
         }
      }
      /* 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++;
                  _bsp_int_disable (io_info_ptr->VECTOR);
                  _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
               }
               /* 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_INDEX != io_info_ptr->TX_BUFFER_SIZE) && (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_INDEX++];   /*  transmit data */
                     io_info_ptr->STATISTICS.TX_PACKETS++;
                     if(io_info_ptr->TX_INDEX == io_info_ptr->TX_BUFFER_SIZE)
                     {
                        _bsp_int_disable (io_info_ptr->VECTOR);
                        _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
                     }
                  }
                  else
                  {
                     _bsp_int_disable (io_info_ptr->VECTOR);
                     _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
                  }
               }
            }
            /* 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))
               {
                  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);
                  }
                  io_info_ptr->RX_BUFFER[io_info_ptr->RX_INDEX++] = i2c_ptr->D;   /* receive data */
                  io_info_ptr->STATISTICS.RX_PACKETS++;
                  if ((0 == io_info_ptr->RX_REQUEST) || (io_info_ptr->RX_INDEX == io_info_ptr->RX_BUFFER_SIZE))
                  {
                     if (0 == io_info_ptr->RX_REQUEST)
                        io_info_ptr->STATE = I2C_STATE_FINISHED;
                     _bsp_int_disable (io_info_ptr->VECTOR);
                     _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
                  }
               }
               else
               {
                  i2c_ptr->C1 |= I2C_C1_TXAK_MASK;
               }
            }
         }
         else
         {
            _bsp_int_disable (io_info_ptr->VECTOR);
            _lwsem_post((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));
         }
      }
   }
} /* Endbody */
uint32_t _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 */
      unsigned char                    *buffer,
      
      /* [IN] number of bytes to output */
      uint32_t                      length
   )
{ /* Body */
   VKI2C_INFO_STRUCT_PTR           io_info_ptr;
   I2C_MemMapPtr                   i2c_ptr;   
   uint32_t                        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 ();
   
   /* If beginning of transmission, set state and send address (master only) */
   io_info_ptr->OPERATION &= (~ I2C_OPERATION_READ);
   io_info_ptr->TX_BUFFER      = buffer;
   io_info_ptr->TX_BUFFER_SIZE = length;
   io_info_ptr->TX_INDEX       = 0;
   
   tmp = io_info_ptr->STATE;
   if (I2C_MODE_MASTER == io_info_ptr->MODE)
   {
      if ((I2C_STATE_READY == tmp) || (I2C_STATE_REPEATED_START == tmp))
      {
         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++;
      }
      else if(I2C_STATE_TRANSMIT == tmp)
      {
         if(length != 0)
         {
            /* send first byte */
            i2c_ptr->D = io_info_ptr->TX_BUFFER[io_info_ptr->TX_INDEX++];   /*  transmit data */
            io_info_ptr->STATISTICS.TX_PACKETS++;
         }
         else
            return 0;
      }
   }

   /* Interrupt enable - end of critical section */
   _bsp_int_enable (io_info_ptr->VECTOR);
   
   /* Wait for tx complite */
   _lwsem_wait((LWSEM_STRUCT_PTR)(&(io_info_ptr->LWSEM)));

   return io_info_ptr->TX_INDEX;

} /* Endbody */