


/*---------------------------------------------------------------------------- * Global Functions *---------------------------------------------------------------------------*/ /*--------------------------- os_idle_demon ---------------------------------*/ #define TIMER_MASK 0xFFFFFF volatile unsigned int rtos_suspend; /// \brief The idle demon is running when no other thread is ready to run void os_idle_demon (void) { unsigned int expected_time; unsigned int prev_time; NVIC_SetPriority(PendSV_IRQn, NVIC_GetPriority(RTC1_IRQn)); for (;; ) { rtos_suspend = 1; expected_time = os_suspend(); expected_time &= TIMER_MASK; if (expected_time > 2) { prev_time = NRF_RTC1->COUNTER; expected_time += prev_time; NRF_RTC1->CC[0] = (expected_time > TIMER_MASK) ? expected_time - TIMER_MASK : expected_time; NRF_RTC1->INTENCLR = RTC_INTENSET_TICK_Msk; NVIC_EnableIRQ(RTC1_IRQn); __disable_irq(); if (rtos_suspend) { NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; __WFI(); NRF_RTC1->EVENTS_COMPARE[0] = 0; NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk; } __enable_irq(); NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk; expected_time = NRF_RTC1->COUNTER; expected_time = (expected_time >= prev_time) ? expected_time - prev_time : TIMER_MASK - prev_time + expected_time; } os_resume(expected_time); } } #if (OS_SYSTICK == 0) // Functions for alternative timer as RTX kernel timer /*--------------------------- os_tick_init ----------------------------------*/ /// \brief Initializes an alternative hardware timer as RTX kernel timer /// \return IRQ number of the alternative hardware timer int os_tick_init (void) { NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { // Do nothing. } NRF_RTC1->PRESCALER = 32;//OS_TRV; NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk; NRF_RTC1->TASKS_START = 1; return (RTC1_IRQn); /* Return IRQ number of timer (0..239) */ } /*--------------------------- os_tick_val -----------------------------------*/ /// \brief Get alternative hardware timer's current value (0 .. OS_TRV) /// \return Current value of the alternative hardware timer uint32_t os_tick_val (void) { return NRF_RTC1->COUNTER; } /*--------------------------- os_tick_ovf -----------------------------------*/ /// \brief Get alternative hardware timer's overflow flag /// \return Overflow flag\n /// - 1 : overflow /// - 0 : no overflow uint32_t os_tick_ovf (void) { return NRF_RTC1->EVENTS_OVRFLW; } /*--------------------------- os_tick_irqack --------------------------------*/ /// \brief Acknowledge alternative hardware timer interrupt void os_tick_irqack (void) { if ((NRF_RTC1->EVENTS_TICK != 0) && ((NRF_RTC1->INTENSET & RTC_INTENSET_TICK_Msk) != 0)) { NRF_RTC1->EVENTS_TICK = 0; } } #if defined (__CC_ARM) /* ARM Compiler */ __asm __declspec(noreturn) void RTC1_IRQHandler(void) { EXTERN OS_Tick_Handler BL OS_Tick_Handler } #else #error "Unknown compiler! Don't know how to create SVC function." #endif #endif // (OS_SYSTICK == 0) 
 //      ble_stack_thread osPoolDef(ble_evt_pool, 8, ble_evt_t); //   osPoolId ble_evt_pool; //    osMessageQDef(ble_stack_msg_box, 8, ble_evt_t); //    osMessageQId ble_stack_msg_box; //     osThreadId ble_stack_thread_id; //      void ble_stack_thread(void const * arg); //     osThreadDef (ble_stack_thread, osPriorityAboveNormal, 1, 400);  //     BLE void ble_stack_thread(void const * arg) { uint32_t err_code; osEvent evt; ble_evt_t * p_ble_evt; UNUSED_PARAMETER(arg); while (1) { evt = osMessageGet(ble_stack_msg_box, osWaitForever); // wait for message if (evt.status == osEventMessage) { p_ble_evt = evt.value.p; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; break; default: // No implementation needed. break; } (void)osPoolFree(ble_evt_pool, p_ble_evt); } } } //      BLE void ble_create_thread (void) { ble_evt_pool = osPoolCreate(osPool(ble_evt_pool)); ble_stack_msg_box = osMessageCreate(osMessageQ(ble_stack_msg_box), NULL); ble_stack_thread_id = osThreadCreate(osThread(ble_stack_thread), NULL); }  int main(void) { uint32_t err_code; bool erase_bonds; static osStatus status; //   status = osKernelInitialize(); //  timers_init(); ble_stack_init(); device_manager_init(erase_bonds); gap_params_init(); advertising_init(); services_init(); conn_params_init(); //     err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); ble_create_thread(); //   status = osKernelStart(); } 
 //    void services_init(void) { ble_uuid_t ble_uuid; /*  128 -  UUID */ ble_uuid128_t base_uuid = ADC_BASE_UUID; uint8_t uuid_type; ble_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; ble_uuid.uuid = ADC_SERVICE_UUID; sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type); sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &adc_handles); } /*    * UUID -   * handles -    (  ) * n_bytes -    * iswrite, isnotf, isread -   , ,  */ uint32_t char_add(uint16_t UUID, ble_gatts_char_handles_t * handles, uint8_t n_bytes, bool iswrite, bool isnotf, bool isread) { ble_gatts_char_md_t char_md; ble_gatts_attr_md_t cccd_md; ble_gatts_attr_t attr_char_value; ble_uuid_t char_uuid; ble_gatts_attr_md_t attr_md; memset(&cccd_md, 0, sizeof(cccd_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); cccd_md.vloc = BLE_GATTS_VLOC_STACK; memset(&char_md, 0, sizeof(char_md)); char_md.char_props.notify = isnotf; //   ; char_md.char_props.write = iswrite; //   ; char_md.char_props.read = isread; //   ; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = &cccd_md; char_md.p_sccd_md = NULL; /*  UUID - 128 -  */ char_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; char_uuid.uuid = UUID; memset(&attr_md, 0, sizeof(attr_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); attr_md.vloc = BLE_GATTS_VLOC_STACK; attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; attr_char_value.p_uuid = &char_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = n_bytes; attr_char_value.init_offs = 0; attr_char_value.max_len = n_bytes; //  ; attr_char_value.p_value = NULL; //   ; /*     */ sd_ble_gatts_characteristic_add(adc_handles, &char_md, &attr_char_value, handles); return 0; }  /*  UUID (  UUID    ) */ #define ADC_BASE_UUID {0x66, 0x9A, 0x0C, 0x20, 0x00, 0x08, 0x1A, 0x8F, 0xE7, 0x11, 0x61, 0xBE, 0x00, 0x00, 0x00, 0x00} /*  UUID (  UUID    ) */ #define ADC_SERVICE_UUID 0x1533 #define ADC_CHAR_UUID 0x1534  //    void ADC_init (void) { //  2       8  NRF_ADC->CONFIG = 0x00; NRF_ADC->CONFIG |= (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos)| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos)| (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos); NRF_ADC->INTENSET |= ADC_INTENSET_END_Enabled << ADC_INTENSET_END_Pos; NRF_ADC->ENABLE |= ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos; //     NVIC_SetPriority(ADC_IRQn, 1); NVIC_EnableIRQ(ADC_IRQn); //      NRF_TIMER1->POWER = 1; NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; NRF_TIMER1->PRESCALER = 10; // 16 MHz / 2^10 = 15625 Hz NRF_TIMER1->CC[0] = 15625; // 15625 Hz / 15625 = 1 Hz NRF_TIMER1->INTENSET = (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos); NRF_TIMER1->SHORTS |= (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos); //   PPI       NRF_PPI->CH[0].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0]; NRF_PPI->CH[0].TEP = (uint32_t) &NRF_ADC->TASKS_START; NRF_PPI->CHEN |= PPI_CHEN_CH0_Enabled; NRF_PPI->CHENSET |= PPI_CHENSET_CH0_Enabled; NRF_PPI->TASKS_CHG[0].EN = 1; NRF_TIMER1->TASKS_START = 1; } //    void ADC_IRQHandler(void) { rtos_suspend = 0; NRF_ADC->EVENTS_END = 0; if (NRF_ADC->CONFIG >> ADC_CONFIG_PSEL_Pos == ADC_CONFIG_PSEL_AnalogInput2) { NRF_TIMER1->EVENTS_COMPARE[0] = 0; adc_val = NRF_ADC->RESULT; osSignalSet(char_update_thread_id, 1<<CharUpdateSignal); } }  //       void char_update_thread (void const* arg); //      osThreadId char_update_thread_id; //      osThreadDef(char_update_thread, osPriorityNormal, 1, 0); //    int32_t CharUpdateSignal = 0x01; //     void char_update_thread (void const* arg) { while(1) { osSignalWait(1<<CharUpdateSignal,osWaitForever); ble_char_update(&adc_val,1,adc_char_handles.value_handle); } }  int main(void) { uint32_t err_code; bool erase_bonds; static osStatus status; //   status = osKernelInitialize(); //  timers_init(); ble_stack_init(); device_manager_init(erase_bonds); gap_params_init(); advertising_init(); services_init(); char_add(ADC_CHAR_UUID,&adc_char_handles, 1, false, false, true); conn_params_init(); //     err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); //   ADC_init(); //   ble_create_thread(); char_update_thread_id = osThreadCreate(osThread(char_update_thread),NULL); //   status = osKernelStart(); } 
Source: https://habr.com/ru/post/350416/
All Articles