/* * FreeRTOS * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * http://aws.amazon.com/freertos * http://www.FreeRTOS.org */ /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "queue.h" /* Demo includes */ #include "aws_test_runner.h" /* AWS library includes. */ #include "iot_logging_task.h" #include "aws_clientcredential.h" /* Nordic BSP includes */ #include "bsp.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_sdh.h" #include "nrf_sdh_soc.h" #include "nrf_sdh_ble.h" #include "nrf_sdh_freertos.h" #include "sensorsim.h" #include "timers.h" #include "app_timer.h" #include "ble_conn_state.h" #include "nrf_drv_clock.h" #include "nrf_ble_gatt.h" #include "nrf_ble_qwr.h" #include "ble_conn_params.h" #include "peer_manager.h" #include "peer_manager_handler.h" #include "bsp_btn_ble.h" #include "app_uart.h" #include #include "SEGGER_RTT.h" #if defined( UART_PRESENT ) #include "nrf_uart.h" #endif #if defined( UARTE_PRESENT ) #include "nrf_uarte.h" #endif /* clang-format off */ #define mainTEST_RUNNER_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 12 ) /* Logging Task Defines. */ #define mainLOGGING_MESSAGE_QUEUE_LENGTH ( 15 ) #define mainLOGGING_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 ) /* BLE Lib defines. */ #define mainBLE_SERVER_UUID { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } /* UART Buffer sizes. */ #define UART_TX_BUF_SIZE ( 256 ) /**< UART TX buffer size. */ #define UART_RX_BUF_SIZE ( 256 ) /**< UART RX buffer size. */ /* LED-associated defines */ #define LED_ONE BSP_LED_0_MASK #define LED_TWO BSP_LED_1_MASK #define LED_THREE BSP_LED_2_MASK #define LED_FOUR BSP_LED_3_MASK #define ALL_APP_LED \ ( BSP_LED_0_MASK | BSP_LED_1_MASK | \ BSP_LED_2_MASK | BSP_LED_3_MASK ) /**< Define used for simultaneous operation of all application LEDs. */ #define LED_BLINK_INTERVAL_MS ( 300 ) /**< LED blinking interval. */ SemaphoreHandle_t xUARTTxComplete; QueueHandle_t UARTqueue = NULL; /** * @brief Application task startup hook for applications using Wi-Fi. If you are not * using Wi-Fi, then start network dependent applications in the vApplicationIPNetorkEventHook * function. If you are not using Wi-Fi, this hook can be disabled by setting * configUSE_DAEMON_TASK_STARTUP_HOOK to 0. */ void vApplicationDaemonTaskStartupHook( void ); /** * @brief Initializes the board. */ static void prvMiscInitialization( void ); /*-----------------------------------------------------------*/ void vUartWrite( uint8_t * pucData ) { uint32_t xErrCode; SEGGER_RTT_WriteString(0, pucData); for( uint32_t i = 0; i < configLOGGING_MAX_MESSAGE_LENGTH; i++ ) { if(pucData[ i ] == 0) { break; } do { xErrCode = app_uart_put(pucData[ i ]); if(xErrCode == NRF_ERROR_NO_MEM) { xErrCode = 0; } } while( xErrCode == NRF_ERROR_BUSY ); xSemaphoreTake(xUARTTxComplete, portMAX_DELAY ); } } /*-----------------------------------------------------------*/ /**@brief Function for putting the chip into sleep mode. * /**@brief Function for putting the chip into sleep mode * * @note This function will not return. */ static void prvSleeModeEnter( void ) { ret_code_t xErrCode; xErrCode = bsp_indication_set( BSP_INDICATE_IDLE ); APP_ERROR_CHECK( xErrCode ); /* Prepare wakeup buttons. */ xErrCode = bsp_btn_ble_sleep_mode_prepare(); APP_ERROR_CHECK( xErrCode ); /* Go to system-off mode (this function will not return; wakeup will cause a reset). */ xErrCode = sd_power_system_off(); APP_ERROR_CHECK( xErrCode ); } /*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/ /**@brief Function for handling a Connection Parameters error. * * @param[in] nrf_error Error code containing information about what went wrong. */ static void conn_params_error_handler( uint32_t nrf_error ) { APP_ERROR_HANDLER( nrf_error ); } /*-----------------------------------------------------------*/ /**@brief Function for handling uart events. * * /**@snippet [Handling the data received over UART] */ void prvUartEventHandler( app_uart_evt_t * pxEvent ) { /* Declared as static so it can be pushed into the queue from the ISR. */ static volatile uint8_t ucRxByte = 0; BaseType_t xHigherPriorityTaskWoken; switch( pxEvent->evt_type ) { case APP_UART_DATA_READY: app_uart_get( (uint8_t *)&ucRxByte ); app_uart_put( ucRxByte ); //portYIELD_FROM_ISR (xHigherPriorityTaskWoken); break; case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER( pxEvent->data.error_communication ); break; case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER( pxEvent->data.error_code ); break; case APP_UART_TX_EMPTY: xSemaphoreGiveFromISR(xUARTTxComplete, &xHigherPriorityTaskWoken); break; default: break; } } /*-----------------------------------------------------------*/ /**@brief Function for handling events from the BSP module. * * @param[in] event Event generated by button press. */ static void prvBSPEventHandler( bsp_event_t xEvent ) { ret_code_t xErrCode; const BTInterface_t * pxIface = BTGetBluetoothInterface(); const BTBleAdapter_t * pxAdapter = pxIface->pxGetLeAdapter(); switch( xEvent ) { case BSP_EVENT_SLEEP: prvSleeModeEnter(); break; case BSP_EVENT_DISCONNECT: pxAdapter->pxDisconnect( 0, NULL, 0 ); break; default: break; } } /*-----------------------------------------------------------*/ /**@brief Function for initializing the UART module. */ static void prvUartInit( void ) { uint32_t xErrCode; app_uart_comm_params_t const xConnParams = { .rx_pin_no = RX_PIN_NUMBER, .tx_pin_no = TX_PIN_NUMBER, .rts_pin_no = RTS_PIN_NUMBER, .cts_pin_no = CTS_PIN_NUMBER, .flow_control = APP_UART_FLOW_CONTROL_DISABLED, .use_parity = false, #if defined( UART_PRESENT ) .baud_rate = NRF_UART_BAUDRATE_115200 #else .baud_rate = NRF_UARTE_BAUDRATE_115200 #endif }; APP_UART_FIFO_INIT( &xConnParams, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, prvUartEventHandler, _PRIO_APP_HIGH, xErrCode ); APP_ERROR_CHECK( xErrCode ); } /** * @brief Initialize BLE stask for Nordic. * On Nordic it is just a stub. */ BTStatus_t bleStackInit( void ) { return eBTStatusSuccess; } /*-----------------------------------------------------------*/ /**@brief Function for initializing the nrf log module. */ static void prvLogInit( void ) { ret_code_t xErrCode = NRF_LOG_INIT( NULL ); APP_ERROR_CHECK( xErrCode ); NRF_LOG_DEFAULT_BACKENDS_INIT(); } /*-----------------------------------------------------------*/ /**@brief Function for initializing the clock. */ static void prvClockInit( void ) { ret_code_t xErrCode = nrf_drv_clock_init(); APP_ERROR_CHECK( xErrCode ); } /*-----------------------------------------------------------*/ /**@brief Function for the Timer initialization. * * @details Initializes the timer module. This creates and starts application timers. */ static void prvTimersInit( void ) { /* Initialize timer module. */ ret_code_t xErrCode = app_timer_init(); APP_ERROR_CHECK( xErrCode ); } /*-----------------------------------------------------------*/ static void prvMiscInitialization( void ) { /* Initialize modules.*/ xUARTTxComplete = xSemaphoreCreateBinary(); prvUartInit(); prvClockInit(); /* Activate deep sleep mode. */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; prvTimersInit(); } /*-----------------------------------------------------------*/ /** * @brief Application runtime entry point. */ int main( void ) { /* Perform any hardware initialization that does not require the RTOS to be * running. */ prvMiscInitialization(); xLoggingTaskInitialize( mainLOGGING_TASK_STACK_SIZE, tskIDLE_PRIORITY, mainLOGGING_MESSAGE_QUEUE_LENGTH ); nrf_sdh_freertos_init( NULL, NULL ); ret_code_t xErrCode = pm_init(); vTaskStartScheduler(); return 0; } /*-----------------------------------------------------------*/ /**@brief Clear bond information from persistent storage. */ static void prvDeleteBonds( void ) { ret_code_t xErrCode; NRF_LOG_INFO( "Erase bonds!" ); xErrCode = pm_peers_delete(); APP_ERROR_CHECK( xErrCode ); } void vApplicationDaemonTaskStartupHook( void ) { xTaskCreate( TEST_RUNNER_RunTests_task, "RunTests_task", mainTEST_RUNNER_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); } /*-----------------------------------------------------------*/ /** * @brief User defined Idle task function. * * @note Do not make any blocking operations in this function. */ void vApplicationIdleHook( void ) { /* FIX ME. If necessary, update to application idle periodic actions. */ static TickType_t xLastPrint = 0; TickType_t xTimeNow; const TickType_t xPrintFrequency = pdMS_TO_TICKS( 5000 ); xTimeNow = xTaskGetTickCount(); if( ( xTimeNow - xLastPrint ) > xPrintFrequency ) { configPRINT( "." ); xLastPrint = xTimeNow; } } /*-----------------------------------------------------------*/ /** * @brief User defined assertion call. This function is plugged into configASSERT. * See FreeRTOSConfig.h to define configASSERT to something different. */ void vAssertCalled( const char * pcFile, uint32_t ulLine ) { /* FIX ME. If necessary, update to applicable assertion routine actions. */ const uint32_t ulLongSleep = 1000UL; volatile uint32_t ulBlockVariable = 0UL; volatile char * pcFileName = ( volatile char * ) pcFile; volatile uint32_t ulLineNumber = ulLine; ( void ) pcFileName; ( void ) ulLineNumber; printf( "vAssertCalled %s, %ld\n", pcFile, ( long ) ulLine ); fflush( stdout ); /* Setting ulBlockVariable to a non-zero value in the debugger will allow * this function to be exited. */ taskDISABLE_INTERRUPTS(); { while( ulBlockVariable == 0UL ) { vTaskDelay( pdMS_TO_TICKS( ulLongSleep ) ); } } taskENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ /** * @brief User defined application error handler required by NRF52SDK */ void app_error_handler( uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name ) { }