static OSStatus platform_uart_receive_bytes( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { uart_status_t retVal = kStatus_UART_Success; uart = MICO_UART_1; //test /* Reset DMA transmission result. The result is assigned in interrupt handler */ #if ADD_OS_CODE uart_interfaces[uart].rx_dma_result = kGeneralErr; #endif #ifdef UART_IRQ_APP retVal = UART_DRV_ReceiveDataBlocking(BOARD_APP_UART_INSTANCE, data, size, timeout); // if(UART_DRV_ReceiveData(BOARD_APP_UART_INSTANCE, data,size )==kStatus_UART_Success){ #else // if(UART_DRV_EdmaReceiveData(BOARD_DEBUG_UART_INSTANCE, data, size)==kStatus_UART_Success){ retVal = UART_DRV_EdmaReceiveDataBlocking(BOARD_APP_UART_INSTANCE, data, size, timeout);// #endif if(retVal == kStatus_UART_Success) { #if ADD_OS_CODE #ifndef NO_MICO_RTOS mico_rtos_set_semaphore( &uart_interfaces[uart].rx_complete ); #else uart_interfaces[uart ].rx_complete = true; #endif #endif return kNoErr; } if ( timeout > 0 ) { #if ADD_OS_CODE #ifndef NO_MICO_RTOS mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout ); #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){ break; } } #endif return uart_interfaces[uart].rx_dma_result; #endif } return kGeneralErr; // kNoErr; }
static OSStatus receive_bytes( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { OSStatus err = kNoErr; if ( driver->rx_buffer != NULL ) { driver->peripheral->rx_dma_config.stream->CR |= DMA_SxCR_CIRC; // Enabled individual byte interrupts so progress can be updated USART_ClearITPendingBit( driver->peripheral->port, USART_IT_RXNE ); USART_ITConfig( driver->peripheral->port, USART_IT_RXNE, ENABLE ); } else { driver->rx_size = size; driver->peripheral->rx_dma_config.stream->CR &= ~(uint32_t) DMA_SxCR_CIRC; } clear_dma_interrupts( driver->peripheral->rx_dma_config.stream, driver->peripheral->rx_dma_config.complete_flags | driver->peripheral->rx_dma_config.error_flags ); driver->peripheral->rx_dma_config.stream->NDTR = size; driver->peripheral->rx_dma_config.stream->M0AR = (uint32_t)data; driver->peripheral->rx_dma_config.stream->CR |= DMA_SxCR_EN; USART_DMACmd( driver->peripheral->port, USART_DMAReq_Rx, ENABLE ); if ( timeout > 0 ) { #ifndef NO_MICO_RTOS err = mico_rtos_get_semaphore( &driver->rx_complete, timeout ); #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) { err = kTimeoutErr; goto exit; } } #endif } exit: return err; }
static OSStatus platform_uart_receive_bytes( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { if ( uart_interfaces[uart].rx_buffer != NULL ) { uart_mapping[uart].rx_dma_stream->CR |= DMA_SxCR_CIRC; // Enabled individual byte interrupts so progress can be updated USART_ITConfig( uart_mapping[uart].usart, USART_IT_RXNE, ENABLE ); } else { uart_mapping[uart].rx_dma_stream->CR &= ~(uint32_t) DMA_SxCR_CIRC; } /* Reset DMA transmission result. The result is assigned in interrupt handler */ uart_interfaces[uart].rx_dma_result = kGeneralErr; uart_mapping[uart].rx_dma_stream->NDTR = size; uart_mapping[uart].rx_dma_stream->M0AR = (uint32_t)data; uart_mapping[uart].rx_dma_stream->CR |= DMA_SxCR_EN; if ( timeout > 0 ) { #ifndef NO_MICO_RTOS mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout ); #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){ break; } } #endif return uart_interfaces[uart].rx_dma_result; } return kNoErr; }
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); 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 ) ) { /* 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; #ifndef NO_MICO_RTOS 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_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 } 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; }
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; }
void init_platform_bootloader( void ) { CRC8_Context crc; OSStatus err = kNoErr; mico_logic_partition_t *rf_partition = MicoFlashGetInfo( MICO_PARTITION_RF_FIRMWARE ); MicoGpioInitialize( (mico_gpio_t)MICO_SYS_LED, OUTPUT_PUSH_PULL ); MicoGpioOutputLow( (mico_gpio_t)MICO_SYS_LED ); MicoGpioInitialize( (mico_gpio_t)MICO_RF_LED, OUTPUT_OPEN_DRAIN_NO_PULL ); MicoGpioOutputHigh( (mico_gpio_t)MICO_RF_LED ); MicoGpioInitialize((mico_gpio_t)BOOT_SEL, INPUT_PULL_UP); MicoGpioInitialize((mico_gpio_t)MFG_SEL, INPUT_PULL_UP); #ifdef USE_MiCOKit_EXT dc_motor_init( ); dc_motor_set( 0 ); rgb_led_init(); rgb_led_open(0, 0, 0); #endif /* Specific operations used in EMW3165 production */ #define NEED_RF_DRIVER_COPY_BASE ((uint32_t)0x08008000) #define TEMP_RF_DRIVER_BASE ((uint32_t)0x08040000) #define TEMP_RF_DRIVER_END ((uint32_t)0x0807FFFF) const uint8_t isDriverNeedCopy = *(uint8_t *)(NEED_RF_DRIVER_COPY_BASE); const uint32_t totalLength = rf_partition->partition_length; const uint8_t crcResult = *(uint8_t *)(TEMP_RF_DRIVER_END); uint8_t targetCrcResult = 0; uint32_t copyLength; uint32_t destStartAddress_tmp = rf_partition->partition_start_addr; uint32_t sourceStartAddress_tmp = TEMP_RF_DRIVER_BASE; uint32_t i; if ( isDriverNeedCopy != 0x0 ) return; platform_log( "Bootloader start to copy RF driver..." ); /* Copy RF driver to SPI flash */ err = platform_flash_init( &platform_flash_peripherals[ MICO_FLASH_SPI ] ); require_noerr(err, exit); err = platform_flash_init( &platform_flash_peripherals[ MICO_FLASH_EMBEDDED ] ); require_noerr(err, exit); err = platform_flash_erase( &platform_flash_peripherals[ MICO_FLASH_SPI ], rf_partition->partition_start_addr, rf_partition->partition_start_addr + rf_partition->partition_length - 1 ); require_noerr(err, exit); platform_log( "Time: %d", mico_get_time_no_os() ); for(i = 0; i <= totalLength/SizePerRW; i++){ if( i == totalLength/SizePerRW ){ if(totalLength%SizePerRW) copyLength = totalLength%SizePerRW; else break; }else{ copyLength = SizePerRW; } printf("."); err = platform_flash_read( &platform_flash_peripherals[ MICO_FLASH_EMBEDDED ], &sourceStartAddress_tmp, data , copyLength ); require_noerr( err, exit ); err = platform_flash_write( &platform_flash_peripherals[ MICO_FLASH_SPI ], &destStartAddress_tmp, data, copyLength ); require_noerr(err, exit); } printf("\r\n"); /* Check CRC-8 check-sum */ platform_log( "Bootloader start to verify RF driver..." ); sourceStartAddress_tmp = TEMP_RF_DRIVER_BASE; destStartAddress_tmp = rf_partition->partition_start_addr; CRC8_Init( &crc ); for(i = 0; i <= totalLength/SizePerRW; i++){ if( i == totalLength/SizePerRW ){ if(totalLength%SizePerRW) copyLength = totalLength%SizePerRW; else break; }else{ copyLength = SizePerRW; } printf("."); err = platform_flash_read( &platform_flash_peripherals[ MICO_FLASH_SPI ], &destStartAddress_tmp, data, copyLength ); require_noerr( err, exit ); CRC8_Update( &crc, data, copyLength); } CRC8_Final( &crc, &targetCrcResult ); printf("\r\n"); //require_string( crcResult == targetCrcResult, exit, "Check-sum error" ); if( crcResult != targetCrcResult ){ platform_log("Check-sum error"); while(1); } /* Clear RF driver from temperary storage */ platform_log("Bootloader start to clear RF driver temporary storage..."); /* Clear copy tag */ err = platform_flash_erase( &platform_flash_peripherals[ MICO_FLASH_EMBEDDED ], NEED_RF_DRIVER_COPY_BASE, NEED_RF_DRIVER_COPY_BASE); require_noerr(err, exit); exit: return; }
OSStatus BUartRecv( mico_uart_t uart, void* data, uint32_t size, uint32_t timeout ) { 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 > (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ uart_interfaces[uart].rx_size = transfer_size; BuartIOctl(BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, uart_interfaces[uart].rx_size-1); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS if ( mico_rtos_get_semaphore( &uart_interfaces[uart].rx_complete, timeout) != kNoErr ) { //BuartIOctl(UART_IOCTL_RXINT_SET, 0); 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 { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); transfer_size -= bytes_available; data = ( (uint8_t*) data + bytes_available ); } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }
void init_platform_bootloader( void ) { OSStatus err = kNoErr; MicoGpioInitialize( (mico_gpio_t)MICO_SYS_LED, OUTPUT_PUSH_PULL ); MicoGpioOutputLow( (mico_gpio_t)MICO_SYS_LED ); MicoGpioInitialize( (mico_gpio_t)MICO_RF_LED, OUTPUT_OPEN_DRAIN_NO_PULL ); MicoGpioOutputHigh( (mico_gpio_t)MICO_RF_LED ); MicoGpioInitialize((mico_gpio_t)BOOT_SEL, INPUT_PULL_UP); MicoGpioInitialize((mico_gpio_t)MFG_SEL, INPUT_PULL_UP); /* Specific operations used in EMW3165 production */ #define NEED_RF_DRIVER_COPY_BASE ((uint32_t)0x08008000) #define TEMP_RF_DRIVER_BASE ((uint32_t)0x08040000) #define TEMP_RF_DRIVER_END ((uint32_t)0x0807FFFF) const uint8_t isDriverNeedCopy = *(uint8_t *)(NEED_RF_DRIVER_COPY_BASE); const uint32_t totalLength = ( DRIVER_FLASH_SIZE < 0x40000)? DRIVER_FLASH_SIZE:0x40000; const uint8_t crcResult = *(uint8_t *)(TEMP_RF_DRIVER_END); uint8_t targetCrcResult = 0; uint32_t copyLength; uint32_t destStartAddress_tmp = DRIVER_START_ADDRESS; uint32_t sourceStartAddress_tmp = TEMP_RF_DRIVER_BASE; uint32_t i; if ( isDriverNeedCopy != 0x0 ) return; platform_log( "Bootloader start to copy RF driver..." ); /* Copy RF driver to SPI flash */ err = MicoFlashInitialize( (mico_flash_t)MICO_FLASH_FOR_DRIVER ); require_noerr(err, exit); err = MicoFlashInitialize( (mico_flash_t)MICO_INTERNAL_FLASH ); require_noerr(err, exit); err = MicoFlashErase( MICO_FLASH_FOR_DRIVER, DRIVER_START_ADDRESS, DRIVER_END_ADDRESS ); require_noerr(err, exit); platform_log( "Time: %d", mico_get_time_no_os() ); for(i = 0; i <= totalLength/SizePerRW; i++){ if( i == totalLength/SizePerRW ){ if(totalLength%SizePerRW) copyLength = totalLength%SizePerRW; else break; }else{ copyLength = SizePerRW; } printf("."); err = MicoFlashRead( MICO_INTERNAL_FLASH, &sourceStartAddress_tmp, data , copyLength ); require_noerr( err, exit ); err = MicoFlashWrite( MICO_FLASH_FOR_DRIVER, &destStartAddress_tmp, data, copyLength); require_noerr(err, exit); } printf("\r\n"); /* Check CRC-8 check-sum */ platform_log( "Bootloader start to verify RF driver..." ); sourceStartAddress_tmp = TEMP_RF_DRIVER_BASE; destStartAddress_tmp = DRIVER_START_ADDRESS; for(i = 0; i <= totalLength/SizePerRW; i++){ if( i == totalLength/SizePerRW ){ if(totalLength%SizePerRW) copyLength = totalLength%SizePerRW; else break; }else{ copyLength = SizePerRW; } printf("."); err = MicoFlashRead( MICO_FLASH_FOR_DRIVER, &destStartAddress_tmp, data, copyLength ); require_noerr( err, exit ); targetCrcResult = CRC8_Table(targetCrcResult, data, copyLength); } printf("\r\n"); //require_string( crcResult == targetCrcResult, exit, "Check-sum error" ); if( crcResult != targetCrcResult ){ platform_log("Check-sum error"); while(1); } /* Clear RF driver from temperary storage */ platform_log("Bootloader start to clear RF driver temporary storage..."); err = MicoFlashInitialize( (mico_flash_t)MICO_INTERNAL_FLASH ); require_noerr(err, exit); /* Clear copy tag */ err = MicoFlashErase(MICO_INTERNAL_FLASH, NEED_RF_DRIVER_COPY_BASE, NEED_RF_DRIVER_COPY_BASE); require_noerr(err, exit); exit: MicoFlashFinalize( MICO_INTERNAL_FLASH ); MicoFlashFinalize( MICO_FLASH_FOR_DRIVER ); }
static OSStatus BUartRecv( platform_uart_driver_t* driver, void* data, uint32_t size, uint32_t timeout ) { int next_trigger; uint32_t recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); uint32_t delay_start = 0; while (size != 0) { uint32_t transfer_size = MIN( BUART_RX_FIFO_SIZE / 2, size ); /* Check if ring buffer already contains the required amount of data. */ if ( transfer_size > recved_data_len ) { /* Set rx_size and wait in rx_complete semaphore until data reaches rx_size or timeout occurs */ driver->rx_size = transfer_size; next_trigger = (driver->buart_fifo_head + driver->rx_size - 1)% BUART_RX_FIFO_SIZE; /* */ if( next_trigger < driver->buart_fifo_head && (driver->buart_fifo_head + recved_data_len) < BUART_RX_FIFO_SIZE ){ BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, BUART_RX_FIFO_SIZE - 1 ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl(UART_IOCTL_RXINT_SET, 1); #ifndef NO_MICO_RTOS #if 0 if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } #else delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( (BUART_RX_FIFO_SIZE - driver->buart_fifo_head) <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #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; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif mico_thread_msleep(20); } #ifndef NO_MICO_RTOS #if 1 recved_data_len = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); if ( transfer_size > recved_data_len ){ BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); if ( mico_rtos_get_semaphore( &driver->rx_complete, timeout) != kNoErr ) { driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } else{ driver->rx_size = 0; } #else //platform_log( "Waiting...,head:%d expext:%d trigger:%d", driver->buart_fifo_head, driver->rx_size, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); delay_start = mico_get_time(); while(1){ mico_rtos_get_semaphore( &driver->rx_complete, 50); if( driver->rx_size <= (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0) ) break; if( mico_get_time() - delay_start > timeout ){ driver->rx_size = 0; BuartIOctl(UART_IOCTL_RXINT_SET, 0); return kTimeoutErr; } } #endif #else BuartIOctl(UART_IOCTL_RXINT_CLR, 0); BuartIOctl( BUART_IOCTL_RXFIFO_TRGR_DEPTH_SET, next_trigger ); BuartIOctl(UART_IOCTL_RXINT_SET, 1); driver->rx_complete = false; 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; BuartIOctl(UART_IOCTL_RXINT_SET, 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 { uint32_t bytes_available; bytes_available = (uint32_t)BuartIOctl(BUART_IOCTL_RXFIFO_DATLEN_GET, 0); bytes_available = MIN( bytes_available, transfer_size ); BuartRecv(data, bytes_available, 0); driver->buart_fifo_head = (driver->buart_fifo_head + bytes_available)% BUART_RX_FIFO_SIZE; transfer_size -= bytes_available; } while ( transfer_size != 0 ); } if ( size != 0 ) { return kGeneralErr; } else { return kNoErr; } }
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; } }