void USART6_IRQHandler( void )
{
  // Clear all interrupts. It's safe to do so because only RXNE interrupt is enabled
  USART6->SR = (uint16_t) (USART6->SR | 0xffff);
  
  // Update tail
  uart_interfaces[ STM32_UART_6 ].rx_buffer->tail = uart_interfaces[ STM32_UART_6 ].rx_buffer->size - uart_mapping[ STM32_UART_6 ].rx_dma_stream->NDTR;
  
  // Notify thread if sufficient data are available
  if ( ( uart_interfaces[ STM32_UART_6 ].rx_size > 0 ) &&
      ( ring_buffer_used_space( uart_interfaces[ STM32_UART_6 ].rx_buffer ) >= uart_interfaces[ STM32_UART_6 ].rx_size ) )
  {
#ifndef NO_MICO_RTOS
    mico_rtos_set_semaphore( &uart_interfaces[ STM32_UART_6 ].rx_complete );
#else
    uart_interfaces[ STM32_UART_1 ].rx_complete = true;
#endif
    uart_interfaces[ STM32_UART_6 ].rx_size = 0;
  }
  
#ifndef NO_MICO_RTOS
  if(uart_interfaces[ STM32_UART_6 ].sem_wakeup)
    mico_rtos_set_semaphore(&uart_interfaces[ STM32_UART_6 ].sem_wakeup);
#endif
}
Exemple #2
0
uint8_t ring_buffer_is_full(ring_buffer_t *ring_buffer)
{
    if (ring_buffer_used_space(ring_buffer) >= ring_buffer->size - 1)
        return 1;
    else
        return 0;
}
Exemple #3
0
void platform_uart_irq( platform_uart_driver_t* driver )
{
    platform_uart_port_t* uart = (platform_uart_port_t*) driver->peripheral->port;

    // Clear all interrupts. It's safe to do so because only RXNE interrupt is enabled
    uart->SR = (uint16_t) ( uart->SR | 0xffff );

    // Update tail
    driver->rx_buffer->tail = driver->rx_buffer->size - driver->peripheral->rx_dma_config.stream->NDTR;

    // Notify thread if sufficient data are available
    if ( ( driver->rx_size > 0 ) && ( ring_buffer_used_space( driver->rx_buffer ) >= driver->rx_size ) )
    {
#ifndef NO_MICO_RTOS
        mico_rtos_set_semaphore( &driver->rx_complete );
#else
        driver->rx_complete = true;
#endif
        driver->rx_size = 0;
    }
#ifndef NO_MICO_RTOS
    if( driver->sem_wakeup )
        mico_rtos_set_semaphore( &driver->sem_wakeup );
#endif
}
Exemple #4
0
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
{
  OSStatus err = kNoErr;

  //platform_mcu_powersave_disable();

  require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr);

  mico_rtos_get_semaphore( &driver->rx_complete, 0 );

  if ( driver->rx_buffer != NULL)
  {
    while ( expected_data_size != 0 )
    {
      uint32_t transfer_size = MIN( driver->rx_buffer->size / 2, expected_data_size );

        /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
        driver->last_receive_result = kNoErr;
        driver->rx_size             = transfer_size;
      
      /* Check if ring buffer already contains the required amount of data. */
      if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) )
      {
        err = mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms );

        /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
        driver->rx_size = 0;

        if( err != kNoErr )
          goto exit;
      }else {
        driver->rx_size = 0;
      }
      err = driver->last_receive_result;
      expected_data_size -= transfer_size;
      
      // Grab data from the buffer
      do
      {
        uint8_t* available_data;
        uint32_t bytes_available;
        
        ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available );
        bytes_available = MIN( bytes_available, transfer_size );
        memcpy( data_in, available_data, bytes_available );
        transfer_size -= bytes_available;
        data_in = ( (uint8_t*) data_in + bytes_available );
        ring_buffer_consume( driver->rx_buffer, bytes_available );
      } while ( transfer_size != 0 );
    }
  }
  else
  {
    err = receive_bytes( driver, data_in, expected_data_size, timeout_ms );
  }
exit:
  //platform_mcu_powersave_enable();
  return err;
}
Exemple #5
0
uint32_t MicoUartGetLengthInBuffer( mico_uart_t uart )
{
  if(uart_mapping[uart].uart == FUART)
    return ring_buffer_used_space( uart_interfaces[uart].rx_buffer );
  else if(uart_mapping[uart].uart == BUART){
    return BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0);
  }
  return 0;
}
Exemple #6
0
OSStatus platform_uart_get_length_in_buffer( platform_uart_driver_t* driver )
{
  if( driver->peripheral->uart == FUART )
    return ring_buffer_used_space( driver->rx_buffer );
  else if( driver->peripheral->uart == BUART ){
    return BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0);
  }
  return 0;
}
void platform_uart_irq( platform_uart_driver_t* driver )
{
    uint32_t status = usart_get_status( driver->peripheral->peripheral );
    uint32_t mask = usart_get_interrupt_mask( driver->peripheral->peripheral );
    Pdc* pdc_register = usart_get_pdc_base( driver->peripheral->peripheral );

    /* ENDTX flag is set when Tx DMA transfer is done
     */
    if ( ( mask & US_IMR_ENDTX ) && ( status & US_CSR_ENDTX ) )
    {
        pdc_packet_t dma_packet;

        /* ENDTX is cleared when TCR or TNCR is set to a non-zero value, which effectively
         * starts another Tx DMA transaction. To work around this, disable Tx before
         * performing a dummy Tx init.
         */
        pdc_disable_transfer( usart_get_pdc_base( driver->peripheral->peripheral ), PERIPH_PTCR_TXTDIS );

        dma_packet.ul_addr = (uint32_t)0;
        dma_packet.ul_size = (uint32_t)1;

        pdc_tx_init( usart_get_pdc_base( USART1 ), &dma_packet, NULL );

        /* Notifies waiting thread that Tx DMA transfer is complete */
        host_rtos_set_semaphore( &driver->tx_dma_complete, WICED_TRUE );
    }

    /* ENDRX flag is set when RCR is 0. RNPR and RNCR values are then copied into
     * RPR and RCR, respectively, while the Tx tranfer continues. We now need to
     * prepare RNPR and RNCR for the next iteration.
     */
    if ( ( mask & US_IMR_ENDRX ) && ( status & US_CSR_ENDRX ) )
    {
        pdc_register->PERIPH_RNPR = (uint32_t)driver->rx_ring_buffer->buffer;
        pdc_register->PERIPH_RNCR = (uint32_t)driver->rx_ring_buffer->size;
    }

    /* RXRDY interrupt is triggered and flag is set when a new character has been
     * received but not yet read from the US_RHR. When this interrupt executes,
     * the DMA engine already read the character out from the US_RHR and RXRDY flag
     * is no longer asserted. The code below updates the ring buffer parameters
     * to keep them current
     */
    if ( mask & US_CSR_RXRDY )
    {
        driver->rx_ring_buffer->tail = driver->rx_ring_buffer->size - pdc_register->PERIPH_RCR;

        // Notify thread if sufficient data are available
        if ( ( driver->rx_transfer_size > 0 ) && ( ring_buffer_used_space( driver->rx_ring_buffer ) >= driver->rx_transfer_size ) )
        {
            host_rtos_set_semaphore( &driver->rx_dma_complete, WICED_TRUE );
            driver->rx_transfer_size = 0;
        }
    }
}
Exemple #8
0
void FuartInterrupt(void)
{
  int status;
  uint8_t rxData;
  status = FuartIOctl(UART_IOCTL_RXSTAT_GET,0);

  if(status & 0x1E){
    /*
     * clear FIFO before clear other flags
     */
    FuartIOctl(UART_IOCTL_RXFIFO_CLR,0);
    /*
     * clear other error flags
     */
    FuartIOctl(UART_IOCTL_RXINT_CLR,0);
  }

  if(status & 0x01)
  { 
    //or,you can receive them in the interrupt directly
    while(FuartRecvByte(&rxData) > 0){
      ring_buffer_write( uart_interfaces[ AP80xx_FUART ].rx_buffer, &rxData,1 );
    }

    FuartIOctl(UART_IOCTL_RXINT_CLR,0);

    // Notify thread if sufficient data are available
    if ( ( uart_interfaces[ 0 ].rx_size > 0 ) &&
        ( ring_buffer_used_space( uart_interfaces[ AP80xx_FUART ].rx_buffer ) >= uart_interfaces[ AP80xx_FUART ].rx_size ) )
    {
  #ifndef NO_MICO_RTOS
      mico_rtos_set_semaphore( &uart_interfaces[ AP80xx_FUART ].rx_complete );
  #else
      uart_interfaces[ AP80xx_FUART ].rx_complete = true;
  #endif
      uart_interfaces[ AP80xx_FUART ].rx_size = 0;
    }
  }

  if(FuartIOctl(UART_IOCTL_TXSTAT_GET,0) & 0x01)
  {
    FuartIOctl(UART_IOCTL_TXINT_CLR,0);
#ifndef NO_MICO_RTOS
    mico_rtos_set_semaphore( &uart_interfaces[ AP80xx_FUART ].tx_complete );
#else
    uart_interfaces[ AP80xx_FUART ].tx_complete = true;
#endif
  }
}
Exemple #9
0
uint32_t MicoUartGetLengthInBuffer( mico_uart_t uart )
{
#if RING_BUFF_ON
  return ring_buffer_used_space( uart_interfaces[uart].rx_buffer );
#else
  uart_state_t * uState = &uartState;
  uint32_t len = 0;
   len =  uState->pRxSize;
   if(len != 0){
       uState->pRxSize = 0;
   }
  return len;
  // return 0; //test
#endif
}
void platform_uart_irq( platform_uart_driver_t* driver )
{
    platform_uart_port_t* uart = (platform_uart_port_t*) driver->interface->uart_base;
    uint8_t data=0;

    while (Chip_UART_GetLineStatus(uart) & UART_LSR_RDR) {
        Chip_UART_ReceiveByte(uart,&data);
        ring_buffer_write( driver->rx_buffer,&data, 1 );
    }

    // Notify thread if sufficient data are available
    if ( ( driver->rx_size > 0 ) && ( ring_buffer_used_space( driver->rx_buffer ) >= driver->rx_size ) )
    {
        host_rtos_set_semaphore( &driver->rx_complete, WICED_TRUE );
        driver->rx_size = 0;
    }
}
Exemple #11
0
void USARTx_IRQHandler( void )
{
  // Clear all interrupts. It's safe to do so because only RXNE interrupt is enabled
  USARTx->SR = (uint16_t) (USARTx->SR | 0xffff);
  
  // Update tail
  rx_buffer.tail = rx_buffer.size - UART_RX_DMA_Stream->NDTR;
  
  // Notify thread if sufficient data are available
  if ( ( rx_size > 0 ) && ( ring_buffer_used_space( &rx_buffer ) >= rx_size ) && sem_init )
  {
    mico_rtos_set_semaphore( &rx_complete );
    rx_size = 0;
  }
  #ifdef MCULowPowerMode
    mico_rtos_set_semaphore(&wakeup);
  #endif  
}
Exemple #12
0
int UART_Recv(u8 *recvBuf, u32 bufLen, u32 timeOut)
{
  while (bufLen != 0){
    uint32_t transfer_size = MIN(rx_buffer.size / 2, bufLen);
    
    /* Check if ring buffer already contains the required amount of data. */
    if ( transfer_size > ring_buffer_used_space( &rx_buffer ) ) {
      /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
      rx_size = transfer_size;
      if ( mico_rtos_get_semaphore( &rx_complete, timeOut ) != 0 ){
        rx_size = 0;
        return -1;
      }
      /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
      rx_size = 0;
    }
    
    bufLen -= transfer_size;
    
    // Grab data from the buffer
    do
    {
      uint8_t* available_data;
      uint32_t bytes_available;
      
      ring_buffer_get_data( &rx_buffer, &available_data, &bytes_available );
      bytes_available = MIN( bytes_available, transfer_size );
      memcpy( recvBuf, available_data, bytes_available );
      transfer_size -= bytes_available;
      recvBuf = ( (uint8_t*) recvBuf + bytes_available );
      ring_buffer_consume( &rx_buffer, bytes_available );
    } while ( transfer_size != 0 );
  }
  
  if ( bufLen != 0 ) {
    return -1;
  }
  else{
    return 0;
  }
}
Exemple #13
0
wiced_result_t ring_buffer_read( wiced_ring_buffer_t* ring_buffer, uint8_t* data, uint32_t data_length, uint32_t* number_of_bytes_read )
{
    uint32_t max_bytes_to_read;
    uint32_t i;
    uint32_t head = ring_buffer->head;

    wiced_assert("Bad args", ring_buffer != NULL && data != NULL && number_of_bytes_read != NULL);

    max_bytes_to_read = MIN(data_length, ring_buffer_used_space(ring_buffer));

    if ( max_bytes_to_read != 0 )
    {
        for ( i = 0; i != max_bytes_to_read; i++, ( head = ( head + 1 ) % ring_buffer->size ) )
        {
            data[ i ] = ring_buffer->buffer[ head ];
        }

        ring_buffer_consume( ring_buffer, max_bytes_to_read );
    }

    *number_of_bytes_read = max_bytes_to_read;
    return WICED_SUCCESS;
}
Exemple #14
0
int ring_buffer_read( ring_buffer_t* ring_buffer, uint8_t* data, uint32_t data_length, uint32_t* number_of_bytes_read )
{
  uint32_t max_bytes_to_read;
  uint32_t i;
  uint32_t head;
  
  head = ring_buffer->head;
  
  max_bytes_to_read = MIN(data_length, ring_buffer_used_space(ring_buffer));
  
  if ( max_bytes_to_read != 0 )
  {
    for ( i = 0; i != max_bytes_to_read; i++, ( head = ( head + 1 ) % ring_buffer->size ) )
    {
      data[ i ] = ring_buffer->buffer[ head ];
    }
    
    ring_buffer_consume( ring_buffer, max_bytes_to_read );
  }
  
  *number_of_bytes_read = max_bytes_to_read;
  
  return 0;
}
Exemple #15
0
OSStatus MicoUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout )
{
#if RING_BUFF_ON
  if (uart_interfaces[uart].rx_buffer != NULL)
  {
    while (size != 0)
    {
      uint32_t transfer_size = MIN(uart_interfaces[uart].rx_buffer->size / 2, size);
      
      /* Check if ring buffer already contains the required amount of data. */
      if ( transfer_size > ring_buffer_used_space( uart_interfaces[uart].rx_buffer ) )
      {
        /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
        uart_interfaces[uart].rx_size = transfer_size;
#ifndef NO_MICO_RTOS
        if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr )
        {
          uart_interfaces[uart].rx_size = 0;
          return kTimeoutErr;
        }
#else
        uart_interfaces[uart].rx_complete = false;
        int delay_start = mico_get_time_no_os();
        while(uart_interfaces[uart].rx_complete == false){
          if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){
            uart_interfaces[uart].rx_size = 0;
            return kTimeoutErr;
          }
        }
#endif
        /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
        uart_interfaces[uart].rx_size = 0;
      }
     
      size -= transfer_size;
      
      // Grab data from the buffer
      do
      {
        uint8_t* available_data;
        uint32_t bytes_available;
         //platform_log("uart receive 03"); 
        ring_buffer_get_data( uart_interfaces[uart].rx_buffer, &available_data, &bytes_available );
        bytes_available = MIN( bytes_available, transfer_size );
        memcpy( data, available_data, bytes_available );
        transfer_size -= bytes_available;
        data = ( (uint8_t*) data + bytes_available );
        ring_buffer_consume( uart_interfaces[uart].rx_buffer, bytes_available );
      } while ( transfer_size != 0 );
    }
    
    if ( size != 0 )
    {
      return kGeneralErr;
    }
    else
    {
      return kNoErr;
    }
  }
  else
  {
    return platform_uart_receive_bytes( uart, data, size, timeout );
  }
#else
    return platform_uart_receive_bytes( uart, data, size, timeout );
#endif 
 // return kNoErr;
}
platform_result_t platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
{
    UNUSED_PARAMETER(driver);
    UNUSED_PARAMETER(data_in);
    UNUSED_PARAMETER(expected_data_size);
    UNUSED_PARAMETER(timeout_ms);

    if ( driver->rx_ring_buffer != NULL )
    {
        while ( expected_data_size != 0 )
        {
            uint32_t transfer_size = MIN(driver->rx_ring_buffer->size / 2, expected_data_size);

            /* Check if ring buffer already contains the required amount of data. */
            if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) )
            {
                /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
                driver->rx_transfer_size = transfer_size;

                if ( host_rtos_get_semaphore( &driver->rx_dma_complete, timeout_ms, WICED_FALSE ) != WWD_SUCCESS )
                {
                    driver->rx_transfer_size = 0;
                    return PLATFORM_TIMEOUT;
                }

                /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
                driver->rx_transfer_size = 0;
            }

            expected_data_size -= transfer_size;

            // Grab data from the buffer
            do
            {
                uint8_t* available_data;
                uint32_t bytes_available;

                ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available );
                bytes_available = MIN( bytes_available, transfer_size );
                memcpy( data_in, available_data, bytes_available );
                transfer_size -= bytes_available;
                data_in = ( (uint8_t*)data_in + bytes_available );
                ring_buffer_consume( driver->rx_ring_buffer, bytes_available );
            }
            while ( transfer_size != 0 );
        }

        if ( expected_data_size != 0 )
        {
            return PLATFORM_ERROR;
        }
        else
        {
            return PLATFORM_SUCCESS;
        }
    }
    else
    {
        /* TODO: need to implement this */
        return PLATFORM_UNSUPPORTED;
    }
}
platform_result_t platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
{
    /*The following is a temporary implemenration of the UART*/
    platform_result_t result = PLATFORM_SUCCESS;
    wiced_assert( "bad argument", ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ) );

    if ( driver->rx_buffer != NULL )
    {
        while ( expected_data_size != 0 )
        {
            uint32_t transfer_size = MIN( driver->rx_buffer->size / 2, expected_data_size );

            /* Check if ring buffer already contains the required amount of data. */
            if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) )
            {
                wwd_result_t wwd_result;

                /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
                WICED_DISABLE_INTERRUPTS( );
                driver->last_receive_result = PLATFORM_SUCCESS;
                driver->rx_size = transfer_size;
                WICED_ENABLE_INTERRUPTS( );

                wwd_result = host_rtos_get_semaphore( &driver->rx_complete, timeout_ms, WICED_TRUE );

                /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
                WICED_DISABLE_INTERRUPTS( );
                driver->rx_size = 0;
                WICED_ENABLE_INTERRUPTS( );

                if ( wwd_result == WWD_TIMEOUT )
                {
                    /* Semaphore timeout. breaks from the while loop */
                    result = PLATFORM_TIMEOUT;
                    break;
                }
                else
                {
                    /* No timeout. retrieve result */
                    result = driver->last_receive_result;
                }
            }

            expected_data_size -= transfer_size;

            // Grab data from the buffer
            do
            {
                uint8_t* available_data;
                uint32_t bytes_available;

                ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available );
                bytes_available = MIN( bytes_available, transfer_size );
                memcpy( data_in, available_data, bytes_available );
                transfer_size -= bytes_available;
                data_in = ( (uint8_t*) data_in + bytes_available );
                ring_buffer_consume( driver->rx_buffer, bytes_available );
            } while ( transfer_size != 0 );
        }

        return result;
    }
    else
    {
        return result;
    }
}
Exemple #18
0
OSStatus platform_uart_get_length_in_buffer( platform_uart_driver_t* driver )
{
    return ring_buffer_used_space( driver->rx_buffer );
}
Exemple #19
0
OSStatus platform_uart_receive_bytes( platform_uart_driver_t* driver, uint8_t* data_in, uint32_t expected_data_size, uint32_t timeout_ms )
{
    OSStatus err = kNoErr;
    uint32_t transfer_size;

    //platform_mcu_powersave_disable();

    require_action_quiet( ( driver != NULL ) && ( data_in != NULL ) && ( expected_data_size != 0 ), exit, err = kParamErr);
    require_action_quiet( driver->rx_ring_buffer != NULL , exit, err = kUnsupportedErr);

    while ( expected_data_size != 0 )
    {
        transfer_size = MIN(driver->rx_ring_buffer->size / 2, expected_data_size);

        /* Check if ring buffer already contains the required amount of data. */
        if ( transfer_size > ring_buffer_used_space( driver->rx_ring_buffer ) )
        {
            /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
            driver->rx_size = transfer_size;

#ifndef NO_MICO_RTOS
            if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout_ms ) != kNoErr )
            {
                driver->rx_size = 0;
                err = kTimeoutErr;
                goto exit;
            }

            /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
            driver->rx_size = 0;
#else
            driver->rx_complete = false;
            int delay_start = mico_get_time_no_os();
            while(driver->rx_complete == false) {
                if(mico_get_time_no_os() >= delay_start + timeout_ms && timeout_ms != MICO_NEVER_TIMEOUT) {
                    driver->rx_size = 0;
                    err = kTimeoutErr;
                    goto exit;
                }
            }
            driver->rx_size = 0;
#endif
        }
        expected_data_size -= transfer_size;

        // Grab data from the buffer
        do
        {
            uint8_t* available_data;
            uint32_t bytes_available;

            ring_buffer_get_data( driver->rx_ring_buffer, &available_data, &bytes_available );
            bytes_available = MIN( bytes_available, transfer_size );
            memcpy( data_in, available_data, bytes_available );
            transfer_size -= bytes_available;
            data_in = ( (uint8_t*)data_in + bytes_available );
            ring_buffer_consume( driver->rx_ring_buffer, bytes_available );
        }
        while ( transfer_size != 0 );
    }

    require_action( expected_data_size == 0, exit, err = kReadErr);

exit:
    //platform_mcu_powersave_enable();
    return err;
}
uint32_t MicoUartGetLengthInBuffer( mico_uart_t uart )
{
  return ring_buffer_used_space( uart_interfaces[uart].rx_buffer );
}
Exemple #21
0
static OSStatus FUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout )
{

  if ( driver->rx_buffer != NULL )
  {
    while (size != 0)
    {
      uint32_t transfer_size = MIN( driver->rx_buffer->size/2, size );
      
      /* Check if ring buffer already contains the required amount of data. */
      if ( transfer_size > ring_buffer_used_space( driver->rx_buffer ) )
      {
        /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */
        driver->rx_size = transfer_size;
        
#ifndef NO_MICO_RTOS
        if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr )
        {
          driver->rx_size = 0;
          return kTimeoutErr;
        }
#else
        driver->rx_complete = false;
        int delay_start = mico_get_time_no_os();
        while(driver->rx_complete == false){
          if(mico_get_time_no_os() >= delay_start + timeout && timeout != MICO_NEVER_TIMEOUT){
            driver->rx_size = 0;
            return kTimeoutErr;
          }
        }
#endif
        
        /* Reset rx_size to prevent semaphore being set while nothing waits for the data */
        driver->rx_size = 0;
      }
      
      size -= transfer_size;
      
      // Grab data from the buffer
      do
      {
        uint8_t* available_data;
        uint32_t bytes_available;
        
        ring_buffer_get_data( driver->rx_buffer, &available_data, &bytes_available );
        bytes_available = MIN( bytes_available, transfer_size );
        memcpy( data, available_data, bytes_available );
        transfer_size -= bytes_available;
        data = ( (uint8_t*) data + bytes_available );
        ring_buffer_consume( driver->rx_buffer, bytes_available );
      } while ( transfer_size != 0 );
    }
    
    if ( size != 0 )
    {
      return kGeneralErr;
    }
    else
    {
      return kNoErr;
    }
  }
  else
  {
    mico_thread_msleep(timeout);
    return kNoMemoryErr;
  }
}