/*---------------------------------------------------------------------------- * 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