├── LICENSE ├── README.md └── src ├── examples ├── common │ ├── brushed_dc_motor.c │ ├── brushed_dc_motor.h │ ├── electronic_speed_controller.c │ ├── electronic_speed_controller.h │ ├── joystick.h │ ├── radioshack_micro_servo.c │ ├── sainsmart_joystick.c │ ├── servo.h │ ├── utility.c │ └── utility.h ├── rx │ ├── main.c │ └── pca10040 │ │ └── blank │ │ ├── armgcc │ │ ├── Makefile │ │ └── poly_rx_gcc_nrf52.ld │ │ └── config │ │ └── sdk_config.h └── tx │ ├── main.c │ ├── pca10040 │ └── blank │ │ ├── armgcc │ │ ├── Makefile │ │ └── poly_tx_gcc_nrf52.ld │ │ └── config │ │ └── sdk_config.h │ └── pca10056 │ └── blank │ ├── armgcc │ ├── Makefile │ └── poly_tx_gcc_nrf52.ld │ └── config │ └── sdk_config.h ├── rc_radio.c └── rc_radio.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Daniel Veilleux 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The nrf_esb library in the [nRF5 SDK](http://developer.nordicsemi.com/nRF5_SDK/) provides a straightfoward path for developing proprietary protocols based on Nordic's [Enhanced ShockBurst](https://devzone.nordicsemi.com/blogs/783/intro-to-shockburstenhanced-shockburst/) link layer. In this project, the nrf_esb library is used to build a customizable remote control library for the nRF52 family of SoCs. It was originally created as part of an RC airplane build that is documented [here](http://inductivekickback.blogspot.com/2017/10/poly.html). 2 | 3 | ### Features 4 | The main features of the Remote Control Radio (rc_radio) library include: 5 | 6 | - A simple binding protocol where the transmitter reduces its output power, broadcasts on a known address and frequency, and waits for a reciever to ACK with a specific payload. 7 | - 5 different "transmitter channels", each with a unique address and channel map 8 | - Payloads can be customized by modifying the rc_radio_data_t struct and recompiling. 9 | - The transmit rate is configurable between 10 and 500 hertz. 10 | - The radio is disabled between events to save energy. 11 | - A Frequency Hopping Spread Spectrum (FHSS) mechanism is used to move the radio to a different channel after each packet is sent or received. 12 | 13 | ### Parameters 14 | To maximize range and robustness the following radio parameters are used: 15 | 16 | - 1mbps datarate 17 | - 5 address bytes 18 | - 2 CRC bytes 19 | - Only pipe 0 is used in order to utilize the better radio front-end. 20 | - Acknowledgements are only used when binding. 21 | 22 | ### SoC Resources 23 | The rc_radio library uses one of the nRF52's high-speed timer peripherals. Unfortunately, the nrf_esb library cannot be controlled via the [PPI](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fppi.html) so the timer is used to generate interrupts. The timer is configured for 1MHz operation to save energy and simplify timer arithmetic. The nrf_esb library itself uses **TIMER2** by default. 24 | 25 | The default NRF_ESB_MAX_PAYLOAD_LENGTH in nrf_esb.h is set to 32 bytes. The rc_radio_data_t payload is 4 bytes long by default. If rc_radio_data_t is modified then NRF_ESB_MAX_PAYLOAD_LENGTH may need to be increased (up to a maximum of 252 bytes). 26 | 27 | The nrf_esb library contains a FIFO mechanism for handling payloads and the NRF_ESB_TX_FIFO_SIZE and NRF_ESB_RX_FIFO_SIZE symbols are set to 8 by default in nrf_esb.h. The rc_radio library does not ever put more than one payload into the transmit FIFO and it processes the received payloads as they arrive so the default FIFO sizes can be reduced to save RAM if necessary. 28 | 29 | The nrf_esb library allows for configuration of the radio and callback interrupt priorities. The rc_radio library sets the radio interrupt priority to 0 and the callback priority to 1. The rc_radio itself uses priority 1 for its timer interrupts. It is recommended to use priorities [2, 7] for the remainder of the application. 30 | 31 | ### Usage 32 | There are unique init functions for the receiver and transmitter modes. Both init functions require an index of a high-speed timer to use (e.g. 0 for TIMER0) as well as a rc_radio_event_handler_t function pointer. 33 | 34 | For the transmitter, the event handler might look like this: 35 | 36 | ``` 37 | void rc_radio_handler(rc_radio_event_t event, const void * const p_context) 38 | { 39 | switch (event) 40 | { 41 | case RC_RADIO_EVENT_BINDING: 42 | NRF_LOG_INFO("Binding...\r\n"); 43 | break; 44 | case RC_RADIO_EVENT_BOUND: 45 | { 46 | rc_radio_bind_info_t * p_bind_info; 47 | p_bind_info = (rc_radio_bind_info_t*) p_context; 48 | 49 | NRF_LOG_INFO("Bound. (%d, %d)\r\n", 50 | p_bind_info->transmitter_channel, 51 | p_bind_info->transmit_rate_hz); 52 | } 53 | break; 54 | case RC_RADIO_EVENT_DATA_SENT: 55 | NRF_LOG_INFO("Data sent.\r\n"); 56 | break; 57 | default: 58 | break; 59 | }; 60 | } 61 | ``` 62 | The receiver's version of the event handler might look like this: 63 | ``` 64 | void rc_radio_handler(rc_radio_event_t event, const void * const p_context) 65 | { 66 | uint32_t err_code; 67 | 68 | switch (event) 69 | { 70 | case RC_RADIO_EVENT_BINDING: 71 | NRF_LOG_INFO("Binding...\r\n"); 72 | break; 73 | case RC_RADIO_EVENT_BOUND: 74 | { 75 | rc_radio_bind_info_t * p_bind_info; 76 | p_bind_info = (rc_radio_bind_info_t*) p_context; 77 | 78 | NRF_LOG_INFO("Bound. (%d, %d)\r\n", 79 | p_bind_info->transmitter_channel, 80 | p_bind_info->transmit_rate_hz); 81 | 82 | } 83 | break; 84 | case RC_RADIO_EVENT_DATA_RECEIVED: 85 | { 86 | rc_radio_data_t * p_rc_data; 87 | p_rc_data = (rc_radio_data_t*) p_context; 88 | 89 | // Apply the data from the payload. 90 | 91 | NRF_LOG_INFO("Data received.\r\n"); 92 | } 93 | break; 94 | case RC_RADIO_EVENT_PACKET_DROPPED: 95 | NRF_LOG_INFO("Packet dropped.\r\n"); 96 | break; 97 | default: 98 | break; 99 | }; 100 | } 101 | ``` 102 | The transmitter also decides which "transmitter channel" to use (e.g. RC_RADIO_TRANSMITTER_CHANNEL_D) as well as the transmit frequency in hertz. Note that when operating as a transmitter, the most recent payload will be reused automatically as needed; this allows the `rc_radio_data_set` function to be called at a lower frequency than the transmit frequency. 103 | 104 | ### Operation 105 | The transmit frequency is converted to a TRANSMIT_INTERVAL_US value. The transmitter uses this interval to trigger its timer's Capture Compare channel 0 (CC0) interrupt. The payload is written to the nrf_esb library during this interrupt to trigger the transmission. The receiver can't compute the TRANSMIT_INTERVAL_US until after it has binded to a transmitter. It then configures its timer to trigger its CC0 interrupt RX_WIDENING_US microseconds before it expects the transmitter to transmit. 106 | 107 | ![Figure 1. Transmit Interval](https://cloud.githubusercontent.com/assets/6494431/26183685/306c44fc-3b35-11e7-9f98-c0bf76848927.png) 108 | 109 | Typically, the packet transmission is successful, the packet is received, and the nrf_esb library executes a callback in the rc_radio library that clears the timer. This keeps the timer in sync with the transmitter. The recieved payload is reported to the application immediately. 110 | 111 | ![Figure 2. Packet Received](https://cloud.githubusercontent.com/assets/6494431/26183687/323d3098-3b35-11e7-8a89-53b7f9db348c.png) 112 | 113 | The receiver also configures its timer to trigger its CC1 interrupt RX_SAFETY_US microseconds after it expects the packet to be received. If the packet is not received then the CC1 interrupt disables the receiver, moves it to the next RF frequency, and notifies the application that a packet was dropped. 114 | 115 | ![Figure 3. Packet Missed](https://cloud.githubusercontent.com/assets/6494431/26183688/33bd8cce-3b35-11e7-90d7-b8356425945b.png) 116 | 117 | A single packet is sent/received per RF channel before moving to the next channel. 118 | -------------------------------------------------------------------------------- /src/examples/common/brushed_dc_motor.c: -------------------------------------------------------------------------------- 1 | #include "brushed_dc_motor.h" 2 | 3 | #include "nrf_pwm.h" 4 | #include "nrf_drv_pwm.h" 5 | #include "app_util_platform.h" 6 | 7 | 8 | // If this flag is not set in the sequence values that are passed to 9 | // nrf_drv_pwm then the polarity of the PWM waveform will be inverted. 10 | // Inverted values are not useful so it is assumed that if a value in 11 | // a sequence doesn't have this flag set then that channel is not enabled. 12 | #define CH_ENABLED_MASK (0x8000UL) 13 | 14 | #define BDCM_MIN_VALUE (0UL) 15 | #define BDCM_MAX_VALUE (500UL) 16 | 17 | // Simple functions for mapping a value betwen [0, 100] to the 18 | // range [BDCM_MIN_VALUE, BDCM_MAX_VALUE] and vice versa. 19 | #define MAP(x) ((x) * (BDCM_MAX_VALUE - BDCM_MIN_VALUE)/100 + BDCM_MIN_VALUE) 20 | #define PAM(x) (((x) - BDCM_MIN_VALUE) * 100 / (BDCM_MAX_VALUE-BDCM_MIN_VALUE)) 21 | 22 | 23 | uint32_t brushed_dc_motor_group_init(brushed_dc_motor_group_t * p_group, 24 | uint8_t pwm_instance_index, 25 | uint8_t ch0_pin, 26 | uint8_t ch1_pin, 27 | uint8_t ch2_pin, 28 | uint8_t ch3_pin) 29 | { 30 | uint32_t err_code; 31 | 32 | if (NULL == p_group) 33 | { 34 | return NRF_ERROR_INVALID_PARAM; 35 | } 36 | 37 | switch (pwm_instance_index) 38 | { 39 | case 0: 40 | p_group->pwm_instance.p_registers = NRF_PWM0; 41 | p_group->pwm_instance.drv_inst_idx = PWM0_INSTANCE_INDEX; 42 | break; 43 | case 1: 44 | p_group->pwm_instance.p_registers = NRF_PWM1; 45 | p_group->pwm_instance.drv_inst_idx = PWM1_INSTANCE_INDEX; 46 | break; 47 | case 2: 48 | p_group->pwm_instance.p_registers = NRF_PWM2; 49 | p_group->pwm_instance.drv_inst_idx = PWM2_INSTANCE_INDEX; 50 | break; 51 | #ifdef NRF52840_XXAA 52 | case 3: 53 | p_group->pwm_instance.p_registers = NRF_PWM3; 54 | p_group->pwm_instance.drv_inst_idx = PWM3_INSTANCE_INDEX; 55 | break; 56 | #endif 57 | default: 58 | return NRF_ERROR_INVALID_PARAM; 59 | } 60 | 61 | nrf_drv_pwm_config_t const pwm_config = 62 | { 63 | .output_pins = 64 | { 65 | ch0_pin, 66 | ch1_pin, 67 | ch2_pin, 68 | ch3_pin 69 | }, 70 | .irq_priority = APP_IRQ_PRIORITY_LOWEST, 71 | .base_clock = NRF_PWM_CLK_1MHz, 72 | .count_mode = NRF_PWM_MODE_UP, 73 | .top_value = BDCM_MAX_VALUE, 74 | .load_mode = NRF_PWM_LOAD_INDIVIDUAL, 75 | .step_mode = NRF_PWM_STEP_AUTO 76 | }; 77 | 78 | err_code = nrf_drv_pwm_init(&p_group->pwm_instance, &pwm_config, NULL); 79 | if (NRF_SUCCESS != err_code) 80 | { 81 | return err_code; 82 | } 83 | 84 | if (BRUSHED_DC_MOTOR_PIN_NOT_USED != ch0_pin) 85 | { 86 | p_group->pwm_values.channel_0 = (CH_ENABLED_MASK | 87 | BRUSHED_DC_MOTOR_MIN_VALUE); 88 | } 89 | else 90 | { 91 | p_group->pwm_values.channel_0 = 0; 92 | } 93 | 94 | if (BRUSHED_DC_MOTOR_PIN_NOT_USED != ch1_pin) 95 | { 96 | p_group->pwm_values.channel_1 = (CH_ENABLED_MASK | 97 | BRUSHED_DC_MOTOR_MIN_VALUE); 98 | } 99 | else 100 | { 101 | p_group->pwm_values.channel_1 = 0; 102 | } 103 | 104 | if (BRUSHED_DC_MOTOR_PIN_NOT_USED != ch2_pin) 105 | { 106 | p_group->pwm_values.channel_2 = (CH_ENABLED_MASK | 107 | BRUSHED_DC_MOTOR_MIN_VALUE); 108 | } 109 | else 110 | { 111 | p_group->pwm_values.channel_2 = 0; 112 | } 113 | 114 | if (BRUSHED_DC_MOTOR_PIN_NOT_USED != ch3_pin) 115 | { 116 | p_group->pwm_values.channel_3 = (CH_ENABLED_MASK | 117 | BRUSHED_DC_MOTOR_MIN_VALUE); 118 | } 119 | else 120 | { 121 | p_group->pwm_values.channel_3 = 0; 122 | } 123 | 124 | nrf_pwm_sequence_t const seq = 125 | { 126 | .values.p_individual = &p_group->pwm_values, 127 | .length = 4, 128 | .repeats = 0, 129 | .end_delay = 0 130 | }; 131 | err_code = nrf_drv_pwm_simple_playback(&p_group->pwm_instance, 132 | &seq, 133 | 1, 134 | NRF_DRV_PWM_FLAG_LOOP); 135 | return err_code; 136 | } 137 | 138 | 139 | uint32_t brushed_dc_motor_value_get(brushed_dc_motor_group_t * p_group, 140 | uint8_t ch_index, 141 | uint8_t * p_value) 142 | { 143 | uint16_t * p_channel_value; 144 | 145 | switch (ch_index) 146 | { 147 | case 0: 148 | p_channel_value = &p_group->pwm_values.channel_0; 149 | break; 150 | case 1: 151 | p_channel_value = &p_group->pwm_values.channel_1; 152 | break; 153 | case 2: 154 | p_channel_value = &p_group->pwm_values.channel_2; 155 | break; 156 | case 3: 157 | p_channel_value = &p_group->pwm_values.channel_3; 158 | break; 159 | default: 160 | return NRF_ERROR_INVALID_PARAM; 161 | } 162 | 163 | if (0 == (*p_channel_value & CH_ENABLED_MASK)) 164 | { 165 | return NRF_ERROR_INVALID_PARAM; 166 | } 167 | 168 | *p_value = (uint8_t)PAM((*p_channel_value & ~CH_ENABLED_MASK)); 169 | 170 | return NRF_SUCCESS; 171 | } 172 | 173 | 174 | uint32_t brushed_dc_motor_value_set(brushed_dc_motor_group_t * p_group, 175 | uint8_t ch_index, 176 | uint8_t value) 177 | { 178 | uint16_t * p_channel_value; 179 | 180 | if (BRUSHED_DC_MOTOR_MAX_VALUE < value) 181 | { 182 | return NRF_ERROR_INVALID_PARAM; 183 | } 184 | 185 | switch (ch_index) 186 | { 187 | case 0: 188 | p_channel_value = &p_group->pwm_values.channel_0; 189 | break; 190 | case 1: 191 | p_channel_value = &p_group->pwm_values.channel_1; 192 | break; 193 | case 2: 194 | p_channel_value = &p_group->pwm_values.channel_2; 195 | break; 196 | case 3: 197 | p_channel_value = &p_group->pwm_values.channel_3; 198 | break; 199 | default: 200 | return NRF_ERROR_INVALID_PARAM; 201 | } 202 | 203 | if (0 == (*p_channel_value & CH_ENABLED_MASK)) 204 | { 205 | return NRF_ERROR_INVALID_PARAM; 206 | } 207 | 208 | *p_channel_value = (MAP(value) | CH_ENABLED_MASK); 209 | 210 | return NRF_SUCCESS; 211 | } 212 | -------------------------------------------------------------------------------- /src/examples/common/brushed_dc_motor.h: -------------------------------------------------------------------------------- 1 | #ifndef BRUSHED_DC_MOTOR_H 2 | #define BRUSHED_DC_MOTOR_H 3 | 4 | #include "nrf_pwm.h" 5 | #include "nrf_drv_pwm.h" 6 | 7 | 8 | #define BRUSHED_DC_MOTOR_MIN_VALUE (0UL) 9 | #define BRUSHED_DC_MOTOR_MAX_VALUE (100UL) 10 | 11 | #define BRUSHED_DC_MOTOR_PIN_NOT_USED (NRF_DRV_PWM_PIN_NOT_USED) 12 | 13 | 14 | // Structs of this type need to kept in the global portion (static) of RAM 15 | // (not const) because they are accessed by EasyDMA. 16 | typedef struct 17 | { 18 | nrf_drv_pwm_t pwm_instance; 19 | nrf_pwm_values_individual_t pwm_values; 20 | } brushed_dc_motor_group_t; 21 | 22 | 23 | // The pwm_instance should be in the range [0, 2] on the nRF52832. The 24 | // chX_pins can be set to any GPIO or set to BRUSHED_DC_MOTOR_PIN_NOT_USED 25 | // if the channel is not required. 26 | uint32_t brushed_dc_motor_group_init(brushed_dc_motor_group_t * p_group, 27 | uint8_t pwm_instance_index, 28 | uint8_t ch0_pin, 29 | uint8_t ch1_pin, 30 | uint8_t ch2_pin, 31 | uint8_t ch3_pin); 32 | 33 | 34 | // Returns NRF_ERROR_INVALID_PARAM if the given ch_index is not assigned 35 | // to a pin. The p_value variable will be scaled to the range 36 | // [BRUSHED_DC_MOTOR_MIN_VALUE, BRUSHED_DC_MOTOR_MAX_VALUE]. 37 | uint32_t brushed_dc_motor_value_get(brushed_dc_motor_group_t * p_group, 38 | uint8_t ch_index, 39 | uint8_t * p_value); 40 | 41 | 42 | // Returns NRF_ERROR_INVALID_PARAM if the given ch_index is not assigned 43 | // to a pin. The value variable shouldbe be in the range 44 | // [BRUSHED_DC_MOTOR_MIN_VALUE, BRUSHED_DC_MOTOR_MAX_VALUE]. 45 | uint32_t brushed_dc_motor_value_set(brushed_dc_motor_group_t * p_group, 46 | uint8_t ch_index, 47 | uint8_t value); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/examples/common/electronic_speed_controller.c: -------------------------------------------------------------------------------- 1 | #include "electronic_speed_controller.h" 2 | 3 | #include "nrf_pwm.h" 4 | #include "nrf_drv_pwm.h" 5 | #include "app_util_platform.h" 6 | #include "utility.h" 7 | 8 | 9 | // If this flag is not set in the sequence values that are passed to 10 | // nrf_drv_pwm then the polarity of the PWM waveform will be inverted. 11 | // Inverted values are not useful to a servo so it is assumed that if 12 | // a value in a sequence doesn't have this flag set then that channel 13 | // is not enabled. 14 | #define CH_ENABLED_MASK (0x8000UL) 15 | 16 | // The ideal servo range (in microseconds) 17 | #define ESC_MIN_VALUE (1000UL) 18 | #define ESC_MAX_VALUE (2000UL) 19 | 20 | 21 | uint32_t esc_throttle_group_init(esc_throttle_group_t * p_group, 22 | uint8_t pwm_instance_index, 23 | uint8_t ch0_pin, 24 | uint8_t ch1_pin, 25 | uint8_t ch2_pin, 26 | uint8_t ch3_pin) 27 | { 28 | uint32_t err_code; 29 | 30 | if (NULL == p_group) 31 | { 32 | return NRF_ERROR_INVALID_PARAM; 33 | } 34 | 35 | switch (pwm_instance_index) 36 | { 37 | case 0: 38 | p_group->pwm_instance.p_registers = NRF_PWM0; 39 | p_group->pwm_instance.drv_inst_idx = PWM0_INSTANCE_INDEX; 40 | break; 41 | case 1: 42 | p_group->pwm_instance.p_registers = NRF_PWM1; 43 | p_group->pwm_instance.drv_inst_idx = PWM1_INSTANCE_INDEX; 44 | break; 45 | case 2: 46 | p_group->pwm_instance.p_registers = NRF_PWM2; 47 | p_group->pwm_instance.drv_inst_idx = PWM2_INSTANCE_INDEX; 48 | break; 49 | #ifdef NRF52840_XXAA 50 | case 3: 51 | p_group->pwm_instance.p_registers = NRF_PWM3; 52 | p_group->pwm_instance.drv_inst_idx = PWM3_INSTANCE_INDEX; 53 | break; 54 | #endif 55 | default: 56 | return NRF_ERROR_INVALID_PARAM; 57 | } 58 | 59 | nrf_drv_pwm_config_t const pwm_config = 60 | { 61 | .output_pins = 62 | { 63 | ch0_pin, 64 | ch1_pin, 65 | ch2_pin, 66 | ch3_pin 67 | }, 68 | .irq_priority = APP_IRQ_PRIORITY_LOWEST, 69 | .base_clock = NRF_PWM_CLK_1MHz, 70 | .count_mode = NRF_PWM_MODE_UP, 71 | .top_value = 20000, // 20ms 72 | .load_mode = NRF_PWM_LOAD_INDIVIDUAL, 73 | .step_mode = NRF_PWM_STEP_AUTO 74 | }; 75 | 76 | err_code = nrf_drv_pwm_init(&p_group->pwm_instance, &pwm_config, NULL); 77 | if (NRF_SUCCESS != err_code) 78 | { 79 | return err_code; 80 | } 81 | 82 | if (ESC_THROTTLE_PIN_NOT_USED != ch0_pin) 83 | { 84 | p_group->pwm_values.channel_0 = (CH_ENABLED_MASK|ESC_MIN_VALUE); 85 | } 86 | else 87 | { 88 | p_group->pwm_values.channel_0 = 0; 89 | } 90 | 91 | if (ESC_THROTTLE_PIN_NOT_USED != ch1_pin) 92 | { 93 | p_group->pwm_values.channel_1 = (CH_ENABLED_MASK|ESC_MIN_VALUE); 94 | } 95 | else 96 | { 97 | p_group->pwm_values.channel_1 = 0; 98 | } 99 | 100 | if (ESC_THROTTLE_PIN_NOT_USED != ch2_pin) 101 | { 102 | p_group->pwm_values.channel_2 = (CH_ENABLED_MASK|ESC_MIN_VALUE); 103 | } 104 | else 105 | { 106 | p_group->pwm_values.channel_2 = 0; 107 | } 108 | 109 | if (ESC_THROTTLE_PIN_NOT_USED != ch3_pin) 110 | { 111 | p_group->pwm_values.channel_3 = (CH_ENABLED_MASK|ESC_MIN_VALUE); 112 | } 113 | else 114 | { 115 | p_group->pwm_values.channel_3 = 0; 116 | } 117 | 118 | nrf_pwm_sequence_t const seq = 119 | { 120 | .values.p_individual = &p_group->pwm_values, 121 | .length = 4, 122 | .repeats = 0, 123 | .end_delay = 0 124 | }; 125 | 126 | err_code = nrf_drv_pwm_simple_playback(&p_group->pwm_instance, 127 | &seq, 128 | 1, 129 | NRF_DRV_PWM_FLAG_LOOP); 130 | return err_code; 131 | } 132 | 133 | 134 | uint32_t esc_throttle_value_get(esc_throttle_group_t * p_group, 135 | uint8_t ch_index, 136 | uint8_t * p_value) 137 | { 138 | uint16_t temp; 139 | uint16_t * p_channel_value; 140 | 141 | switch (ch_index) 142 | { 143 | case 0: 144 | p_channel_value = &p_group->pwm_values.channel_0; 145 | break; 146 | case 1: 147 | p_channel_value = &p_group->pwm_values.channel_1; 148 | break; 149 | case 2: 150 | p_channel_value = &p_group->pwm_values.channel_2; 151 | break; 152 | case 3: 153 | p_channel_value = &p_group->pwm_values.channel_3; 154 | break; 155 | default: 156 | return NRF_ERROR_INVALID_PARAM; 157 | } 158 | 159 | if (0 == (*p_channel_value & CH_ENABLED_MASK)) 160 | { 161 | return NRF_ERROR_INVALID_PARAM; 162 | } 163 | 164 | temp = pam((*p_channel_value & ~CH_ENABLED_MASK), 165 | ESC_THROTTLE_MIN_VALUE, 166 | ESC_THROTTLE_MAX_VALUE); 167 | *p_value = (uint8_t)temp; 168 | 169 | return NRF_SUCCESS; 170 | } 171 | 172 | 173 | uint32_t esc_throttle_value_set(esc_throttle_group_t * p_group, 174 | uint8_t ch_index, 175 | uint8_t value) 176 | { 177 | uint16_t temp; 178 | uint16_t * p_channel_value; 179 | 180 | if (ESC_THROTTLE_MAX_VALUE < value) 181 | { 182 | return NRF_ERROR_INVALID_PARAM; 183 | } 184 | 185 | switch (ch_index) 186 | { 187 | case 0: 188 | p_channel_value = &p_group->pwm_values.channel_0; 189 | break; 190 | case 1: 191 | p_channel_value = &p_group->pwm_values.channel_1; 192 | break; 193 | case 2: 194 | p_channel_value = &p_group->pwm_values.channel_2; 195 | break; 196 | case 3: 197 | p_channel_value = &p_group->pwm_values.channel_3; 198 | break; 199 | default: 200 | return NRF_ERROR_INVALID_PARAM; 201 | } 202 | 203 | if (0 == (*p_channel_value & CH_ENABLED_MASK)) 204 | { 205 | return NRF_ERROR_INVALID_PARAM; 206 | } 207 | 208 | temp = map(value, ESC_MIN_VALUE, ESC_MAX_VALUE); 209 | *p_channel_value = (temp | CH_ENABLED_MASK); 210 | 211 | return NRF_SUCCESS; 212 | } 213 | -------------------------------------------------------------------------------- /src/examples/common/electronic_speed_controller.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple wrapper around the nrf_drv_pwm driver's nrf_drv_pwm_simple_playback 3 | * functionality. 4 | */ 5 | #ifndef ESC_H 6 | #define ESC_H 7 | 8 | #include "nrf_pwm.h" 9 | #include "nrf_drv_pwm.h" 10 | 11 | 12 | #define ESC_THROTTLE_MIN_VALUE (0L) 13 | #define ESC_THROTTLE_MAX_VALUE (100UL) 14 | 15 | #define ESC_THROTTLE_PIN_NOT_USED (NRF_DRV_PWM_PIN_NOT_USED) 16 | 17 | 18 | // Structs of this type need to kept in the global portion (static) of RAM 19 | // (not const) because they are accessed by EasyDMA. 20 | typedef struct 21 | { 22 | nrf_drv_pwm_t pwm_instance; 23 | nrf_pwm_values_individual_t pwm_values; 24 | } esc_throttle_group_t; 25 | 26 | 27 | // The pwm_instance should be in the range [0, 2] on the nRF52832. The chX_pins 28 | // can be set to any GPIO or set to ESC_THROTTLE_PIN_NOT_USED if the channel is 29 | // not required. 30 | uint32_t esc_throttle_group_init(esc_throttle_group_t * p_group, 31 | uint8_t pwm_instance_index, 32 | uint8_t ch0_pin, 33 | uint8_t ch1_pin, 34 | uint8_t ch2_pin, 35 | uint8_t ch3_pin); 36 | 37 | 38 | // Returns NRF_ERROR_INVALID_PARAM if the given ch_index is not assigned to a 39 | // pin. The p_value variable will be scaled to the range 40 | // [ESC_THROTTLE_MIN_VALUE, ESC_THROTTLE_MAX_VALUE]. 41 | uint32_t esc_throttle_value_get(esc_throttle_group_t * p_group, 42 | uint8_t ch_index, 43 | uint8_t * p_value); 44 | 45 | 46 | // Returns NRF_ERROR_INVALID_PARAM if the given ch_index is not assigned to a 47 | // pin. The value variable shouldbe be in the range 48 | // [ESC_THROTTLE_MIN_VALUE, ESC_THROTTLE_MAX_VALUE]. 49 | uint32_t esc_throttle_value_set(esc_throttle_group_t * p_group, 50 | uint8_t ch_index, 51 | uint8_t value); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/examples/common/joystick.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple wrapper that uses a timer and the PPI to trigger ADC reads. The 3 | * values are scaled before the joystick_event_handler is called. 4 | * 5 | * Sometimes wiring is easier if one of the joysticks is mounted upside down. 6 | * The INVERT_L_X_AXIS, INVERT_L_Y_AXIS, INVERT_R_X_AXIS, and/or 7 | * INVERT_R_Y_AXIS symbols can be set to 1 in the Makefile to correct for this. 8 | */ 9 | #ifndef JOYSTICK_H 10 | #define JOYSTICK_H 11 | 12 | #include "stdint.h" 13 | 14 | #ifdef NRF52840_XXAA 15 | #include "nrf52840_bitfields.h" 16 | #else 17 | #include "nrf52_bitfields.h" 18 | #endif 19 | 20 | 21 | #define JOYSTICK_MIN_VALUE (0UL) 22 | #define JOYSTICK_MAX_VALUE (100UL) 23 | #define JOYSTICK_INVALID_VALUE (0xFFUL) 24 | 25 | 26 | typedef enum 27 | { 28 | JOYSTICK_PIN_0 = SAADC_CH_PSELP_PSELP_AnalogInput0, // P0.2 29 | JOYSTICK_PIN_1 = SAADC_CH_PSELP_PSELP_AnalogInput1, // P0.3 30 | JOYSTICK_PIN_2 = SAADC_CH_PSELP_PSELP_AnalogInput2, // P0.4 31 | JOYSTICK_PIN_3 = SAADC_CH_PSELP_PSELP_AnalogInput3, // P0.5 32 | JOYSTICK_PIN_4 = SAADC_CH_PSELP_PSELP_AnalogInput4, // P0.28 33 | JOYSTICK_PIN_5 = SAADC_CH_PSELP_PSELP_AnalogInput5, // P0.29 34 | JOYSTICK_PIN_6 = SAADC_CH_PSELP_PSELP_AnalogInput6, // P0.30 35 | JOYSTICK_PIN_7 = SAADC_CH_PSELP_PSELP_AnalogInput7, // P0.31 36 | JOYSTICK_PIN_NOT_USED = 0xFF, 37 | JOYSTICK_PIN_AIN_COUNT 38 | } joystick_pin_t; 39 | 40 | 41 | typedef void (*joystick_event_handler_t)(uint8_t l_axis_x_value, 42 | uint8_t l_axis_y_value, 43 | uint8_t r_axis_x_value, 44 | uint8_t r_axis_y_value); 45 | 46 | 47 | /** 48 | * Inits a timer that triggers the SAADC at the given rate. The timer instance 49 | * is used to select a free timer peripheral (e.g. 0 is converted to TIMER0). 50 | */ 51 | uint32_t joystick_init(uint8_t timer_instance_index, 52 | uint8_t update_rate_hz, 53 | joystick_event_handler_t joystick_event_handler, 54 | joystick_pin_t l_x_axis_pin, 55 | joystick_pin_t l_y_axis_pin, 56 | joystick_pin_t r_x_axis_pin, 57 | joystick_pin_t r_y_axis_pin); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/examples/common/radioshack_micro_servo.c: -------------------------------------------------------------------------------- 1 | #include "servo.h" 2 | 3 | #include "nrf_pwm.h" 4 | #include "nrf_drv_pwm.h" 5 | #include "app_util_platform.h" 6 | 7 | 8 | // If this flag is not set in the sequence values that are passed to 9 | // nrf_drv_pwm then the polarity of the PWM waveform will be inverted. 10 | // Inverted values are not useful to a servo so it is assumed that if 11 | // a value in a sequence doesn't have this flag set then that channel 12 | // is not enabled. 13 | #define CH_ENABLED_MASK (0x8000UL) 14 | 15 | // The RadioShack micro servo's usable range. 16 | #define RSMS_MIN_VALUE (600UL) 17 | #define RSMS_MAX_VALUE (2500UL) 18 | #define RSMS_NEUTRAL_VALUE (((RSMS_MAX_VALUE-RSMS_MIN_VALUE)/2)+RSMS_MIN_VALUE) 19 | 20 | // Simple functions for mapping a value betwen [0, 100] to the 21 | // range [RSMS_MIN_VALUE, RSMS_MAX_VALUE] and vice versa. 22 | #define MAP(x) ((x) * (RSMS_MAX_VALUE - RSMS_MIN_VALUE)/100 + RSMS_MIN_VALUE) 23 | #define PAM(x) (((x) - RSMS_MIN_VALUE) * 100 / (RSMS_MAX_VALUE-RSMS_MIN_VALUE)) 24 | 25 | 26 | uint32_t servo_group_init(servo_group_t * p_group, 27 | uint8_t pwm_instance_index, 28 | uint8_t ch0_pin, 29 | uint8_t ch1_pin, 30 | uint8_t ch2_pin, 31 | uint8_t ch3_pin) 32 | { 33 | uint32_t err_code; 34 | 35 | if (NULL == p_group) 36 | { 37 | return NRF_ERROR_INVALID_PARAM; 38 | } 39 | 40 | switch (pwm_instance_index) 41 | { 42 | case 0: 43 | p_group->pwm_instance.p_registers = NRF_PWM0; 44 | p_group->pwm_instance.drv_inst_idx = PWM0_INSTANCE_INDEX; 45 | break; 46 | case 1: 47 | p_group->pwm_instance.p_registers = NRF_PWM1; 48 | p_group->pwm_instance.drv_inst_idx = PWM1_INSTANCE_INDEX; 49 | break; 50 | case 2: 51 | p_group->pwm_instance.p_registers = NRF_PWM2; 52 | p_group->pwm_instance.drv_inst_idx = PWM2_INSTANCE_INDEX; 53 | break; 54 | #ifdef NRF52840_XXAA 55 | case 3: 56 | p_group->pwm_instance.p_registers = NRF_PWM3; 57 | p_group->pwm_instance.drv_inst_idx = PWM3_INSTANCE_INDEX; 58 | break; 59 | #endif 60 | default: 61 | return NRF_ERROR_INVALID_PARAM; 62 | } 63 | 64 | nrf_drv_pwm_config_t const pwm_config = 65 | { 66 | .output_pins = 67 | { 68 | ch0_pin, 69 | ch1_pin, 70 | ch2_pin, 71 | ch3_pin 72 | }, 73 | .irq_priority = APP_IRQ_PRIORITY_LOWEST, 74 | .base_clock = NRF_PWM_CLK_1MHz, 75 | .count_mode = NRF_PWM_MODE_UP, 76 | .top_value = 20000, // 20ms 77 | .load_mode = NRF_PWM_LOAD_INDIVIDUAL, 78 | .step_mode = NRF_PWM_STEP_AUTO 79 | }; 80 | 81 | err_code = nrf_drv_pwm_init(&p_group->pwm_instance, &pwm_config, NULL); 82 | if (NRF_SUCCESS != err_code) 83 | { 84 | return err_code; 85 | } 86 | 87 | if (SERVO_PIN_NOT_USED != ch0_pin) 88 | { 89 | p_group->pwm_values.channel_0 = (CH_ENABLED_MASK|RSMS_NEUTRAL_VALUE); 90 | } 91 | else 92 | { 93 | p_group->pwm_values.channel_0 = 0; 94 | } 95 | 96 | if (SERVO_PIN_NOT_USED != ch1_pin) 97 | { 98 | p_group->pwm_values.channel_1 = (CH_ENABLED_MASK|RSMS_NEUTRAL_VALUE); 99 | } 100 | else 101 | { 102 | p_group->pwm_values.channel_1 = 0; 103 | } 104 | 105 | if (SERVO_PIN_NOT_USED != ch2_pin) 106 | { 107 | p_group->pwm_values.channel_2 = (CH_ENABLED_MASK|RSMS_NEUTRAL_VALUE); 108 | } 109 | else 110 | { 111 | p_group->pwm_values.channel_2 = 0; 112 | } 113 | 114 | if (SERVO_PIN_NOT_USED != ch3_pin) 115 | { 116 | p_group->pwm_values.channel_3 = (CH_ENABLED_MASK|RSMS_NEUTRAL_VALUE); 117 | } 118 | else 119 | { 120 | p_group->pwm_values.channel_3 = 0; 121 | } 122 | 123 | nrf_pwm_sequence_t const seq = 124 | { 125 | .values.p_individual = &p_group->pwm_values, 126 | .length = 4, 127 | .repeats = 0, 128 | .end_delay = 0 129 | }; 130 | err_code = nrf_drv_pwm_simple_playback(&p_group->pwm_instance, 131 | &seq, 132 | 1, 133 | NRF_DRV_PWM_FLAG_LOOP); 134 | return err_code; 135 | } 136 | 137 | 138 | uint32_t servo_value_get(servo_group_t * p_group, 139 | uint8_t ch_index, 140 | uint8_t * p_value) 141 | { 142 | uint16_t * p_channel_value; 143 | 144 | switch (ch_index) 145 | { 146 | case 0: 147 | p_channel_value = &p_group->pwm_values.channel_0; 148 | break; 149 | case 1: 150 | p_channel_value = &p_group->pwm_values.channel_1; 151 | break; 152 | case 2: 153 | p_channel_value = &p_group->pwm_values.channel_2; 154 | break; 155 | case 3: 156 | p_channel_value = &p_group->pwm_values.channel_3; 157 | break; 158 | default: 159 | return NRF_ERROR_INVALID_PARAM; 160 | } 161 | 162 | if (0 == (*p_channel_value & CH_ENABLED_MASK)) 163 | { 164 | return NRF_ERROR_INVALID_PARAM; 165 | } 166 | 167 | *p_value = (uint8_t)PAM((*p_channel_value & ~CH_ENABLED_MASK)); 168 | 169 | return NRF_SUCCESS; 170 | } 171 | 172 | 173 | uint32_t servo_value_set(servo_group_t * p_group, 174 | uint8_t ch_index, 175 | uint8_t value) 176 | { 177 | uint16_t * p_channel_value; 178 | 179 | if (SERVO_MAX_VALUE < value) 180 | { 181 | return NRF_ERROR_INVALID_PARAM; 182 | } 183 | 184 | switch (ch_index) 185 | { 186 | case 0: 187 | p_channel_value = &p_group->pwm_values.channel_0; 188 | break; 189 | case 1: 190 | p_channel_value = &p_group->pwm_values.channel_1; 191 | break; 192 | case 2: 193 | p_channel_value = &p_group->pwm_values.channel_2; 194 | break; 195 | case 3: 196 | p_channel_value = &p_group->pwm_values.channel_3; 197 | break; 198 | default: 199 | return NRF_ERROR_INVALID_PARAM; 200 | } 201 | 202 | if (0 == (*p_channel_value & CH_ENABLED_MASK)) 203 | { 204 | return NRF_ERROR_INVALID_PARAM; 205 | } 206 | 207 | *p_channel_value = (MAP(value) | CH_ENABLED_MASK); 208 | 209 | return NRF_SUCCESS; 210 | } 211 | -------------------------------------------------------------------------------- /src/examples/common/sainsmart_joystick.c: -------------------------------------------------------------------------------- 1 | #include "nrf_saadc.h" 2 | #include "nrf_drv_saadc.h" 3 | #include "nrf_ppi.h" 4 | #include "nrf_drv_ppi.h" 5 | #include "nrf_drv_timer.h" 6 | 7 | #include "joystick.h" 8 | 9 | 10 | #ifndef INVERT_L_X_AXIS 11 | #define INVERT_L_X_AXIS 0 12 | #endif 13 | 14 | #ifndef INVERT_L_Y_AXIS 15 | #define INVERT_L_Y_AXIS 0 16 | #endif 17 | 18 | #ifndef INVERT_R_X_AXIS 19 | #define INVERT_R_X_AXIS 0 20 | #endif 21 | 22 | #ifndef INVERT_R_Y_AXIS 23 | #define INVERT_R_Y_AXIS 0 24 | #endif 25 | 26 | 27 | #define JOYSTICK_MAX_CHANNELS (4UL) 28 | 29 | #define SAINSMART_MIN_VALUE (0UL) 30 | #define SAINSMART_MAX_VALUE (3120UL) 31 | #define SAINSMART_NEUTRAL_VALUE (1620UL) 32 | 33 | 34 | // Simple function for mapping a value betwen [0, 100] to the 35 | // range [JOYSTICK_MIN_VALUE, JOYSTICK_MAX_VALUE]. 36 | #define PAM(x) (((x) - SAINSMART_MIN_VALUE) * 100 / (SAINSMART_MAX_VALUE - SAINSMART_MIN_VALUE)) 37 | 38 | 39 | static nrf_saadc_value_t m_buffer_pool[2][JOYSTICK_MAX_CHANNELS]; 40 | static nrf_ppi_channel_t m_ppi_channel; 41 | static nrf_drv_timer_t m_timer; 42 | static joystick_event_handler_t m_handler; 43 | static uint8_t m_enabled_channels; 44 | static bool m_l_x_enabled=false; 45 | static bool m_l_y_enabled=false; 46 | static bool m_r_x_enabled=false; 47 | static bool m_r_y_enabled=false; 48 | 49 | 50 | static void m_timer_handler(nrf_timer_event_t event_type, void * p_context) 51 | { 52 | // Required but not used. 53 | } 54 | 55 | 56 | static uint32_t m_saadc_sampling_event_init(uint32_t sampling_interval_ms) 57 | { 58 | ret_code_t err_code; 59 | uint32_t timer_compare_event_addr; 60 | uint32_t saadc_sample_task_addr; 61 | 62 | err_code = nrf_drv_ppi_init(); 63 | if (NRF_SUCCESS != err_code) 64 | { 65 | return err_code; 66 | } 67 | 68 | nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; 69 | timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32; 70 | 71 | err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, m_timer_handler); 72 | if (NRF_SUCCESS != err_code) 73 | { 74 | return err_code; 75 | } 76 | 77 | uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, sampling_interval_ms); 78 | nrf_drv_timer_extended_compare(&m_timer, 79 | NRF_TIMER_CC_CHANNEL0, 80 | ticks, 81 | NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, 82 | false); 83 | nrf_drv_timer_enable(&m_timer); 84 | 85 | timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer, 86 | NRF_TIMER_CC_CHANNEL0); 87 | saadc_sample_task_addr = nrf_drv_saadc_sample_task_get(); 88 | 89 | // Setup PPI channel so that timer compare event is triggering sample 90 | // task in SAADC. 91 | err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel); 92 | if (NRF_SUCCESS != err_code) 93 | { 94 | return err_code; 95 | } 96 | 97 | err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, 98 | timer_compare_event_addr, 99 | saadc_sample_task_addr); 100 | return err_code; 101 | } 102 | 103 | 104 | static void m_saadc_callback(nrf_drv_saadc_evt_t const * p_event) 105 | { 106 | if (p_event->type == NRF_DRV_SAADC_EVT_DONE) 107 | { 108 | ret_code_t err_code; 109 | uint32_t i = 0; 110 | uint32_t l_x, l_y, r_x, r_y; 111 | 112 | err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, m_enabled_channels); 113 | APP_ERROR_CHECK(err_code); 114 | 115 | if (m_l_x_enabled) 116 | { 117 | l_x = p_event->data.done.p_buffer[i]; 118 | 119 | if (l_x > SAINSMART_MAX_VALUE) 120 | { 121 | l_x = SAINSMART_MAX_VALUE; 122 | } 123 | #if INVERT_L_X_AXIS 124 | l_x = PAM(SAINSMART_MAX_VALUE - l_x); 125 | #else 126 | l_x = PAM(l_x); 127 | #endif 128 | i++; 129 | } 130 | else 131 | { 132 | l_x = JOYSTICK_INVALID_VALUE; 133 | } 134 | 135 | if (m_l_y_enabled) 136 | { 137 | l_y = p_event->data.done.p_buffer[i]; 138 | 139 | if (l_y > SAINSMART_MAX_VALUE) 140 | { 141 | l_y = SAINSMART_MAX_VALUE; 142 | } 143 | #if INVERT_L_Y_AXIS 144 | l_y = PAM(SAINSMART_MAX_VALUE - l_y); 145 | #else 146 | l_y = PAM(l_y); 147 | #endif 148 | i++; 149 | } 150 | else 151 | { 152 | l_y = JOYSTICK_INVALID_VALUE; 153 | } 154 | 155 | if (m_r_x_enabled) 156 | { 157 | r_x = p_event->data.done.p_buffer[i]; 158 | 159 | if (r_x > SAINSMART_MAX_VALUE) 160 | { 161 | r_x = SAINSMART_MAX_VALUE; 162 | } 163 | #if INVERT_R_X_AXIS 164 | r_x = PAM(SAINSMART_MAX_VALUE - r_x); 165 | #else 166 | r_x = PAM(r_x); 167 | #endif 168 | i++; 169 | } 170 | else 171 | { 172 | r_x = JOYSTICK_INVALID_VALUE; 173 | } 174 | 175 | if (m_r_y_enabled) 176 | { 177 | r_y = p_event->data.done.p_buffer[i]; 178 | 179 | if (r_y > SAINSMART_MAX_VALUE) 180 | { 181 | r_y = SAINSMART_MAX_VALUE; 182 | } 183 | #if INVERT_R_Y_AXIS 184 | r_y = PAM(SAINSMART_MAX_VALUE - r_y); 185 | #else 186 | r_y = PAM(r_y); 187 | #endif 188 | i++; 189 | } 190 | else 191 | { 192 | r_y = JOYSTICK_INVALID_VALUE; 193 | } 194 | 195 | m_handler(l_x, l_y, r_x, r_y); 196 | } 197 | } 198 | 199 | 200 | uint32_t joystick_init(uint8_t timer_instance_index, 201 | uint8_t update_rate_hz, 202 | joystick_event_handler_t joystick_event_handler, 203 | joystick_pin_t l_x_axis_pin, 204 | joystick_pin_t l_y_axis_pin, 205 | joystick_pin_t r_x_axis_pin, 206 | joystick_pin_t r_y_axis_pin) 207 | { 208 | ret_code_t err_code; 209 | 210 | if (NULL == joystick_event_handler) 211 | { 212 | return NRF_ERROR_INVALID_PARAM; 213 | } 214 | 215 | m_handler = joystick_event_handler; 216 | 217 | nrf_drv_saadc_config_t saadc_config = { 218 | .resolution = NRF_SAADC_RESOLUTION_12BIT, \ 219 | .oversample = NRF_SAADC_OVERSAMPLE_DISABLED, \ 220 | .interrupt_priority = 7, \ 221 | .low_power_mode = false \ 222 | }; 223 | 224 | err_code = nrf_drv_saadc_init(&saadc_config, m_saadc_callback); 225 | if (NRF_SUCCESS != err_code) 226 | { 227 | return err_code; 228 | } 229 | 230 | m_enabled_channels = 0; 231 | 232 | if (JOYSTICK_PIN_NOT_USED != l_x_axis_pin) 233 | { 234 | nrf_saadc_channel_config_t channel_config = 235 | NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(l_x_axis_pin); 236 | 237 | err_code = nrf_drv_saadc_channel_init(m_enabled_channels, &channel_config); 238 | if (NRF_SUCCESS != err_code) 239 | { 240 | return err_code; 241 | } 242 | m_enabled_channels++; 243 | m_l_x_enabled = true; 244 | } 245 | 246 | if (JOYSTICK_PIN_NOT_USED != l_y_axis_pin) 247 | { 248 | nrf_saadc_channel_config_t channel_config = 249 | NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(l_y_axis_pin); 250 | 251 | err_code = nrf_drv_saadc_channel_init(m_enabled_channels, &channel_config); 252 | if (NRF_SUCCESS != err_code) 253 | { 254 | return err_code; 255 | } 256 | m_enabled_channels++; 257 | m_l_y_enabled = true; 258 | } 259 | 260 | if (JOYSTICK_PIN_NOT_USED != r_x_axis_pin) 261 | { 262 | nrf_saadc_channel_config_t channel_config = 263 | NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(r_x_axis_pin); 264 | 265 | err_code = nrf_drv_saadc_channel_init(m_enabled_channels, &channel_config); 266 | if (NRF_SUCCESS != err_code) 267 | { 268 | return err_code; 269 | } 270 | m_enabled_channels++; 271 | m_r_x_enabled = true; 272 | } 273 | 274 | if (JOYSTICK_PIN_NOT_USED != r_y_axis_pin) 275 | { 276 | nrf_saadc_channel_config_t channel_config = 277 | NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(r_y_axis_pin); 278 | 279 | err_code = nrf_drv_saadc_channel_init(m_enabled_channels, &channel_config); 280 | if (NRF_SUCCESS != err_code) 281 | { 282 | return err_code; 283 | } 284 | m_enabled_channels++; 285 | m_r_y_enabled = true; 286 | } 287 | 288 | err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], m_enabled_channels); 289 | if (NRF_SUCCESS != err_code) 290 | { 291 | return err_code; 292 | } 293 | 294 | err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], m_enabled_channels); 295 | if (NRF_SUCCESS != err_code) 296 | { 297 | return err_code; 298 | } 299 | 300 | switch (timer_instance_index) 301 | { 302 | case 0: 303 | m_timer.p_reg = NRF_TIMER0; 304 | m_timer.instance_id = TIMER0_INSTANCE_INDEX; 305 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(0); 306 | break; 307 | case 1: 308 | m_timer.p_reg = NRF_TIMER1; 309 | m_timer.instance_id = TIMER1_INSTANCE_INDEX; 310 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(1); 311 | break; 312 | case 2: 313 | m_timer.p_reg = NRF_TIMER2; 314 | m_timer.instance_id = TIMER2_INSTANCE_INDEX; 315 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(2); 316 | break; 317 | case 3: 318 | m_timer.p_reg = NRF_TIMER3; 319 | m_timer.instance_id = TIMER3_INSTANCE_INDEX; 320 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(3); 321 | break; 322 | case 4: 323 | m_timer.p_reg = NRF_TIMER4; 324 | m_timer.instance_id = TIMER4_INSTANCE_INDEX; 325 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(4); 326 | break; 327 | default: 328 | return NRF_ERROR_INVALID_PARAM; 329 | } 330 | 331 | err_code = m_saadc_sampling_event_init(1000 / update_rate_hz); 332 | if (NRF_SUCCESS != err_code) 333 | { 334 | return err_code; 335 | } 336 | 337 | err_code = nrf_drv_ppi_channel_enable(m_ppi_channel); 338 | if (NRF_SUCCESS != err_code) 339 | { 340 | return err_code; 341 | } 342 | 343 | return NRF_SUCCESS; 344 | } 345 | -------------------------------------------------------------------------------- /src/examples/common/servo.h: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple wrapper around the nrf_drv_pwm driver's nrf_drv_pwm_simple_playback 3 | * functionality. 4 | */ 5 | #ifndef SERVO_H 6 | #define SERVO_H 7 | 8 | #include "nrf_pwm.h" 9 | #include "nrf_drv_pwm.h" 10 | 11 | 12 | #define SERVO_MIN_VALUE (0UL) 13 | #define SERVO_NEUTRAL_VALUE (50UL) 14 | #define SERVO_MAX_VALUE (100UL) 15 | 16 | #define SERVO_PIN_NOT_USED (NRF_DRV_PWM_PIN_NOT_USED) 17 | 18 | 19 | // Structs of this type need to kept in the global portion (static) of RAM 20 | // (not const) because they are accessed by EasyDMA. 21 | typedef struct 22 | { 23 | nrf_drv_pwm_t pwm_instance; 24 | nrf_pwm_values_individual_t pwm_values; 25 | } servo_group_t; 26 | 27 | 28 | // The pwm_instance should be in the range [0, 2] on the nRF52832. The chX_pins 29 | // can be set to any GPIO or set to SERVO_PIN_NOT_USED if the channel is not 30 | // required. 31 | uint32_t servo_group_init(servo_group_t * p_group, 32 | uint8_t pwm_instance_index, 33 | uint8_t ch0_pin, 34 | uint8_t ch1_pin, 35 | uint8_t ch2_pin, 36 | uint8_t ch3_pin); 37 | 38 | 39 | // Returns NRF_ERROR_INVALID_PARAM if the given ch_index is not assigned to a 40 | // pin. The p_value variable will be scaled to the range 41 | // [SERVO_MIN_VALUE, SERVO_MAX_VALUE]. 42 | uint32_t servo_value_get(servo_group_t * p_group, 43 | uint8_t ch_index, 44 | uint8_t * p_value); 45 | 46 | 47 | // Returns NRF_ERROR_INVALID_PARAM if the given ch_index is not assigned to a 48 | // pin. The value variable shouldbe be in the range 49 | // [SERVO_MIN_VALUE, SERVO_MAX_VALUE]. 50 | uint32_t servo_value_set(servo_group_t * p_group, 51 | uint8_t ch_index, 52 | uint8_t value); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/examples/common/utility.c: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | 3 | 4 | inline uint32_t map(uint8_t value, uint32_t min, uint32_t max) 5 | { 6 | return (value * (max - min) / 100 + min); 7 | } 8 | 9 | 10 | inline uint8_t pam(uint32_t value, uint32_t min, uint32_t max) 11 | { 12 | return ((value - min) * 100 / (max - min)); 13 | } 14 | -------------------------------------------------------------------------------- /src/examples/common/utility.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITY_H 2 | #define UTILITY_H 3 | 4 | #include "stdint.h" 5 | 6 | 7 | /** 8 | * Maps a value from the range [0, 100] to [min, max]. 9 | */ 10 | uint32_t map(uint8_t value, uint32_t min, uint32_t max); 11 | 12 | /** 13 | * Maps a value from the range [min, max] to [0, 100]. 14 | */ 15 | uint8_t pam(uint32_t value, uint32_t min, uint32_t max); 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/examples/rx/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sdk_common.h" 4 | #include "nrf.h" 5 | #include "nrf_esb_error_codes.h" 6 | #include "nrf_delay.h" 7 | #include "nrf_gpio.h" 8 | #include "nrf_error.h" 9 | #include "boards.h" 10 | 11 | #define NRF_LOG_MODULE_NAME "APP" 12 | #include "nrf_log.h" 13 | #include "nrf_log_ctrl.h" 14 | 15 | #include "joystick.h" 16 | #include "servo.h" 17 | #include "rc_radio.h" 18 | #include "utility.h" 19 | 20 | 21 | #define RADIO_TIMER_INSTANCE (0UL) 22 | #define SERVO_PWM_INSTANCE (0UL) 23 | #define THROTTLE_PWM_INSTANCE (1UL) 24 | 25 | #define BOUND_LED_PIN (7UL) 26 | 27 | #define YAW_SERVO_PIN (31UL) 28 | #define ROLL_SERVO_PIN (30UL) 29 | #define PITCH_SERVO_PIN (29UL) 30 | #define THROTTLE_PIN (28UL) 31 | 32 | #define YAW_SERVO_CHAN (0UL) 33 | #define ROLL_SERVO_CHAN (1UL) 34 | #define PITCH_SERVO_CHAN (2UL) 35 | 36 | #define THROTTLE_CHAN (0UL) 37 | 38 | // Don't allow the servos to swing further than MAX_SERVO_DELTA 39 | // in either direction from SERVO_NEUTRAL_VALUE. 40 | #define MAX_SERVO_DELTA (15UL) 41 | 42 | 43 | #ifndef INVERT_ROLL 44 | #define INVERT_ROLL 0 45 | #endif 46 | 47 | #ifndef INVERT_YAW 48 | #define INVERT_YAW 0 49 | #endif 50 | 51 | #ifndef INVERT_PITCH 52 | #define INVERT_PITCH 0 53 | #endif 54 | 55 | #ifndef BDCM 56 | #define BDCM 0 57 | #endif 58 | 59 | #ifndef ESC 60 | #define ESC 0 61 | #endif 62 | 63 | #if (0 == BDCM) 64 | #if (0 == ESC) 65 | #error Either BDCM or ESC needs to be specified. 66 | #endif 67 | #endif 68 | 69 | #if BDCM 70 | #if ESC 71 | #error Either BDCM or ESC needs to be specified but not both. 72 | #endif 73 | #endif 74 | 75 | #if BDCM 76 | #include "brushed_dc_motor.h" 77 | #else 78 | #include "electronic_speed_controller.h" 79 | #endif 80 | 81 | 82 | static servo_group_t m_servo_group; 83 | 84 | #if BDCM 85 | static brushed_dc_motor_group_t m_brushed_dc_motor_group; 86 | #else 87 | static esc_throttle_group_t m_esc_group; 88 | #endif 89 | 90 | 91 | static void m_controls_reset(void) 92 | { 93 | uint32_t err_code; 94 | 95 | err_code = servo_value_set(&m_servo_group, 96 | ROLL_SERVO_CHAN, 97 | SERVO_NEUTRAL_VALUE); 98 | APP_ERROR_CHECK(err_code); 99 | 100 | err_code = servo_value_set(&m_servo_group, 101 | PITCH_SERVO_CHAN, 102 | SERVO_NEUTRAL_VALUE); 103 | APP_ERROR_CHECK(err_code); 104 | 105 | err_code = servo_value_set(&m_servo_group, 106 | YAW_SERVO_CHAN, 107 | SERVO_NEUTRAL_VALUE); 108 | APP_ERROR_CHECK(err_code); 109 | 110 | #if BDCM 111 | err_code = brushed_dc_motor_value_set(&m_brushed_dc_motor_group, 112 | THROTTLE_CHAN, 113 | BRUSHED_DC_MOTOR_MIN_VALUE); 114 | APP_ERROR_CHECK(err_code); 115 | #else 116 | err_code = esc_throttle_value_set(&m_esc_group, 117 | THROTTLE_CHAN, 118 | ESC_THROTTLE_MIN_VALUE); 119 | APP_ERROR_CHECK(err_code); 120 | #endif 121 | 122 | NRF_LOG_INFO("Controls reset.\r\n"); 123 | } 124 | 125 | 126 | static void m_roll_set(uint8_t raw_roll) 127 | { 128 | uint32_t err_code; 129 | uint8_t roll; 130 | 131 | #if INVERT_ROLL 132 | raw_roll = (JOYSTICK_MAX_VALUE - raw_roll); 133 | #endif 134 | 135 | if (SERVO_NEUTRAL_VALUE < raw_roll) 136 | { 137 | roll = pam(raw_roll, SERVO_NEUTRAL_VALUE, SERVO_MAX_VALUE); 138 | roll = map(roll, 139 | SERVO_NEUTRAL_VALUE, 140 | (SERVO_NEUTRAL_VALUE + MAX_SERVO_DELTA)); 141 | } 142 | else 143 | { 144 | roll = pam(raw_roll, SERVO_MIN_VALUE, SERVO_NEUTRAL_VALUE); 145 | roll = map(roll, 146 | (SERVO_NEUTRAL_VALUE - MAX_SERVO_DELTA), 147 | SERVO_NEUTRAL_VALUE); 148 | } 149 | 150 | err_code = servo_value_set(&m_servo_group, 151 | ROLL_SERVO_CHAN, 152 | roll); 153 | APP_ERROR_CHECK(err_code); 154 | 155 | NRF_LOG_INFO(" Roll: (%d) -> (%d)\r\n", raw_roll, roll); 156 | } 157 | 158 | 159 | static void m_pitch_set(uint8_t raw_pitch) 160 | { 161 | uint32_t err_code; 162 | uint8_t pitch; 163 | 164 | #if INVERT_PITCH 165 | raw_pitch = (JOYSTICK_MAX_VALUE - raw_pitch); 166 | #endif 167 | 168 | if (SERVO_NEUTRAL_VALUE < raw_pitch) 169 | { 170 | pitch = pam(raw_pitch, SERVO_NEUTRAL_VALUE, SERVO_MAX_VALUE); 171 | pitch = map(pitch, 172 | SERVO_NEUTRAL_VALUE, 173 | (SERVO_NEUTRAL_VALUE + MAX_SERVO_DELTA)); 174 | } 175 | else 176 | { 177 | pitch = pam(raw_pitch, SERVO_MIN_VALUE, SERVO_NEUTRAL_VALUE); 178 | pitch = map(pitch, 179 | (SERVO_NEUTRAL_VALUE - MAX_SERVO_DELTA), 180 | SERVO_NEUTRAL_VALUE); 181 | } 182 | 183 | err_code = servo_value_set(&m_servo_group, 184 | PITCH_SERVO_CHAN, 185 | pitch); 186 | APP_ERROR_CHECK(err_code); 187 | 188 | NRF_LOG_INFO(" Pitch: (%d) -> (%d)\r\n", raw_pitch, pitch); 189 | } 190 | 191 | 192 | static void m_yaw_set(uint8_t raw_yaw) 193 | { 194 | uint32_t err_code; 195 | uint8_t yaw; 196 | 197 | #if INVERT_YAW 198 | raw_yaw = (JOYSTICK_MAX_VALUE - raw_yaw); 199 | #endif 200 | 201 | if (SERVO_NEUTRAL_VALUE < raw_yaw) 202 | { 203 | yaw = pam(raw_yaw, SERVO_NEUTRAL_VALUE, SERVO_MAX_VALUE); 204 | yaw = map(yaw, 205 | SERVO_NEUTRAL_VALUE, 206 | (SERVO_NEUTRAL_VALUE + MAX_SERVO_DELTA)); 207 | } 208 | else 209 | { 210 | yaw = pam(raw_yaw, SERVO_MIN_VALUE, SERVO_NEUTRAL_VALUE); 211 | yaw = map(yaw, 212 | (SERVO_NEUTRAL_VALUE - MAX_SERVO_DELTA), 213 | SERVO_NEUTRAL_VALUE); 214 | } 215 | 216 | err_code = servo_value_set(&m_servo_group, 217 | YAW_SERVO_CHAN, 218 | yaw); 219 | APP_ERROR_CHECK(err_code); 220 | 221 | NRF_LOG_INFO(" Yaw: (%d) -> (%d)\r\n", raw_yaw, yaw); 222 | } 223 | 224 | 225 | static void m_throttle_set(uint8_t raw_throttle) 226 | { 227 | uint32_t err_code; 228 | uint8_t throttle; 229 | 230 | #if BDCM 231 | throttle = map(raw_throttle, 232 | BRUSHED_DC_MOTOR_MIN_VALUE, 233 | BRUSHED_DC_MOTOR_MAX_VALUE); 234 | 235 | err_code = brushed_dc_motor_value_set(&m_brushed_dc_motor_group, 236 | THROTTLE_CHAN, 237 | throttle); 238 | APP_ERROR_CHECK(err_code); 239 | #else 240 | throttle = map(raw_throttle, 241 | ESC_THROTTLE_MIN_VALUE, 242 | ESC_THROTTLE_MAX_VALUE); 243 | 244 | err_code = esc_throttle_value_set(&m_esc_group, 245 | THROTTLE_CHAN, 246 | throttle); 247 | APP_ERROR_CHECK(err_code); 248 | #endif 249 | 250 | NRF_LOG_INFO(" Throttle: (%d) -> (%d)\r\n", raw_throttle, throttle); 251 | } 252 | 253 | 254 | static void m_rc_radio_handler(rc_radio_event_t event, const void * const p_context) 255 | { 256 | switch (event) 257 | { 258 | case RC_RADIO_EVENT_BINDING: 259 | // Reset all of the control values so the plane doesn't keep flying 260 | // if the transmitter drops. 261 | m_controls_reset(); 262 | 263 | nrf_gpio_pin_set(BOUND_LED_PIN); 264 | NRF_LOG_INFO("Binding...\r\n"); 265 | break; 266 | case RC_RADIO_EVENT_BOUND: 267 | { 268 | rc_radio_bind_info_t * p_bind_info; 269 | p_bind_info = (rc_radio_bind_info_t*) p_context; 270 | 271 | nrf_gpio_pin_clear(BOUND_LED_PIN); 272 | NRF_LOG_INFO("Bound. (%d, %d)\r\n", 273 | p_bind_info->transmitter_channel, 274 | p_bind_info->transmit_rate_hz); 275 | } 276 | break; 277 | case RC_RADIO_EVENT_DATA_RECEIVED: 278 | { 279 | rc_radio_data_t * p_rc_data; 280 | p_rc_data = (rc_radio_data_t*) p_context; 281 | 282 | nrf_gpio_pin_clear(BOUND_LED_PIN); 283 | NRF_LOG_INFO("Data recieved:\r\n"); 284 | 285 | m_roll_set(p_rc_data->roll); 286 | m_pitch_set(p_rc_data->pitch); 287 | m_throttle_set(p_rc_data->throttle); 288 | m_yaw_set(p_rc_data->yaw); 289 | } 290 | break; 291 | case RC_RADIO_EVENT_PACKET_DROPPED: 292 | nrf_gpio_pin_set(BOUND_LED_PIN); 293 | NRF_LOG_INFO("Packet dropped.\r\n"); 294 | break; 295 | default: 296 | break; 297 | }; 298 | } 299 | 300 | 301 | static void m_gpio_init(void) 302 | { 303 | nrf_gpio_cfg_output(BOUND_LED_PIN); 304 | nrf_gpio_pin_set(BOUND_LED_PIN); 305 | } 306 | 307 | 308 | int main(void) 309 | { 310 | uint32_t err_code; 311 | 312 | err_code = NRF_LOG_INIT(NULL); 313 | APP_ERROR_CHECK(err_code); 314 | 315 | m_gpio_init(); 316 | 317 | err_code = servo_group_init(&m_servo_group, 318 | SERVO_PWM_INSTANCE, 319 | YAW_SERVO_PIN, 320 | ROLL_SERVO_PIN, 321 | PITCH_SERVO_PIN, 322 | SERVO_PIN_NOT_USED); 323 | APP_ERROR_CHECK(err_code); 324 | 325 | #if BDCM 326 | err_code = brushed_dc_motor_group_init(&m_brushed_dc_motor_group, 327 | THROTTLE_PWM_INSTANCE, 328 | THROTTLE_PIN, 329 | BRUSHED_DC_MOTOR_PIN_NOT_USED, 330 | BRUSHED_DC_MOTOR_PIN_NOT_USED, 331 | BRUSHED_DC_MOTOR_PIN_NOT_USED); 332 | APP_ERROR_CHECK(err_code); 333 | #else 334 | err_code = esc_throttle_group_init(&m_esc_group, 335 | THROTTLE_PWM_INSTANCE, 336 | THROTTLE_PIN, 337 | ESC_THROTTLE_PIN_NOT_USED, 338 | ESC_THROTTLE_PIN_NOT_USED, 339 | ESC_THROTTLE_PIN_NOT_USED); 340 | APP_ERROR_CHECK(err_code); 341 | #endif 342 | 343 | err_code = rc_radio_receiver_init(RADIO_TIMER_INSTANCE, 344 | m_rc_radio_handler); 345 | APP_ERROR_CHECK(err_code); 346 | 347 | err_code = rc_radio_enable(); 348 | APP_ERROR_CHECK(err_code); 349 | 350 | while (true) 351 | { 352 | if (false == NRF_LOG_PROCESS()) 353 | { 354 | __WFE(); 355 | } 356 | } 357 | } 358 | -------------------------------------------------------------------------------- /src/examples/rx/pca10040/blank/armgcc/Makefile: -------------------------------------------------------------------------------- 1 | # The PROJECT_NAME can be changed arbitrarily (it does not depend on anything). 2 | PROJECT_NAME := poly_rx 3 | 4 | SHAREDFLAGS := -DINVERT_ROLL=1 \ 5 | -DESC=1 6 | 7 | ifneq (,$(findstring -DESC=1,$(SHAREDFLAGS))) 8 | SRC_FILES := $(PROJ_DIR)/../common/electronic_speed_controller.c 9 | else 10 | SRC_FILES := $(PROJ_DIR)/../common/brushed_dc_motor.c 11 | endif 12 | 13 | # The LINKER_SCRIPT is usually in the same directory as the Makefile. 14 | LINKER_SCRIPT := poly_rx_gcc_nrf52.ld 15 | 16 | BOARD := PCA10040 17 | 18 | DBG_BUILD_DIR := ./_debug 19 | REL_BUILD_DIR := ./_release 20 | DEPS_DIR := ./_deps 21 | 22 | SDK_ROOT := ../../../../../../../../.. 23 | PROJ_DIR := ../../.. 24 | 25 | # JLINK_MON_DEBUG_DIR should point to the directory that contains the files 26 | # in JLINK_MON_DEBUG_FILES plus JLINK_MONITOR.h. If Monitor Mode Debugging is 27 | # not required then leave JLINK_MON_DEBUG_DIR empty. 28 | JLINK_MON_DEBUG_DIR := 29 | 30 | # The offset of the application needs to be specified so the J-Link knows 31 | # the location of the DebugMon_Handler. For the S132 v4 this is 0x1F000. 32 | JLINK_MON_DEBUG_APP_FLASH_LOCATION := 0x00 33 | 34 | # If the JLINK_MON_DEBUG_DIR is empty then make sure it is evaluated correctly. 35 | JLINK_MON_DEBUG_DIR := $(strip $(JLINK_MON_DEBUG_DIR)) 36 | 37 | # These are the required files as of version 6.12a of the J-Link driver. 38 | JLINK_MON_DEBUG_FILES := JLINK_MONITOR.c JLINK_MONITOR_ISR_SES.s 39 | 40 | # Init commands will be written to a file and then specified when starting GDB 41 | # instead of relying on .gdbinit (to avoid having to enable .gbdinit files). 42 | GDB_CMD_PATH := $(DBG_BUILD_DIR)/gdb.txt 43 | 44 | # Include the correct template Makefile depending on platform. 45 | TEMPLATE_PATH = $(SDK_ROOT)/components/toolchain/gcc 46 | ifeq ($(OS),Windows_NT) 47 | include $(TEMPLATE_PATH)/Makefile.windows 48 | # The Windows command shell 'start' function is used so the executable 49 | # is started in its own window. 50 | TERMINAL := cmd /c start "" 51 | TERMINAL_END := 52 | NRFJPROG := nrfjprog.exe 53 | GDBSERVER := JLinkGDBServerCL.exe 54 | RTT_CLIENT := JLinkRTTClient.exe 55 | else 56 | include $(TEMPLATE_PATH)/Makefile.posix 57 | TERMINAL := gnome-terminal -e " 58 | TERMINAL_END := " 59 | NRFJPROG := nrfjprog 60 | GDBSERVER := JLinkGDBServer 61 | RTT_CLIENT := JLinkRTTClient 62 | endif 63 | 64 | # If multiple J-Links are attached to the computer then "SN=1234" can be used 65 | # to specify a serial number for GDB and flash targets. A random GDB port will 66 | # be generated so multiple targets can be debugged simultaneously. 67 | GDB_PORT := 2331 68 | ifdef SN 69 | NRFJPROG_SN := --snr $(SN) 70 | GDB_SERVER_SN := -select usb=$(SN) 71 | GDB_PORT := $(shell awk 'BEGIN{srand();printf("%4.4s", 1000+9999*rand())}') 72 | endif 73 | 74 | # Toolchain commands (these rely on the inclusion of the template Makefile) 75 | CC := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc 76 | AS := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as 77 | AR := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar -r 78 | LD := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld 79 | NM := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm 80 | OBJDUMP := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump 81 | OBJCOPY := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy 82 | SIZE := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size 83 | GDB := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gdb 84 | 85 | SHAREDFLAGS += \ 86 | -mcpu=cortex-m4 \ 87 | -mthumb \ 88 | -DNRF52 \ 89 | -DNRF52832_XXAA \ 90 | -DCONFIG_GPIO_AS_PINRESET \ 91 | -DBOARD_$(BOARD) \ 92 | -DNRF52_PAN_74 \ 93 | -DBSP_DEFINES_ONLY \ 94 | -DESB_PRESENT 95 | 96 | CFLAGS += \ 97 | --std=gnu99 \ 98 | -Wall \ 99 | -Werror \ 100 | -mfloat-abi=hard \ 101 | -mfpu=fpv4-sp-d16 \ 102 | -ffunction-sections \ 103 | -fdata-sections \ 104 | -fno-strict-aliasing \ 105 | -fno-builtin \ 106 | --short-enums \ 107 | -mabi=aapcs \ 108 | $(SHAREDFLAGS) 109 | 110 | ASMFLAGS += \ 111 | -x assembler-with-cpp \ 112 | $(SHAREDFLAGS) 113 | 114 | LDFLAGS += \ 115 | -mthumb \ 116 | -mabi=aapcs \ 117 | -L $(TEMPLATE_PATH) \ 118 | -T$(LINKER_SCRIPT) \ 119 | -mcpu=cortex-m4 \ 120 | -mfloat-abi=hard \ 121 | -mfpu=fpv4-sp-d16 \ 122 | -Wl,--gc-sections \ 123 | --specs=nano.specs \ 124 | -lc \ 125 | -lnosys 126 | 127 | SRC_FILES += \ 128 | $(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \ 129 | $(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \ 130 | $(SDK_ROOT)/components/boards/boards.c \ 131 | $(SDK_ROOT)/components/libraries/util/app_error.c \ 132 | $(SDK_ROOT)/components/libraries/util/app_error_weak.c \ 133 | $(SDK_ROOT)/components/libraries/util/app_util_platform.c \ 134 | $(SDK_ROOT)/components/libraries/util/nrf_assert.c \ 135 | $(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \ 136 | $(SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \ 137 | $(SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \ 138 | $(PROJ_DIR)/main.c \ 139 | $(PROJ_DIR)/../common/radioshack_micro_servo.c \ 140 | $(PROJ_DIR)/../../rc_radio.c \ 141 | $(PROJ_DIR)/../common/utility.c \ 142 | $(SDK_ROOT)/external/segger_rtt/RTT_Syscalls_GCC.c \ 143 | $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \ 144 | $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \ 145 | $(SDK_ROOT)/components/proprietary_rf/esb/nrf_esb.c \ 146 | $(SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52.S \ 147 | $(SDK_ROOT)/components/toolchain/system_nrf52.c \ 148 | $(SDK_ROOT)/components/drivers_nrf/pwm/nrf_drv_pwm.c \ 149 | $(SDK_ROOT)/components/proprietary_rf/esb/nrf_esb.c \ 150 | $(SDK_ROOT)/components/drivers_nrf/timer/nrf_drv_timer.c 151 | 152 | INC_DIRS += \ 153 | $(SDK_ROOT)/components \ 154 | $(SDK_ROOT)/components/libraries/util \ 155 | $(SDK_ROOT)/components/toolchain/gcc \ 156 | $(SDK_ROOT)/components/drivers_nrf/uart \ 157 | ../config \ 158 | $(SDK_ROOT)/components/drivers_nrf/common \ 159 | $(SDK_ROOT)/components/libraries/strerror \ 160 | $(SDK_ROOT)/components/proprietary_rf/esb \ 161 | $(PROJ_DIR) \ 162 | $(PROJ_DIR)/../common \ 163 | $(PROJ_DIR)/../.. \ 164 | $(SDK_ROOT)/external/segger_rtt \ 165 | $(SDK_ROOT)/components/libraries/bsp \ 166 | $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \ 167 | $(SDK_ROOT)/components/toolchain \ 168 | $(SDK_ROOT)/components/device \ 169 | $(SDK_ROOT)/components/libraries/log \ 170 | $(SDK_ROOT)/components/boards \ 171 | $(SDK_ROOT)/components/drivers_nrf/delay \ 172 | $(SDK_ROOT)/components/toolchain/cmsis/include \ 173 | $(SDK_ROOT)/components/drivers_nrf/hal \ 174 | $(SDK_ROOT)/components/libraries/log/src \ 175 | $(SDK_ROOT)/components/drivers_nrf/pwm \ 176 | $(SDK_ROOT)/components/drivers_nrf/timer 177 | 178 | # The Monitor Mode debugging files will always be tracked by make if they are 179 | # used during debugging. They won't be passed to the linker for the release 180 | # version of the build. 181 | DBG_SRC_FILES := 182 | ifneq "$(JLINK_MON_DEBUG_DIR)" "" 183 | INC_DIRS += $(JLINK_MON_DEBUG_DIR) 184 | DBG_SRC_FILES += $(addprefix $(JLINK_MON_DEBUG_DIR)/, $(JLINK_MON_DEBUG_FILES)) 185 | else 186 | $(warning Define JLINK_MON_DEBUG_DIR to enable Monitor Mode Debugging.) 187 | endif 188 | 189 | ASSEMBLY_EXTS := s S 190 | 191 | # Convert to absolute paths and sort to remove duplicates. 192 | SRC_FILES := $(sort $(foreach f,$(SRC_FILES),$(abspath $(f)))) 193 | DBG_SRC_FILES := $(sort $(foreach f,$(DBG_SRC_FILES),$(abspath $(f)))) 194 | INC_DIRS := $(sort $(foreach d,$(INC_DIRS),$(abspath $(d)))) 195 | 196 | # Split the file paths into file names and directories. And remove duplicates. 197 | SRC_DIRS := $(sort $(dir $(SRC_FILES))) 198 | SRC_FILE_NAMES := $(notdir $(SRC_FILES)) 199 | DBG_SRC_DIRS := $(sort $(dir $(DBG_SRC_FILES))) 200 | DBG_SRC_FILE_NAMES := $(notdir $(DBG_SRC_FILES)) 201 | 202 | # Convert each source file name into the form '$(OBJ_DIR)/$(SRC_FILE).o'. 203 | OBJ := $(patsubst %,%.o,$(basename $(SRC_FILE_NAMES))) 204 | DBG_OBJ := $(patsubst %,%.o,$(basename $(DBG_SRC_FILE_NAMES))) 205 | DBG_OBJ := $(addprefix $(DBG_BUILD_DIR)/,$(OBJ) $(DBG_OBJ)) 206 | REL_OBJ := $(addprefix $(REL_BUILD_DIR)/,$(OBJ)) 207 | 208 | .PHONY: default 209 | default: CFLAGS += -O0 -ggdb -DDEBUG -DDEBUG_NRF 210 | default: OBJ_DIR := $(DBG_BUILD_DIR) 211 | default: $(DBG_BUILD_DIR)/$(PROJECT_NAME).hex 212 | $(call echosize,$(DBG_BUILD_DIR)/$(PROJECT_NAME).out) 213 | 214 | .PHONY: release 215 | release: CFLAGS += -O3 -g3 216 | release: OBJ_DIR := $(REL_BUILD_DIR) 217 | release: $(REL_BUILD_DIR)/$(PROJECT_NAME).bin $(REL_BUILD_DIR)/$(PROJECT_NAME).hex 218 | $(call echosize,$(REL_BUILD_DIR)/$(PROJECT_NAME).out) 219 | 220 | .PHONY: all 221 | all: default release 222 | 223 | DEPS := $(addprefix $(DEPS_DIR)/,$(OBJ:.o=.d)) 224 | -include $(DEPS) 225 | 226 | INCLUDES := $(patsubst %,-I%,$(INC_DIRS)) 227 | 228 | # Look for all source files in SRC_DIRS. 229 | vpath % $(SRC_DIRS) $(DBG_SRC_DIRS) 230 | 231 | define echosize 232 | @echo '' 233 | @'$(SIZE)' $1; 234 | @echo '' 235 | endef 236 | 237 | define flash 238 | @"$(NRFJPROG)" $(NRFJPROG_SN) --program $1 -f nrf52 --sectorerase --verify 239 | @"$(NRFJPROG)" $(NRFJPROG_SN) --reset -f nrf52 240 | endef 241 | 242 | $(DBG_BUILD_DIR)/%.o: %.c | $(DBG_BUILD_DIR) 243 | @echo Compiling file: $(notdir $<) 244 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c -o $@ $< 245 | 246 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).hex: $(DBG_BUILD_DIR)/$(PROJECT_NAME).out 247 | @echo Creating hex file: $(notdir $@) 248 | @'$(OBJCOPY)' -O ihex $(DBG_BUILD_DIR)/$(PROJECT_NAME).out $@ 249 | 250 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).bin: $(DBG_BUILD_DIR)/$(PROJECT_NAME).out 251 | @echo Creating bin file: $(notdir $@) 252 | @'$(OBJCOPY)' -O binary $(DBG_BUILD_DIR)/$(PROJECT_NAME).out $@ 253 | 254 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).out: $(DBG_OBJ) 255 | @echo Linking ELF file: $(notdir $@) 256 | @'$(CC)' $(LDFLAGS) $(DBG_OBJ) -lm -o $@ 257 | 258 | $(REL_BUILD_DIR)/%.o: %.c | $(REL_BUILD_DIR) 259 | @echo Compiling file: $(notdir $<) 260 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c -o $@ $< 261 | 262 | $(REL_BUILD_DIR)/$(PROJECT_NAME).hex: $(REL_BUILD_DIR)/$(PROJECT_NAME).out 263 | @echo Creating hex file: $(notdir $@) 264 | @'$(OBJCOPY)' -O ihex $(REL_BUILD_DIR)/$(PROJECT_NAME).out $@ 265 | 266 | $(REL_BUILD_DIR)/$(PROJECT_NAME).bin: $(REL_BUILD_DIR)/$(PROJECT_NAME).out 267 | @echo Creating bin file: $(notdir $@) 268 | @'$(OBJCOPY)' -O binary $(REL_BUILD_DIR)/$(PROJECT_NAME).out $@ 269 | 270 | $(REL_BUILD_DIR)/$(PROJECT_NAME).out: $(REL_OBJ) 271 | @echo Linking ELF file: $(notdir $@) 272 | @'$(CC)' $(LDFLAGS) $(REL_OBJ) -lm -o $@ 273 | 274 | $(DEPS_DIR)/%.d: %.c | $(DEPS_DIR) 275 | @echo Adding dependency for file: $(notdir $<) 276 | @echo -n "$(DBG_BUILD_DIR)/$(notdir $(<:.c=.o)) " > $@ 277 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c $< -MM \ 278 | -MT $(REL_BUILD_DIR)/$(notdir $(<:.c=.o)) >> $@ 279 | 280 | # The eval command is used to create a different version of these targets for 281 | # each extension in the ASSEMBLY_EXTS list. 282 | define assembly_targets 283 | $$(DBG_BUILD_DIR)/%.o: %.$1 | $$(DBG_BUILD_DIR) 284 | @echo Compiling assembly file: $$(notdir $$<) 285 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c -o $$@ $$< 286 | 287 | $$(REL_BUILD_DIR)/%.o: %.$1 | $$(REL_BUILD_DIR) 288 | @echo Compiling assembly file: $$(notdir $$<) 289 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c -o $$@ $$< 290 | 291 | $$(DEPS_DIR)/%.d: %.$1 | $$(DEPS_DIR) 292 | @echo Adding dependency for file: $$(notdir $$<) 293 | @echo -n "$$(DBG_BUILD_DIR)/$$(notdir $$(<:.$1=.o)) " > $$@ 294 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c $$< -MM \ 295 | -MT $$(REL_BUILD_DIR)/$$(notdir $$(<:.$1=.o)) >> $$@ 296 | endef 297 | $(foreach EXT,$(ASSEMBLY_EXTS),$(eval $(call assembly_targets,$(EXT)))) 298 | 299 | $(DEPS_DIR) $(DBG_BUILD_DIR) $(REL_BUILD_DIR):; @mkdir $@ 300 | 301 | .PHONY: flash_debug 302 | flash_debug: default 303 | $(call flash,$(DBG_BUILD_DIR)/$(PROJECT_NAME).hex) 304 | 305 | .PHONY: flash_release 306 | flash_release: release 307 | $(call flash,$(REL_BUILD_DIR)/$(PROJECT_NAME).hex) 308 | 309 | .PHONY: gdb_cmd_file 310 | gdb_cmd_file: default 311 | @echo "target remote localhost:$(GDB_PORT)" > $(GDB_CMD_PATH) 312 | @echo "mon speed 10000" >> $(GDB_CMD_PATH) 313 | @echo "mon flash download=1" >> $(GDB_CMD_PATH) 314 | @echo "load $(DBG_BUILD_DIR)/$(PROJECT_NAME).out" >> $(GDB_CMD_PATH) 315 | @echo "break main" >> $(GDB_CMD_PATH) 316 | @echo "mon reset 0" >> $(GDB_CMD_PATH) 317 | @echo "c" >> $(GDB_CMD_PATH) 318 | 319 | .PHONY: gdb_mon_cmd_file 320 | gdb_mon_cmd_file: gdb_cmd_file 321 | @echo "mon exec SetMonModeDebug=1" >> $(GDB_CMD_PATH) 322 | @echo "mon exec SetMonModeVTableAddr=$(JLINK_MON_DEBUG_APP_FLASH_LOCATION)" >> $(GDB_CMD_PATH) 323 | 324 | .PHONY: gdb_cli 325 | gdb_cli: 326 | @$(TERMINAL) '$(GDBSERVER)' $(GDB_SERVER_SN) -device nrf52832_XXAA \ 327 | -if swd -port $(GDB_PORT) $(TERMINAL_END) 328 | @$(TERMINAL) '$(GDB)' $(DBG_BUILD_DIR)/$(PROJECT_NAME).out -x $(GDB_CMD_PATH) $(TERMINAL_END) 329 | 330 | .PHONY: rtt 331 | rtt: 332 | @$(TERMINAL) '$(RTT_CLIENT)' $(TERMINAL_END) 333 | 334 | .PHONY: gdb 335 | gdb: gdb_cmd_file gdb_cli 336 | 337 | .PHONY: gdb_mon 338 | gdb_mon: gdb_mon_cmd_file gdb_cli 339 | 340 | .PHONY: gdb_rtt 341 | gdb_rtt: gdb rtt 342 | 343 | .PHONY: gdb_mon_rtt 344 | gdb_mon_rtt: gdb_mon rtt 345 | 346 | .PHONY: clean 347 | clean: 348 | @rm -rf $(DBG_BUILD_DIR) 349 | @rm -rf $(REL_BUILD_DIR) 350 | @rm -rf $(DEPS_DIR) 351 | 352 | .PHONY: help 353 | help: 354 | @echo "The following targets are available:" 355 | @echo " (default) - Compile with debug flags" 356 | @echo " release - Compile with release flags" 357 | @echo " all - Compile debug and release targets" 358 | @echo " clean - Remove object and dependency directories" 359 | @echo " gdb [SN=1234] - Perform debug compile and then launch gdb" 360 | @echo " gdb_rtt [SN=1234] - Call gdb target and then open RTT Client" 361 | ifneq "$(JLINK_MON_DEBUG_DIR)" "" 362 | @echo " gdb_mon [SN=1234] - Enable Monitor Mode Debugging" 363 | @echo " gdb_mon_rtt [SN=1234] - Enable Mon Debugging and open RTT Client" 364 | endif 365 | @echo " flash_debug [SN=1234] - Flash the debug build" 366 | @echo " flash_release [SN=1234]- Flash the release build" 367 | 368 | # This is a special target that tells make to delete a file if an error occurs 369 | # while the file is being generated. 370 | .DELETE_ON_ERROR: 371 | -------------------------------------------------------------------------------- /src/examples/rx/pca10040/blank/armgcc/poly_rx_gcc_nrf52.ld: -------------------------------------------------------------------------------- 1 | /* Linker script to configure memory regions. */ 2 | 3 | SEARCH_DIR(.) 4 | GROUP(-lgcc -lc -lnosys) 5 | 6 | MEMORY 7 | { 8 | FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 9 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 10 | } 11 | 12 | SECTIONS 13 | { 14 | .fs_data : 15 | { 16 | PROVIDE(__start_fs_data = .); 17 | KEEP(*(.fs_data)) 18 | PROVIDE(__stop_fs_data = .); 19 | } > RAM 20 | } INSERT AFTER .data; 21 | 22 | SECTIONS 23 | { 24 | .pwr_mgmt_data : 25 | { 26 | PROVIDE(__start_pwr_mgmt_data = .); 27 | KEEP(*(SORT(.pwr_mgmt_data*))) 28 | PROVIDE(__stop_pwr_mgmt_data = .); 29 | } > FLASH 30 | } INSERT AFTER .text 31 | 32 | INCLUDE "nrf5x_common.ld" 33 | -------------------------------------------------------------------------------- /src/examples/rx/pca10040/blank/config/sdk_config.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef SDK_CONFIG_H 4 | #define SDK_CONFIG_H 5 | // <<< Use Configuration Wizard in Context Menu >>>\n 6 | #ifdef USE_APP_CONFIG 7 | #include "app_config.h" 8 | #endif 9 | // nRF_Drivers 10 | 11 | // TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver 12 | //========================================================== 13 | #ifndef TIMER_ENABLED 14 | #define TIMER_ENABLED 1 15 | #endif 16 | #if TIMER_ENABLED 17 | // TIMER_DEFAULT_CONFIG_FREQUENCY - Timer frequency if in Timer mode 18 | 19 | // <0=> 16 MHz 20 | // <1=> 8 MHz 21 | // <2=> 4 MHz 22 | // <3=> 2 MHz 23 | // <4=> 1 MHz 24 | // <5=> 500 kHz 25 | // <6=> 250 kHz 26 | // <7=> 125 kHz 27 | // <8=> 62.5 kHz 28 | // <9=> 31.25 kHz 29 | 30 | #ifndef TIMER_DEFAULT_CONFIG_FREQUENCY 31 | #define TIMER_DEFAULT_CONFIG_FREQUENCY 0 32 | #endif 33 | 34 | // TIMER_DEFAULT_CONFIG_MODE - Timer mode or operation 35 | 36 | // <0=> Timer 37 | // <1=> Counter 38 | 39 | #ifndef TIMER_DEFAULT_CONFIG_MODE 40 | #define TIMER_DEFAULT_CONFIG_MODE 0 41 | #endif 42 | 43 | // TIMER_DEFAULT_CONFIG_BIT_WIDTH - Timer counter bit width 44 | 45 | // <0=> 16 bit 46 | // <1=> 8 bit 47 | // <2=> 24 bit 48 | // <3=> 32 bit 49 | 50 | #ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH 51 | #define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0 52 | #endif 53 | 54 | // TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority 55 | 56 | 57 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 58 | // <0=> 0 (highest) 59 | // <1=> 1 60 | // <2=> 2 61 | // <3=> 3 62 | // <4=> 4 63 | // <5=> 5 64 | // <6=> 6 65 | // <7=> 7 66 | 67 | #ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 68 | #define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 69 | #endif 70 | 71 | // TIMER0_ENABLED - Enable TIMER0 instance 72 | 73 | 74 | #ifndef TIMER0_ENABLED 75 | #define TIMER0_ENABLED 1 76 | #endif 77 | 78 | // TIMER1_ENABLED - Enable TIMER1 instance 79 | 80 | 81 | #ifndef TIMER1_ENABLED 82 | #define TIMER1_ENABLED 1 83 | #endif 84 | 85 | // TIMER2_ENABLED - Enable TIMER2 instance 86 | 87 | 88 | #ifndef TIMER2_ENABLED 89 | #define TIMER2_ENABLED 1 90 | #endif 91 | 92 | // TIMER3_ENABLED - Enable TIMER3 instance 93 | 94 | 95 | #ifndef TIMER3_ENABLED 96 | #define TIMER3_ENABLED 0 97 | #endif 98 | 99 | // TIMER4_ENABLED - Enable TIMER4 instance 100 | 101 | 102 | #ifndef TIMER4_ENABLED 103 | #define TIMER4_ENABLED 0 104 | #endif 105 | 106 | // TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. 107 | //========================================================== 108 | #ifndef TIMER_CONFIG_LOG_ENABLED 109 | #define TIMER_CONFIG_LOG_ENABLED 0 110 | #endif 111 | #if TIMER_CONFIG_LOG_ENABLED 112 | // TIMER_CONFIG_LOG_LEVEL - Default Severity level 113 | 114 | // <0=> Off 115 | // <1=> Error 116 | // <2=> Warning 117 | // <3=> Info 118 | // <4=> Debug 119 | 120 | #ifndef TIMER_CONFIG_LOG_LEVEL 121 | #define TIMER_CONFIG_LOG_LEVEL 3 122 | #endif 123 | 124 | // TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. 125 | 126 | // <0=> Default 127 | // <1=> Black 128 | // <2=> Red 129 | // <3=> Green 130 | // <4=> Yellow 131 | // <5=> Blue 132 | // <6=> Magenta 133 | // <7=> Cyan 134 | // <8=> White 135 | 136 | #ifndef TIMER_CONFIG_INFO_COLOR 137 | #define TIMER_CONFIG_INFO_COLOR 0 138 | #endif 139 | 140 | // TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 141 | 142 | // <0=> Default 143 | // <1=> Black 144 | // <2=> Red 145 | // <3=> Green 146 | // <4=> Yellow 147 | // <5=> Blue 148 | // <6=> Magenta 149 | // <7=> Cyan 150 | // <8=> White 151 | 152 | #ifndef TIMER_CONFIG_DEBUG_COLOR 153 | #define TIMER_CONFIG_DEBUG_COLOR 0 154 | #endif 155 | 156 | #endif //TIMER_CONFIG_LOG_ENABLED 157 | // 158 | 159 | #endif //TIMER_ENABLED 160 | // 161 | 162 | // PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver 163 | //========================================================== 164 | #ifndef PWM_ENABLED 165 | #define PWM_ENABLED 1 166 | #endif 167 | #if PWM_ENABLED 168 | // PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin <0-31> 169 | 170 | 171 | #ifndef PWM_DEFAULT_CONFIG_OUT0_PIN 172 | #define PWM_DEFAULT_CONFIG_OUT0_PIN 31 173 | #endif 174 | 175 | // PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin <0-31> 176 | 177 | 178 | #ifndef PWM_DEFAULT_CONFIG_OUT1_PIN 179 | #define PWM_DEFAULT_CONFIG_OUT1_PIN 31 180 | #endif 181 | 182 | // PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin <0-31> 183 | 184 | 185 | #ifndef PWM_DEFAULT_CONFIG_OUT2_PIN 186 | #define PWM_DEFAULT_CONFIG_OUT2_PIN 31 187 | #endif 188 | 189 | // PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin <0-31> 190 | 191 | 192 | #ifndef PWM_DEFAULT_CONFIG_OUT3_PIN 193 | #define PWM_DEFAULT_CONFIG_OUT3_PIN 31 194 | #endif 195 | 196 | // PWM_DEFAULT_CONFIG_BASE_CLOCK - Base clock 197 | 198 | // <0=> 16 MHz 199 | // <1=> 8 MHz 200 | // <2=> 4 MHz 201 | // <3=> 2 MHz 202 | // <4=> 1 MHz 203 | // <5=> 500 kHz 204 | // <6=> 250 kHz 205 | // <7=> 125 MHz 206 | 207 | #ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK 208 | #define PWM_DEFAULT_CONFIG_BASE_CLOCK 4 209 | #endif 210 | 211 | // PWM_DEFAULT_CONFIG_COUNT_MODE - Count mode 212 | 213 | // <0=> Up 214 | // <1=> Up and Down 215 | 216 | #ifndef PWM_DEFAULT_CONFIG_COUNT_MODE 217 | #define PWM_DEFAULT_CONFIG_COUNT_MODE 0 218 | #endif 219 | 220 | // PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 221 | #ifndef PWM_DEFAULT_CONFIG_TOP_VALUE 222 | #define PWM_DEFAULT_CONFIG_TOP_VALUE 20000 223 | #endif 224 | 225 | // PWM_DEFAULT_CONFIG_LOAD_MODE - Load mode 226 | 227 | // <0=> Common 228 | // <1=> Grouped 229 | // <2=> Individual 230 | // <3=> Waveform 231 | 232 | #ifndef PWM_DEFAULT_CONFIG_LOAD_MODE 233 | #define PWM_DEFAULT_CONFIG_LOAD_MODE 0 234 | #endif 235 | 236 | // PWM_DEFAULT_CONFIG_STEP_MODE - Step mode 237 | 238 | // <0=> Auto 239 | // <1=> Triggered 240 | 241 | #ifndef PWM_DEFAULT_CONFIG_STEP_MODE 242 | #define PWM_DEFAULT_CONFIG_STEP_MODE 0 243 | #endif 244 | 245 | // PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority 246 | 247 | 248 | // Priorities 0,1,4,5 (nRF52) are reserved for SoftDevice 249 | // <0=> 0 (highest) 250 | // <1=> 1 251 | // <2=> 2 252 | // <3=> 3 253 | // <4=> 4 254 | // <5=> 5 255 | // <6=> 6 256 | // <7=> 7 257 | 258 | #ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY 259 | #define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 7 260 | #endif 261 | 262 | // PWM0_ENABLED - Enable PWM0 instance 263 | 264 | 265 | #ifndef PWM0_ENABLED 266 | #define PWM0_ENABLED 1 267 | #endif 268 | 269 | // PWM1_ENABLED - Enable PWM1 instance 270 | 271 | 272 | #ifndef PWM1_ENABLED 273 | #define PWM1_ENABLED 1 274 | #endif 275 | 276 | // PWM2_ENABLED - Enable PWM2 instance 277 | 278 | 279 | #ifndef PWM2_ENABLED 280 | #define PWM2_ENABLED 0 281 | #endif 282 | 283 | // PWM_CONFIG_LOG_ENABLED - Enables logging in the module. 284 | //========================================================== 285 | #ifndef PWM_CONFIG_LOG_ENABLED 286 | #define PWM_CONFIG_LOG_ENABLED 0 287 | #endif 288 | #if PWM_CONFIG_LOG_ENABLED 289 | // PWM_CONFIG_LOG_LEVEL - Default Severity level 290 | 291 | // <0=> Off 292 | // <1=> Error 293 | // <2=> Warning 294 | // <3=> Info 295 | // <4=> Debug 296 | 297 | #ifndef PWM_CONFIG_LOG_LEVEL 298 | #define PWM_CONFIG_LOG_LEVEL 3 299 | #endif 300 | 301 | // PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. 302 | 303 | // <0=> Default 304 | // <1=> Black 305 | // <2=> Red 306 | // <3=> Green 307 | // <4=> Yellow 308 | // <5=> Blue 309 | // <6=> Magenta 310 | // <7=> Cyan 311 | // <8=> White 312 | 313 | #ifndef PWM_CONFIG_INFO_COLOR 314 | #define PWM_CONFIG_INFO_COLOR 0 315 | #endif 316 | 317 | // PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 318 | 319 | // <0=> Default 320 | // <1=> Black 321 | // <2=> Red 322 | // <3=> Green 323 | // <4=> Yellow 324 | // <5=> Blue 325 | // <6=> Magenta 326 | // <7=> Cyan 327 | // <8=> White 328 | 329 | #ifndef PWM_CONFIG_DEBUG_COLOR 330 | #define PWM_CONFIG_DEBUG_COLOR 0 331 | #endif 332 | 333 | #endif //PWM_CONFIG_LOG_ENABLED 334 | // 335 | 336 | // PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround for PWM. 337 | 338 | // The workaround uses interrupts to wake up the CPU and ensure 339 | // it is active when PWM is about to start a DMA transfer. For 340 | // initial transfer, done when a playback is started via PPI, 341 | // a specific EGU instance is used to generate the interrupt. 342 | // During the playback, the PWM interrupt triggered on SEQEND 343 | // event of a preceding sequence is used to protect the transfer 344 | // done for the next sequence to be played. 345 | //========================================================== 346 | #ifndef PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 347 | #define PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 348 | #endif 349 | #if PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 350 | // PWM_NRF52_ANOMALY_109_EGU_INSTANCE - EGU instance used by the nRF52 Anomaly 109 workaround for PWM. 351 | 352 | // <0=> EGU0 353 | // <1=> EGU1 354 | // <2=> EGU2 355 | // <3=> EGU3 356 | // <4=> EGU4 357 | // <5=> EGU5 358 | 359 | #ifndef PWM_NRF52_ANOMALY_109_EGU_INSTANCE 360 | #define PWM_NRF52_ANOMALY_109_EGU_INSTANCE 5 361 | #endif 362 | 363 | #endif //PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 364 | // 365 | 366 | #endif //PWM_ENABLED 367 | // 368 | 369 | //========================================================== 370 | // PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common - Peripheral drivers common module 371 | //========================================================== 372 | #ifndef PERIPHERAL_RESOURCE_SHARING_ENABLED 373 | #define PERIPHERAL_RESOURCE_SHARING_ENABLED 0 374 | #endif 375 | #if PERIPHERAL_RESOURCE_SHARING_ENABLED 376 | // COMMON_CONFIG_LOG_ENABLED - Enables logging in the module. 377 | //========================================================== 378 | #ifndef COMMON_CONFIG_LOG_ENABLED 379 | #define COMMON_CONFIG_LOG_ENABLED 0 380 | #endif 381 | #if COMMON_CONFIG_LOG_ENABLED 382 | // COMMON_CONFIG_LOG_LEVEL - Default Severity level 383 | 384 | // <0=> Off 385 | // <1=> Error 386 | // <2=> Warning 387 | // <3=> Info 388 | // <4=> Debug 389 | 390 | #ifndef COMMON_CONFIG_LOG_LEVEL 391 | #define COMMON_CONFIG_LOG_LEVEL 3 392 | #endif 393 | 394 | // COMMON_CONFIG_INFO_COLOR - ANSI escape code prefix. 395 | 396 | // <0=> Default 397 | // <1=> Black 398 | // <2=> Red 399 | // <3=> Green 400 | // <4=> Yellow 401 | // <5=> Blue 402 | // <6=> Magenta 403 | // <7=> Cyan 404 | // <8=> White 405 | 406 | #ifndef COMMON_CONFIG_INFO_COLOR 407 | #define COMMON_CONFIG_INFO_COLOR 0 408 | #endif 409 | 410 | // COMMON_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 411 | 412 | // <0=> Default 413 | // <1=> Black 414 | // <2=> Red 415 | // <3=> Green 416 | // <4=> Yellow 417 | // <5=> Blue 418 | // <6=> Magenta 419 | // <7=> Cyan 420 | // <8=> White 421 | 422 | #ifndef COMMON_CONFIG_DEBUG_COLOR 423 | #define COMMON_CONFIG_DEBUG_COLOR 0 424 | #endif 425 | 426 | #endif //COMMON_CONFIG_LOG_ENABLED 427 | // 428 | 429 | #endif //PERIPHERAL_RESOURCE_SHARING_ENABLED 430 | // 431 | 432 | // UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver 433 | //========================================================== 434 | #ifndef UART_ENABLED 435 | #define UART_ENABLED 0 436 | #endif 437 | #if UART_ENABLED 438 | // UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control 439 | 440 | // <0=> Disabled 441 | // <1=> Enabled 442 | 443 | #ifndef UART_DEFAULT_CONFIG_HWFC 444 | #define UART_DEFAULT_CONFIG_HWFC 0 445 | #endif 446 | 447 | // UART_DEFAULT_CONFIG_PARITY - Parity 448 | 449 | // <0=> Excluded 450 | // <14=> Included 451 | 452 | #ifndef UART_DEFAULT_CONFIG_PARITY 453 | #define UART_DEFAULT_CONFIG_PARITY 0 454 | #endif 455 | 456 | // UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate 457 | 458 | // <323584=> 1200 baud 459 | // <643072=> 2400 baud 460 | // <1290240=> 4800 baud 461 | // <2576384=> 9600 baud 462 | // <3862528=> 14400 baud 463 | // <5152768=> 19200 baud 464 | // <7716864=> 28800 baud 465 | // <10289152=> 38400 baud 466 | // <15400960=> 57600 baud 467 | // <20615168=> 76800 baud 468 | // <30801920=> 115200 baud 469 | // <61865984=> 230400 baud 470 | // <67108864=> 250000 baud 471 | // <121634816=> 460800 baud 472 | // <251658240=> 921600 baud 473 | // <268435456=> 57600 baud 474 | 475 | #ifndef UART_DEFAULT_CONFIG_BAUDRATE 476 | #define UART_DEFAULT_CONFIG_BAUDRATE 30801920 477 | #endif 478 | 479 | // UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority 480 | 481 | 482 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 483 | // <0=> 0 (highest) 484 | // <1=> 1 485 | // <2=> 2 486 | // <3=> 3 487 | // <4=> 4 488 | // <5=> 5 489 | // <6=> 6 490 | // <7=> 7 491 | 492 | #ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY 493 | #define UART_DEFAULT_CONFIG_IRQ_PRIORITY 7 494 | #endif 495 | 496 | // UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA 497 | 498 | 499 | #ifndef UART_EASY_DMA_SUPPORT 500 | #define UART_EASY_DMA_SUPPORT 1 501 | #endif 502 | 503 | // UART_LEGACY_SUPPORT - Driver supporting Legacy mode 504 | 505 | 506 | #ifndef UART_LEGACY_SUPPORT 507 | #define UART_LEGACY_SUPPORT 1 508 | #endif 509 | 510 | // UART0_ENABLED - Enable UART0 instance 511 | //========================================================== 512 | #ifndef UART0_ENABLED 513 | #define UART0_ENABLED 1 514 | #endif 515 | #if UART0_ENABLED 516 | // UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA 517 | 518 | 519 | #ifndef UART0_CONFIG_USE_EASY_DMA 520 | #define UART0_CONFIG_USE_EASY_DMA 1 521 | #endif 522 | 523 | #endif //UART0_ENABLED 524 | // 525 | 526 | // UART_CONFIG_LOG_ENABLED - Enables logging in the module. 527 | //========================================================== 528 | #ifndef UART_CONFIG_LOG_ENABLED 529 | #define UART_CONFIG_LOG_ENABLED 0 530 | #endif 531 | #if UART_CONFIG_LOG_ENABLED 532 | // UART_CONFIG_LOG_LEVEL - Default Severity level 533 | 534 | // <0=> Off 535 | // <1=> Error 536 | // <2=> Warning 537 | // <3=> Info 538 | // <4=> Debug 539 | 540 | #ifndef UART_CONFIG_LOG_LEVEL 541 | #define UART_CONFIG_LOG_LEVEL 3 542 | #endif 543 | 544 | // UART_CONFIG_INFO_COLOR - ANSI escape code prefix. 545 | 546 | // <0=> Default 547 | // <1=> Black 548 | // <2=> Red 549 | // <3=> Green 550 | // <4=> Yellow 551 | // <5=> Blue 552 | // <6=> Magenta 553 | // <7=> Cyan 554 | // <8=> White 555 | 556 | #ifndef UART_CONFIG_INFO_COLOR 557 | #define UART_CONFIG_INFO_COLOR 0 558 | #endif 559 | 560 | // UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 561 | 562 | // <0=> Default 563 | // <1=> Black 564 | // <2=> Red 565 | // <3=> Green 566 | // <4=> Yellow 567 | // <5=> Blue 568 | // <6=> Magenta 569 | // <7=> Cyan 570 | // <8=> White 571 | 572 | #ifndef UART_CONFIG_DEBUG_COLOR 573 | #define UART_CONFIG_DEBUG_COLOR 0 574 | #endif 575 | 576 | #endif //UART_CONFIG_LOG_ENABLED 577 | // 578 | 579 | #endif //UART_ENABLED 580 | // 581 | 582 | // 583 | //========================================================== 584 | 585 | // nRF_Libraries 586 | 587 | //========================================================== 588 | // NRF_STRERROR_ENABLED - nrf_strerror - Library for converting error code to string. 589 | 590 | 591 | #ifndef NRF_STRERROR_ENABLED 592 | #define NRF_STRERROR_ENABLED 1 593 | #endif 594 | 595 | // 596 | //========================================================== 597 | 598 | // nRF_Log 599 | 600 | //========================================================== 601 | // NRF_LOG_ENABLED - nrf_log - Logging 602 | //========================================================== 603 | #ifndef NRF_LOG_ENABLED 604 | #define NRF_LOG_ENABLED 1 605 | #endif 606 | #if NRF_LOG_ENABLED 607 | // NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string 608 | //========================================================== 609 | #ifndef NRF_LOG_USES_COLORS 610 | #define NRF_LOG_USES_COLORS 0 611 | #endif 612 | #if NRF_LOG_USES_COLORS 613 | // NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix. 614 | 615 | // <0=> Default 616 | // <1=> Black 617 | // <2=> Red 618 | // <3=> Green 619 | // <4=> Yellow 620 | // <5=> Blue 621 | // <6=> Magenta 622 | // <7=> Cyan 623 | // <8=> White 624 | 625 | #ifndef NRF_LOG_COLOR_DEFAULT 626 | #define NRF_LOG_COLOR_DEFAULT 0 627 | #endif 628 | 629 | // NRF_LOG_ERROR_COLOR - ANSI escape code prefix. 630 | 631 | // <0=> Default 632 | // <1=> Black 633 | // <2=> Red 634 | // <3=> Green 635 | // <4=> Yellow 636 | // <5=> Blue 637 | // <6=> Magenta 638 | // <7=> Cyan 639 | // <8=> White 640 | 641 | #ifndef NRF_LOG_ERROR_COLOR 642 | #define NRF_LOG_ERROR_COLOR 0 643 | #endif 644 | 645 | // NRF_LOG_WARNING_COLOR - ANSI escape code prefix. 646 | 647 | // <0=> Default 648 | // <1=> Black 649 | // <2=> Red 650 | // <3=> Green 651 | // <4=> Yellow 652 | // <5=> Blue 653 | // <6=> Magenta 654 | // <7=> Cyan 655 | // <8=> White 656 | 657 | #ifndef NRF_LOG_WARNING_COLOR 658 | #define NRF_LOG_WARNING_COLOR 0 659 | #endif 660 | 661 | #endif //NRF_LOG_USES_COLORS 662 | // 663 | 664 | // NRF_LOG_DEFAULT_LEVEL - Default Severity level 665 | 666 | // <0=> Off 667 | // <1=> Error 668 | // <2=> Warning 669 | // <3=> Info 670 | // <4=> Debug 671 | 672 | #ifndef NRF_LOG_DEFAULT_LEVEL 673 | #define NRF_LOG_DEFAULT_LEVEL 4 674 | #endif 675 | 676 | // NRF_LOG_DEFERRED - Enable deffered logger. 677 | 678 | // Log data is buffered and can be processed in idle. 679 | //========================================================== 680 | #ifndef NRF_LOG_DEFERRED 681 | #define NRF_LOG_DEFERRED 1 682 | #endif 683 | #if NRF_LOG_DEFERRED 684 | // NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words. 685 | // Must be power of 2 686 | 687 | #ifndef NRF_LOG_DEFERRED_BUFSIZE 688 | #define NRF_LOG_DEFERRED_BUFSIZE 256 689 | #endif 690 | 691 | #endif //NRF_LOG_DEFERRED 692 | // 693 | 694 | // NRF_LOG_USES_TIMESTAMP - Enable timestamping 695 | 696 | 697 | // Function for getting the timestamp is provided by the user 698 | 699 | #ifndef NRF_LOG_USES_TIMESTAMP 700 | #define NRF_LOG_USES_TIMESTAMP 0 701 | #endif 702 | 703 | #endif //NRF_LOG_ENABLED 704 | // 705 | 706 | // nrf_log_backend - Logging sink 707 | 708 | //========================================================== 709 | // NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string 710 | // Logger backend RAM usage is determined by this value. 711 | 712 | #ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH 713 | #define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256 714 | #endif 715 | 716 | // NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp 717 | // If higher resolution timestamp source is used it might be needed to increase that 718 | 719 | #ifndef NRF_LOG_TIMESTAMP_DIGITS 720 | #define NRF_LOG_TIMESTAMP_DIGITS 8 721 | #endif 722 | 723 | // NRF_LOG_BACKEND_SERIAL_USES_UART - If enabled data is printed over UART 724 | //========================================================== 725 | #ifndef NRF_LOG_BACKEND_SERIAL_USES_UART 726 | #define NRF_LOG_BACKEND_SERIAL_USES_UART 0 727 | #endif 728 | #if NRF_LOG_BACKEND_SERIAL_USES_UART 729 | // NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE - Default Baudrate 730 | 731 | // <323584=> 1200 baud 732 | // <643072=> 2400 baud 733 | // <1290240=> 4800 baud 734 | // <2576384=> 9600 baud 735 | // <3862528=> 14400 baud 736 | // <5152768=> 19200 baud 737 | // <7716864=> 28800 baud 738 | // <10289152=> 38400 baud 739 | // <15400960=> 57600 baud 740 | // <20615168=> 76800 baud 741 | // <30801920=> 115200 baud 742 | // <61865984=> 230400 baud 743 | // <67108864=> 250000 baud 744 | // <121634816=> 460800 baud 745 | // <251658240=> 921600 baud 746 | // <268435456=> 57600 baud 747 | 748 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 749 | #define NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 30801920 750 | #endif 751 | 752 | // NRF_LOG_BACKEND_SERIAL_UART_TX_PIN - UART TX pin 753 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 754 | #define NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 6 755 | #endif 756 | 757 | // NRF_LOG_BACKEND_SERIAL_UART_RX_PIN - UART RX pin 758 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 759 | #define NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 8 760 | #endif 761 | 762 | // NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN - UART RTS pin 763 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 764 | #define NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 5 765 | #endif 766 | 767 | // NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN - UART CTS pin 768 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 769 | #define NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 7 770 | #endif 771 | 772 | // NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL - Hardware Flow Control 773 | 774 | // <0=> Disabled 775 | // <1=> Enabled 776 | 777 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 778 | #define NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 0 779 | #endif 780 | 781 | // NRF_LOG_BACKEND_UART_INSTANCE - UART instance used 782 | 783 | // <0=> 0 784 | 785 | #ifndef NRF_LOG_BACKEND_UART_INSTANCE 786 | #define NRF_LOG_BACKEND_UART_INSTANCE 0 787 | #endif 788 | 789 | #endif //NRF_LOG_BACKEND_SERIAL_USES_UART 790 | // 791 | 792 | // NRF_LOG_BACKEND_SERIAL_USES_RTT - If enabled data is printed using RTT 793 | //========================================================== 794 | #ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT 795 | #define NRF_LOG_BACKEND_SERIAL_USES_RTT 1 796 | #endif 797 | #if NRF_LOG_BACKEND_SERIAL_USES_RTT 798 | // NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE - RTT output buffer size. 799 | // Should be equal or bigger than \ref NRF_LOG_BACKEND_MAX_STRING_LENGTH. 800 | // This value is used in Segger RTT configuration to set the buffer size 801 | // if it is bigger than default RTT buffer size. 802 | 803 | #ifndef NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 804 | #define NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 512 805 | #endif 806 | 807 | #endif //NRF_LOG_BACKEND_SERIAL_USES_RTT 808 | // 809 | 810 | // 811 | //========================================================== 812 | 813 | // 814 | //========================================================== 815 | 816 | // nRF_Segger_RTT 817 | 818 | //========================================================== 819 | // segger_rtt - SEGGER RTT 820 | 821 | //========================================================== 822 | // SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. 823 | // Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 824 | // or this value is actually used. It depends on which one is bigger. 825 | 826 | #ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 827 | #define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 64 828 | #endif 829 | 830 | // SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer. 831 | #ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 832 | #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 833 | #endif 834 | 835 | // SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer. 836 | #ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 837 | #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 838 | #endif 839 | 840 | // SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer. 841 | #ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 842 | #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 843 | #endif 844 | 845 | // SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full. 846 | 847 | 848 | // The following modes are supported: 849 | // - SKIP - Do not block, output nothing. 850 | // - TRIM - Do not block, output as much as fits. 851 | // - BLOCK - Wait until there is space in the buffer. 852 | // <0=> SKIP 853 | // <1=> TRIM 854 | // <2=> BLOCK_IF_FIFO_FULL 855 | 856 | #ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE 857 | #define SEGGER_RTT_CONFIG_DEFAULT_MODE 0 858 | #endif 859 | 860 | // 861 | //========================================================== 862 | 863 | // 864 | //========================================================== 865 | 866 | // <<< end of configuration section >>> 867 | #endif //SDK_CONFIG_H 868 | 869 | -------------------------------------------------------------------------------- /src/examples/tx/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * The throttle is kept at neutral until its value exceeds 3 | * THROTTLE_SAFETY_MARGIN. This is meant to keep noise on the joystick ADC pin 4 | * from activating the throttle unexpectedly. 5 | * 6 | * There are typically two types of throttle joysticks on RC transmitters: 7 | * 1) Ones that automatically return to the center position on both X 8 | * and Y axis 9 | * 2) Ones that automatically return to the center position on the X 10 | * axis but can be left at an arbitrary position on the Y axis 11 | * 12 | * This module assumes that the throttle control is linked to the left 13 | * joystick's Y axis. There are three throttle control modes: 14 | * 1) THROTTLE_CTL_FWD_ONLY_NEUTRAL_0 - Throttle is neutral at joystick 15 | * position 0 and values match the joystick's position. 16 | * 2) THROTTLE_CTL_FWD_ONLY_NEUTRAL_50 - Throttle is neutral at joystick 17 | * position 50. Joystick values below 50 are considered 0. Values are 18 | * mapped from joystick range [50, 100] to [0, 100]. 19 | * 3) THROTTLE_CTL_FWD_BKWD_NEUTRAL_50 - The same as 20 | * THROTTLE_CTL_FWD_ONLY_NEUTRAL_0 except THROTTLE_SAFETY_MARGIN is 21 | * applied to values on both sides of the neutral point. 22 | * 23 | * BOUND_LED_PIN selects an LED to light after a receiver has ACK'd and the 24 | * transmitter begins transmitting data. 25 | * 26 | * INVERT_PITCH_BUTTON_PIN is used as a toggle to invert the pitch data (right 27 | * joystick's Y axis). INVERTED_PITCH_LED_PIN selects an LED to light when the 28 | * pitch is inverted. 29 | * 30 | * THROT_CTL_BUTTON_PIN is used as a cycle through the possible throttle_ctl_t 31 | * modes. THROT_CTL_CHANGED_LED_PIN selects an LED to light when the mode 32 | * has been changed from the default mode (i.e. a warning). 33 | * 34 | * BIND_RESET_BUTTON_PIN is used to reset the transmitter back to binding mode. 35 | */ 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include "nrf.h" 41 | #include "boards.h" 42 | #include "app_error.h" 43 | #include "nrf_delay.h" 44 | #include "app_util_platform.h" 45 | #include "nrf_gpio.h" 46 | #include "app_timer.h" 47 | #include "app_button.h" 48 | 49 | #define NRF_LOG_MODULE_NAME "APP" 50 | #include "nrf_log.h" 51 | #include "nrf_log_ctrl.h" 52 | 53 | #include "joystick.h" 54 | #include "rc_radio.h" 55 | #include "utility.h" 56 | 57 | 58 | #define RADIO_TIMER_INSTANCE (0UL) 59 | #define JOYSTICK_TIMER_INSTANCE (1UL) 60 | 61 | #define RADIO_UPDATE_RATE_HZ (100UL) 62 | #define JOYSTICK_UPDATE_RATE_HZ (50UL) 63 | 64 | #define THROTTLE_CTL_DEFAULT (THROTTLE_CTL_FWD_ONLY_NEUTRAL_50) 65 | #define THROTTLE_SAFETY_MARGIN (8UL) 66 | 67 | #define INVERTED_PITCH_LED_PIN (LED_1) 68 | #define THROT_CTL_CHANGED_LED_PIN (LED_3) 69 | #define BOUND_LED_PIN (LED_4) 70 | #define INVERT_PITCH_BUTTON_PIN (BUTTON_1) 71 | #define THROT_CTL_BUTTON_PIN (BUTTON_3) 72 | #define BIND_RESET_BUTTON_PIN (BUTTON_4) 73 | #define LEFT_X_JS_PIN (JOYSTICK_PIN_1) // P0.3 74 | #define LEFT_Y_JS_PIN (JOYSTICK_PIN_2) // P0.4 75 | #define RIGHT_X_JS_PIN (JOYSTICK_PIN_4) // P0.28 76 | #define RIGHT_Y_JS_PIN (JOYSTICK_PIN_5) // P0.29 77 | 78 | #define NEUTRAL_50_JOYSTICK_VALUE (50UL) 79 | 80 | 81 | typedef enum 82 | { 83 | THROTTLE_CTL_FWD_ONLY_NEUTRAL_0, 84 | THROTTLE_CTL_FWD_ONLY_NEUTRAL_50, 85 | THROTTLE_CTL_FWD_BKWD_NEUTRAL_50, 86 | THROTTLE_CTL_COUNT 87 | } throttle_ctl_t; 88 | 89 | 90 | static void m_button_handler(uint8_t pin_no, uint8_t button_action); 91 | 92 | static rc_radio_data_t m_radio_data; 93 | static bool m_invert_y_axis=false; 94 | static throttle_ctl_t m_throttle_ctl=THROTTLE_CTL_DEFAULT; 95 | static app_button_cfg_t m_buttons[] = 96 | { 97 | { 98 | INVERT_PITCH_BUTTON_PIN, 99 | BUTTONS_ACTIVE_STATE, 100 | BUTTON_PULL, 101 | m_button_handler 102 | }, 103 | { 104 | THROT_CTL_BUTTON_PIN, 105 | BUTTONS_ACTIVE_STATE, 106 | BUTTON_PULL, 107 | m_button_handler 108 | }, 109 | { 110 | BIND_RESET_BUTTON_PIN, 111 | BUTTONS_ACTIVE_STATE, 112 | BUTTON_PULL, 113 | m_button_handler 114 | } 115 | }; 116 | 117 | 118 | static void m_joystick_handler(uint8_t l_x, 119 | uint8_t l_y, 120 | uint8_t r_x, 121 | uint8_t r_y) 122 | { 123 | NRF_LOG_INFO("-----Raw joystick data-----\r\n"); 124 | NRF_LOG_INFO("Left X:\t%d\r\n", l_x); 125 | NRF_LOG_INFO("Left Y:\t%d\r\n", l_y); 126 | NRF_LOG_INFO("Right X:\t%d\r\n", r_x); 127 | NRF_LOG_INFO("Right Y:\t%d\r\n", r_y); 128 | 129 | m_radio_data.yaw = l_x; 130 | m_radio_data.roll = r_x; 131 | 132 | if (!m_invert_y_axis) 133 | { 134 | m_radio_data.pitch = r_y; 135 | } 136 | else 137 | { 138 | m_radio_data.pitch = (JOYSTICK_MAX_VALUE - r_y); 139 | } 140 | 141 | switch (m_throttle_ctl) 142 | { 143 | case THROTTLE_CTL_FWD_ONLY_NEUTRAL_0: 144 | if (THROTTLE_SAFETY_MARGIN <= l_y) 145 | { 146 | m_radio_data.throttle = l_y; 147 | } 148 | else 149 | { 150 | m_radio_data.throttle = 0; 151 | } 152 | break; 153 | case THROTTLE_CTL_FWD_ONLY_NEUTRAL_50: 154 | if ((NEUTRAL_50_JOYSTICK_VALUE + THROTTLE_SAFETY_MARGIN) <= l_y) 155 | { 156 | // Convert from [50, 100] to [0, 100]. 157 | m_radio_data.throttle = pam(l_y, 158 | NEUTRAL_50_JOYSTICK_VALUE, 159 | JOYSTICK_MAX_VALUE); 160 | } 161 | else 162 | { 163 | m_radio_data.throttle = 0; 164 | } 165 | break; 166 | case THROTTLE_CTL_FWD_BKWD_NEUTRAL_50: 167 | if (((NEUTRAL_50_JOYSTICK_VALUE + THROTTLE_SAFETY_MARGIN) > l_y) && 168 | ((NEUTRAL_50_JOYSTICK_VALUE - THROTTLE_SAFETY_MARGIN) < l_y)) 169 | { 170 | m_radio_data.throttle = NEUTRAL_50_JOYSTICK_VALUE; 171 | } 172 | else 173 | { 174 | m_radio_data.throttle = l_y; 175 | } 176 | break; 177 | default: 178 | break; 179 | } 180 | 181 | NRF_LOG_INFO("-----Channel data-----\r\n"); 182 | NRF_LOG_INFO("Yaw:\t\t%d\r\n", m_radio_data.yaw); 183 | NRF_LOG_INFO("Throttle:\t%d\r\n", m_radio_data.throttle); 184 | NRF_LOG_INFO("Roll:\t%d\r\n", m_radio_data.roll); 185 | NRF_LOG_INFO("Pitch:\t%d\r\n", m_radio_data.pitch); 186 | 187 | APP_ERROR_CHECK(rc_radio_data_set(&m_radio_data)); 188 | } 189 | 190 | 191 | static void m_rc_radio_handler(rc_radio_event_t event, 192 | const void * const p_context) 193 | { 194 | switch (event) 195 | { 196 | case RC_RADIO_EVENT_BINDING: 197 | nrf_gpio_pin_set(BOUND_LED_PIN); 198 | NRF_LOG_INFO("Binding...\r\n"); 199 | break; 200 | case RC_RADIO_EVENT_BOUND: 201 | { 202 | rc_radio_bind_info_t * p_bind_info; 203 | p_bind_info = (rc_radio_bind_info_t*) p_context; 204 | 205 | nrf_gpio_pin_clear(BOUND_LED_PIN); 206 | NRF_LOG_INFO("Bound. (%d, %d)\r\n", 207 | p_bind_info->transmitter_channel, 208 | p_bind_info->transmit_rate_hz); 209 | } 210 | break; 211 | case RC_RADIO_EVENT_DATA_SENT: 212 | NRF_LOG_INFO("Data sent.\r\n"); 213 | break; 214 | default: 215 | break; 216 | }; 217 | } 218 | 219 | 220 | static void m_button_handler(uint8_t pin_no, uint8_t button_action) 221 | { 222 | NRF_LOG_INFO("Button %d action %d.\r\n", pin_no, button_action); 223 | 224 | if (button_action) 225 | { 226 | switch (pin_no) 227 | { 228 | case INVERT_PITCH_BUTTON_PIN: 229 | m_invert_y_axis = !m_invert_y_axis; 230 | 231 | if (m_invert_y_axis) 232 | { 233 | nrf_gpio_pin_clear(INVERTED_PITCH_LED_PIN); 234 | } 235 | else 236 | { 237 | nrf_gpio_pin_set(INVERTED_PITCH_LED_PIN); 238 | } 239 | break; 240 | case THROT_CTL_BUTTON_PIN: 241 | m_throttle_ctl = ((m_throttle_ctl + 1) % THROTTLE_CTL_COUNT); 242 | if (THROTTLE_CTL_DEFAULT != m_throttle_ctl) 243 | { 244 | nrf_gpio_pin_clear(THROT_CTL_CHANGED_LED_PIN); 245 | } 246 | else 247 | { 248 | nrf_gpio_pin_set(THROT_CTL_CHANGED_LED_PIN); 249 | } 250 | NRF_LOG_INFO("Throttle ctl mode set to: %d\r\n", m_throttle_ctl); 251 | break; 252 | case BIND_RESET_BUTTON_PIN: 253 | rc_radio_disable(); 254 | rc_radio_enable(); 255 | break; 256 | default: 257 | break; 258 | } 259 | } 260 | } 261 | 262 | 263 | static void m_gpio_init(void) 264 | { 265 | nrf_gpio_cfg_output(BOUND_LED_PIN); 266 | nrf_gpio_cfg_output(INVERTED_PITCH_LED_PIN); 267 | nrf_gpio_cfg_output(THROT_CTL_CHANGED_LED_PIN); 268 | nrf_gpio_pin_set(BOUND_LED_PIN); 269 | nrf_gpio_pin_set(INVERTED_PITCH_LED_PIN); 270 | nrf_gpio_pin_set(THROT_CTL_CHANGED_LED_PIN); 271 | } 272 | 273 | 274 | static void lfclk_start(void) 275 | { 276 | NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); 277 | NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; 278 | NRF_CLOCK->TASKS_LFCLKSTART = 1; 279 | while (0 == NRF_CLOCK->EVENTS_LFCLKSTARTED) 280 | { 281 | } 282 | NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; 283 | } 284 | 285 | 286 | int main(void) 287 | { 288 | uint32_t err_code; 289 | 290 | NRF_POWER->DCDCEN = true; 291 | 292 | err_code = NRF_LOG_INIT(NULL); 293 | APP_ERROR_CHECK(err_code); 294 | 295 | m_gpio_init(); 296 | 297 | // The app_timer module requires an LFCLK source. 298 | lfclk_start(); 299 | err_code = app_timer_init(); 300 | APP_ERROR_CHECK(err_code); 301 | 302 | err_code = app_button_init(m_buttons, 303 | (sizeof(m_buttons) / sizeof(m_buttons[0])), 304 | APP_TIMER_TICKS(50)); 305 | APP_ERROR_CHECK(err_code); 306 | 307 | err_code = app_button_enable(); 308 | APP_ERROR_CHECK(err_code); 309 | 310 | memset((uint8_t*)&m_radio_data, 0, sizeof(m_radio_data)); 311 | 312 | err_code = rc_radio_transmitter_init(RADIO_TIMER_INSTANCE, 313 | RADIO_UPDATE_RATE_HZ, 314 | RC_RADIO_TRANSMITTER_CHANNEL_A, 315 | m_rc_radio_handler); 316 | APP_ERROR_CHECK(err_code); 317 | 318 | err_code = rc_radio_enable(); 319 | APP_ERROR_CHECK(err_code); 320 | 321 | err_code = joystick_init(JOYSTICK_TIMER_INSTANCE, 322 | JOYSTICK_UPDATE_RATE_HZ, 323 | m_joystick_handler, 324 | LEFT_X_JS_PIN, 325 | LEFT_Y_JS_PIN, 326 | RIGHT_X_JS_PIN, 327 | RIGHT_Y_JS_PIN); 328 | APP_ERROR_CHECK(err_code); 329 | 330 | while (true) 331 | { 332 | if (false == NRF_LOG_PROCESS()) 333 | { 334 | __WFE(); 335 | } 336 | } 337 | } 338 | -------------------------------------------------------------------------------- /src/examples/tx/pca10040/blank/armgcc/Makefile: -------------------------------------------------------------------------------- 1 | # The PROJECT_NAME can be changed arbitrarily (it does not depend on anything). 2 | PROJECT_NAME := poly_tx 3 | 4 | SHAREDFLAGS := -DINVERT_L_X_AXIS=1 \ 5 | -DINVERT_R_Y_AXIS=1 6 | 7 | # The LINKER_SCRIPT is usually in the same directory as the Makefile. 8 | LINKER_SCRIPT := poly_tx_gcc_nrf52.ld 9 | 10 | BOARD := PCA10040 11 | 12 | DBG_BUILD_DIR := ./_debug 13 | REL_BUILD_DIR := ./_release 14 | DEPS_DIR := ./_deps 15 | 16 | SDK_ROOT := ../../../../../../../../.. 17 | PROJ_DIR := ../../.. 18 | 19 | # JLINK_MON_DEBUG_DIR should point to the directory that contains the files 20 | # in JLINK_MON_DEBUG_FILES plus JLINK_MONITOR.h. If Monitor Mode Debugging is 21 | # not required then leave JLINK_MON_DEBUG_DIR empty. 22 | JLINK_MON_DEBUG_DIR := 23 | 24 | # The offset of the application needs to be specified so the J-Link knows 25 | # the location of the DebugMon_Handler. For the S132 v4 this is 0x1F000. 26 | JLINK_MON_DEBUG_APP_FLASH_LOCATION := 0x00 27 | 28 | # If the JLINK_MON_DEBUG_DIR is empty then make sure it is evaluated correctly. 29 | JLINK_MON_DEBUG_DIR := $(strip $(JLINK_MON_DEBUG_DIR)) 30 | 31 | # These are the required files as of version 6.12a of the J-Link driver. 32 | JLINK_MON_DEBUG_FILES := JLINK_MONITOR.c JLINK_MONITOR_ISR_SES.s 33 | 34 | # Init commands will be written to a file and then specified when starting GDB 35 | # instead of relying on .gdbinit (to avoid having to enable .gbdinit files). 36 | GDB_CMD_PATH := $(DBG_BUILD_DIR)/gdb.txt 37 | 38 | # Include the correct template Makefile depending on platform. 39 | TEMPLATE_PATH = $(SDK_ROOT)/components/toolchain/gcc 40 | ifeq ($(OS),Windows_NT) 41 | include $(TEMPLATE_PATH)/Makefile.windows 42 | # The Windows command shell 'start' function is used so the executable 43 | # is started in its own window. 44 | TERMINAL := cmd /c start "" 45 | TERMINAL_END := 46 | NRFJPROG := nrfjprog.exe 47 | GDBSERVER := JLinkGDBServerCL.exe 48 | RTT_CLIENT := JLinkRTTClient.exe 49 | else 50 | include $(TEMPLATE_PATH)/Makefile.posix 51 | TERMINAL := gnome-terminal -e " 52 | TERMINAL_END := " 53 | NRFJPROG := nrfjprog 54 | GDBSERVER := JLinkGDBServer 55 | RTT_CLIENT := JLinkRTTClient 56 | endif 57 | 58 | # If multiple J-Links are attached to the computer then "SN=1234" can be used 59 | # to specify a serial number for GDB and flash targets. A random GDB port will 60 | # be generated so multiple targets can be debugged simultaneously. 61 | GDB_PORT := 2331 62 | ifdef SN 63 | NRFJPROG_SN := --snr $(SN) 64 | GDB_SERVER_SN := -select usb=$(SN) 65 | GDB_PORT := $(shell awk 'BEGIN{srand();printf("%4.4s", 1000+9999*rand())}') 66 | endif 67 | 68 | # Toolchain commands (these rely on the inclusion of the template Makefile) 69 | CC := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc 70 | AS := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as 71 | AR := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar -r 72 | LD := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld 73 | NM := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm 74 | OBJDUMP := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump 75 | OBJCOPY := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy 76 | SIZE := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size 77 | GDB := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gdb 78 | 79 | SHAREDFLAGS += \ 80 | -mcpu=cortex-m4 \ 81 | -mthumb \ 82 | -DNRF52 \ 83 | -DNRF52832_XXAA \ 84 | -DCONFIG_GPIO_AS_PINRESET \ 85 | -DBOARD_$(BOARD) \ 86 | -DNRF52_PAN_74 \ 87 | -DBSP_DEFINES_ONLY \ 88 | -DESB_PRESENT 89 | 90 | CFLAGS += \ 91 | --std=gnu99 \ 92 | -Wall \ 93 | -Werror \ 94 | -mfloat-abi=hard \ 95 | -mfpu=fpv4-sp-d16 \ 96 | -ffunction-sections \ 97 | -fdata-sections \ 98 | -fno-strict-aliasing \ 99 | -fno-builtin \ 100 | --short-enums \ 101 | -mabi=aapcs \ 102 | $(SHAREDFLAGS) 103 | 104 | ASMFLAGS += \ 105 | -x assembler-with-cpp \ 106 | $(SHAREDFLAGS) 107 | 108 | LDFLAGS += \ 109 | -mthumb \ 110 | -mabi=aapcs \ 111 | -L $(TEMPLATE_PATH) \ 112 | -T$(LINKER_SCRIPT) \ 113 | -mcpu=cortex-m4 \ 114 | -mfloat-abi=hard \ 115 | -mfpu=fpv4-sp-d16 \ 116 | -Wl,--gc-sections \ 117 | --specs=nano.specs \ 118 | -lc \ 119 | -lnosys 120 | 121 | SRC_FILES += \ 122 | $(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \ 123 | $(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \ 124 | $(SDK_ROOT)/components/boards/boards.c \ 125 | $(SDK_ROOT)/components/libraries/util/app_error.c \ 126 | $(SDK_ROOT)/components/libraries/util/app_error_weak.c \ 127 | $(SDK_ROOT)/components/libraries/util/app_util_platform.c \ 128 | $(SDK_ROOT)/components/libraries/util/nrf_assert.c \ 129 | $(SDK_ROOT)/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c \ 130 | $(SDK_ROOT)/components/libraries/experimental_section_vars/nrf_section_iter.c \ 131 | $(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \ 132 | $(SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \ 133 | $(SDK_ROOT)/components/drivers_nrf/power/nrf_drv_power.c \ 134 | $(SDK_ROOT)/components/drivers_nrf/ppi/nrf_drv_ppi.c \ 135 | $(SDK_ROOT)/components/drivers_nrf/saadc/nrf_drv_saadc.c \ 136 | $(SDK_ROOT)/components/drivers_nrf/timer/nrf_drv_timer.c \ 137 | $(SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \ 138 | $(SDK_ROOT)/components/drivers_nrf/hal/nrf_saadc.c \ 139 | $(PROJ_DIR)/main.c \ 140 | $(PROJ_DIR)/../common/sainsmart_joystick.c \ 141 | $(PROJ_DIR)/../../rc_radio.c \ 142 | $(PROJ_DIR)/../common/utility.c \ 143 | $(SDK_ROOT)/external/segger_rtt/RTT_Syscalls_GCC.c \ 144 | $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \ 145 | $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \ 146 | $(SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52.S \ 147 | $(SDK_ROOT)/components/toolchain/system_nrf52.c \ 148 | $(SDK_ROOT)/components/drivers_nrf/pwm/nrf_drv_pwm.c \ 149 | $(SDK_ROOT)/components/proprietary_rf/esb/nrf_esb.c \ 150 | $(SDK_ROOT)/components/libraries/button/app_button.c \ 151 | $(SDK_ROOT)/components/libraries/timer/app_timer.c \ 152 | $(SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c 153 | 154 | INC_DIRS += \ 155 | $(SDK_ROOT)/components \ 156 | $(PROJ_DIR) \ 157 | $(PROJ_DIR)/../common \ 158 | $(PROJ_DIR)/../.. \ 159 | $(SDK_ROOT)/components/libraries/pwr_mgmt \ 160 | $(SDK_ROOT)/components/libraries/strerror \ 161 | $(SDK_ROOT)/components/drivers_nrf/delay \ 162 | $(SDK_ROOT)/components/toolchain/cmsis/include \ 163 | $(SDK_ROOT)/components/drivers_nrf/timer \ 164 | $(SDK_ROOT)/components/libraries/util \ 165 | $(SDK_ROOT)/components/drivers_nrf/uart \ 166 | $(SDK_ROOT)/components/libraries/bsp \ 167 | $(SDK_ROOT)/components/device \ 168 | $(SDK_ROOT)/external/segger_rtt \ 169 | $(SDK_ROOT)/components/libraries/log \ 170 | $(SDK_ROOT)/components/libraries/experimental_section_vars \ 171 | $(SDK_ROOT)/components/libraries/mutex \ 172 | $(SDK_ROOT)/components/drivers_nrf/saadc \ 173 | $(SDK_ROOT)/components/drivers_nrf/power \ 174 | $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \ 175 | ../config \ 176 | $(SDK_ROOT)/components/libraries/atomic \ 177 | $(SDK_ROOT)/components/boards \ 178 | $(SDK_ROOT)/components/drivers_nrf/hal \ 179 | $(SDK_ROOT)/components/toolchain/gcc \ 180 | $(SDK_ROOT)/components/toolchain \ 181 | $(SDK_ROOT)/components/drivers_nrf/common \ 182 | $(SDK_ROOT)/components/drivers_nrf/ppi \ 183 | $(SDK_ROOT)/components/libraries/log/src \ 184 | $(SDK_ROOT)/components/proprietary_rf/esb \ 185 | $(SDK_ROOT)/components/drivers_nrf/pwm \ 186 | $(SDK_ROOT)/components/libraries/button \ 187 | $(SDK_ROOT)/components/libraries/timer \ 188 | $(SDK_ROOT)/components/drivers_nrf/gpiote 189 | 190 | # The Monitor Mode debugging files will always be tracked by make if they are 191 | # used during debugging. They won't be passed to the linker for the release 192 | # version of the build. 193 | DBG_SRC_FILES := 194 | ifneq "$(JLINK_MON_DEBUG_DIR)" "" 195 | INC_DIRS += $(JLINK_MON_DEBUG_DIR) 196 | DBG_SRC_FILES += $(addprefix $(JLINK_MON_DEBUG_DIR)/, $(JLINK_MON_DEBUG_FILES)) 197 | else 198 | $(warning Define JLINK_MON_DEBUG_DIR to enable Monitor Mode Debugging.) 199 | endif 200 | 201 | ASSEMBLY_EXTS := s S 202 | 203 | # Convert to absolute paths and sort to remove duplicates. 204 | SRC_FILES := $(sort $(foreach f,$(SRC_FILES),$(abspath $(f)))) 205 | DBG_SRC_FILES := $(sort $(foreach f,$(DBG_SRC_FILES),$(abspath $(f)))) 206 | INC_DIRS := $(sort $(foreach d,$(INC_DIRS),$(abspath $(d)))) 207 | 208 | # Split the file paths into file names and directories. And remove duplicates. 209 | SRC_DIRS := $(sort $(dir $(SRC_FILES))) 210 | SRC_FILE_NAMES := $(notdir $(SRC_FILES)) 211 | DBG_SRC_DIRS := $(sort $(dir $(DBG_SRC_FILES))) 212 | DBG_SRC_FILE_NAMES := $(notdir $(DBG_SRC_FILES)) 213 | 214 | # Convert each source file name into the form '$(OBJ_DIR)/$(SRC_FILE).o'. 215 | OBJ := $(patsubst %,%.o,$(basename $(SRC_FILE_NAMES))) 216 | DBG_OBJ := $(patsubst %,%.o,$(basename $(DBG_SRC_FILE_NAMES))) 217 | DBG_OBJ := $(addprefix $(DBG_BUILD_DIR)/,$(OBJ) $(DBG_OBJ)) 218 | REL_OBJ := $(addprefix $(REL_BUILD_DIR)/,$(OBJ)) 219 | 220 | .PHONY: default 221 | default: CFLAGS += -O0 -ggdb -DDEBUG -DDEBUG_NRF 222 | default: OBJ_DIR := $(DBG_BUILD_DIR) 223 | default: $(DBG_BUILD_DIR)/$(PROJECT_NAME).hex 224 | $(call echosize,$(DBG_BUILD_DIR)/$(PROJECT_NAME).out) 225 | 226 | .PHONY: release 227 | release: CFLAGS += -O3 -g3 228 | release: OBJ_DIR := $(REL_BUILD_DIR) 229 | release: $(REL_BUILD_DIR)/$(PROJECT_NAME).bin $(REL_BUILD_DIR)/$(PROJECT_NAME).hex 230 | $(call echosize,$(REL_BUILD_DIR)/$(PROJECT_NAME).out) 231 | 232 | .PHONY: all 233 | all: default release 234 | 235 | DEPS := $(addprefix $(DEPS_DIR)/,$(OBJ:.o=.d)) 236 | -include $(DEPS) 237 | 238 | INCLUDES := $(patsubst %,-I%,$(INC_DIRS)) 239 | 240 | # Look for all source files in SRC_DIRS. 241 | vpath % $(SRC_DIRS) $(DBG_SRC_DIRS) 242 | 243 | define echosize 244 | @echo '' 245 | @'$(SIZE)' $1; 246 | @echo '' 247 | endef 248 | 249 | define flash 250 | @"$(NRFJPROG)" $(NRFJPROG_SN) --program $1 -f nrf52 --sectorerase --verify 251 | @"$(NRFJPROG)" $(NRFJPROG_SN) --reset -f nrf52 252 | endef 253 | 254 | $(DBG_BUILD_DIR)/%.o: %.c | $(DBG_BUILD_DIR) 255 | @echo Compiling file: $(notdir $<) 256 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c -o $@ $< 257 | 258 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).hex: $(DBG_BUILD_DIR)/$(PROJECT_NAME).out 259 | @echo Creating hex file: $(notdir $@) 260 | @'$(OBJCOPY)' -O ihex $(DBG_BUILD_DIR)/$(PROJECT_NAME).out $@ 261 | 262 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).bin: $(DBG_BUILD_DIR)/$(PROJECT_NAME).out 263 | @echo Creating bin file: $(notdir $@) 264 | @'$(OBJCOPY)' -O binary $(DBG_BUILD_DIR)/$(PROJECT_NAME).out $@ 265 | 266 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).out: $(DBG_OBJ) 267 | @echo Linking ELF file: $(notdir $@) 268 | @'$(CC)' $(LDFLAGS) $(DBG_OBJ) -lm -o $@ 269 | 270 | $(REL_BUILD_DIR)/%.o: %.c | $(REL_BUILD_DIR) 271 | @echo Compiling file: $(notdir $<) 272 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c -o $@ $< 273 | 274 | $(REL_BUILD_DIR)/$(PROJECT_NAME).hex: $(REL_BUILD_DIR)/$(PROJECT_NAME).out 275 | @echo Creating hex file: $(notdir $@) 276 | @'$(OBJCOPY)' -O ihex $(REL_BUILD_DIR)/$(PROJECT_NAME).out $@ 277 | 278 | $(REL_BUILD_DIR)/$(PROJECT_NAME).bin: $(REL_BUILD_DIR)/$(PROJECT_NAME).out 279 | @echo Creating bin file: $(notdir $@) 280 | @'$(OBJCOPY)' -O binary $(REL_BUILD_DIR)/$(PROJECT_NAME).out $@ 281 | 282 | $(REL_BUILD_DIR)/$(PROJECT_NAME).out: $(REL_OBJ) 283 | @echo Linking ELF file: $(notdir $@) 284 | @'$(CC)' $(LDFLAGS) $(REL_OBJ) -lm -o $@ 285 | 286 | $(DEPS_DIR)/%.d: %.c | $(DEPS_DIR) 287 | @echo Adding dependency for file: $(notdir $<) 288 | @echo -n "$(DBG_BUILD_DIR)/$(notdir $(<:.c=.o)) " > $@ 289 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c $< -MM \ 290 | -MT $(REL_BUILD_DIR)/$(notdir $(<:.c=.o)) >> $@ 291 | 292 | # The eval command is used to create a different version of these targets for 293 | # each extension in the ASSEMBLY_EXTS list. 294 | define assembly_targets 295 | $$(DBG_BUILD_DIR)/%.o: %.$1 | $$(DBG_BUILD_DIR) 296 | @echo Compiling assembly file: $$(notdir $$<) 297 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c -o $$@ $$< 298 | 299 | $$(REL_BUILD_DIR)/%.o: %.$1 | $$(REL_BUILD_DIR) 300 | @echo Compiling assembly file: $$(notdir $$<) 301 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c -o $$@ $$< 302 | 303 | $$(DEPS_DIR)/%.d: %.$1 | $$(DEPS_DIR) 304 | @echo Adding dependency for file: $$(notdir $$<) 305 | @echo -n "$$(DBG_BUILD_DIR)/$$(notdir $$(<:.$1=.o)) " > $$@ 306 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c $$< -MM \ 307 | -MT $$(REL_BUILD_DIR)/$$(notdir $$(<:.$1=.o)) >> $$@ 308 | endef 309 | $(foreach EXT,$(ASSEMBLY_EXTS),$(eval $(call assembly_targets,$(EXT)))) 310 | 311 | $(DEPS_DIR) $(DBG_BUILD_DIR) $(REL_BUILD_DIR):; @mkdir $@ 312 | 313 | .PHONY: flash_debug 314 | flash_debug: default 315 | $(call flash,$(DBG_BUILD_DIR)/$(PROJECT_NAME).hex) 316 | 317 | .PHONY: flash_release 318 | flash_release: release 319 | $(call flash,$(REL_BUILD_DIR)/$(PROJECT_NAME).hex) 320 | 321 | .PHONY: gdb_cmd_file 322 | gdb_cmd_file: default 323 | @echo "target remote localhost:$(GDB_PORT)" > $(GDB_CMD_PATH) 324 | @echo "mon speed 10000" >> $(GDB_CMD_PATH) 325 | @echo "mon flash download=1" >> $(GDB_CMD_PATH) 326 | @echo "load $(DBG_BUILD_DIR)/$(PROJECT_NAME).out" >> $(GDB_CMD_PATH) 327 | @echo "break main" >> $(GDB_CMD_PATH) 328 | @echo "mon reset 0" >> $(GDB_CMD_PATH) 329 | @echo "c" >> $(GDB_CMD_PATH) 330 | 331 | .PHONY: gdb_mon_cmd_file 332 | gdb_mon_cmd_file: gdb_cmd_file 333 | @echo "mon exec SetMonModeDebug=1" >> $(GDB_CMD_PATH) 334 | @echo "mon exec SetMonModeVTableAddr=$(JLINK_MON_DEBUG_APP_FLASH_LOCATION)" >> $(GDB_CMD_PATH) 335 | 336 | .PHONY: gdb_cli 337 | gdb_cli: 338 | @$(TERMINAL) '$(GDBSERVER)' $(GDB_SERVER_SN) -device nrf52832_XXAA \ 339 | -if swd -port $(GDB_PORT) $(TERMINAL_END) 340 | @$(TERMINAL) '$(GDB)' $(DBG_BUILD_DIR)/$(PROJECT_NAME).out -x $(GDB_CMD_PATH) $(TERMINAL_END) 341 | 342 | .PHONY: rtt 343 | rtt: 344 | @$(TERMINAL) '$(RTT_CLIENT)' $(TERMINAL_END) 345 | 346 | .PHONY: gdb 347 | gdb: gdb_cmd_file gdb_cli 348 | 349 | .PHONY: gdb_mon 350 | gdb_mon: gdb_mon_cmd_file gdb_cli 351 | 352 | .PHONY: gdb_rtt 353 | gdb_rtt: gdb rtt 354 | 355 | .PHONY: gdb_mon_rtt 356 | gdb_mon_rtt: gdb_mon rtt 357 | 358 | .PHONY: clean 359 | clean: 360 | @rm -rf $(DBG_BUILD_DIR) 361 | @rm -rf $(REL_BUILD_DIR) 362 | @rm -rf $(DEPS_DIR) 363 | 364 | .PHONY: help 365 | help: 366 | @echo "The following targets are available:" 367 | @echo " (default) - Compile with debug flags" 368 | @echo " release - Compile with release flags" 369 | @echo " all - Compile debug and release targets" 370 | @echo " clean - Remove object and dependency directories" 371 | @echo " gdb [SN=1234] - Perform debug compile and then launch gdb" 372 | @echo " gdb_rtt [SN=1234] - Call gdb target and then open RTT Client" 373 | ifneq "$(JLINK_MON_DEBUG_DIR)" "" 374 | @echo " gdb_mon [SN=1234] - Enable Monitor Mode Debugging" 375 | @echo " gdb_mon_rtt [SN=1234] - Enable Mon Debugging and open RTT Client" 376 | endif 377 | @echo " flash_debug [SN=1234] - Flash the debug build" 378 | @echo " flash_release [SN=1234]- Flash the release build" 379 | 380 | # This is a special target that tells make to delete a file if an error occurs 381 | # while the file is being generated. 382 | .DELETE_ON_ERROR: 383 | -------------------------------------------------------------------------------- /src/examples/tx/pca10040/blank/armgcc/poly_tx_gcc_nrf52.ld: -------------------------------------------------------------------------------- 1 | /* Linker script to configure memory regions. */ 2 | 3 | SEARCH_DIR(.) 4 | GROUP(-lgcc -lc -lnosys) 5 | 6 | MEMORY 7 | { 8 | FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 9 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 10 | } 11 | 12 | SECTIONS 13 | { 14 | .fs_data : 15 | { 16 | PROVIDE(__start_fs_data = .); 17 | KEEP(*(.fs_data)) 18 | PROVIDE(__stop_fs_data = .); 19 | } > RAM 20 | } INSERT AFTER .data; 21 | 22 | SECTIONS 23 | { 24 | .pwr_mgmt_data : 25 | { 26 | PROVIDE(__start_pwr_mgmt_data = .); 27 | KEEP(*(SORT(.pwr_mgmt_data*))) 28 | PROVIDE(__stop_pwr_mgmt_data = .); 29 | } > FLASH 30 | } INSERT AFTER .text 31 | 32 | INCLUDE "nrf5x_common.ld" 33 | -------------------------------------------------------------------------------- /src/examples/tx/pca10040/blank/config/sdk_config.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef SDK_CONFIG_H 4 | #define SDK_CONFIG_H 5 | // <<< Use Configuration Wizard in Context Menu >>>\n 6 | #ifdef USE_APP_CONFIG 7 | #include "app_config.h" 8 | #endif 9 | // nRF_Drivers 10 | 11 | //========================================================== 12 | // PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common - Peripheral drivers common module 13 | //========================================================== 14 | #ifndef PERIPHERAL_RESOURCE_SHARING_ENABLED 15 | #define PERIPHERAL_RESOURCE_SHARING_ENABLED 0 16 | #endif 17 | #if PERIPHERAL_RESOURCE_SHARING_ENABLED 18 | // COMMON_CONFIG_LOG_ENABLED - Enables logging in the module. 19 | //========================================================== 20 | #ifndef COMMON_CONFIG_LOG_ENABLED 21 | #define COMMON_CONFIG_LOG_ENABLED 0 22 | #endif 23 | #if COMMON_CONFIG_LOG_ENABLED 24 | // COMMON_CONFIG_LOG_LEVEL - Default Severity level 25 | 26 | // <0=> Off 27 | // <1=> Error 28 | // <2=> Warning 29 | // <3=> Info 30 | // <4=> Debug 31 | 32 | #ifndef COMMON_CONFIG_LOG_LEVEL 33 | #define COMMON_CONFIG_LOG_LEVEL 3 34 | #endif 35 | 36 | // COMMON_CONFIG_INFO_COLOR - ANSI escape code prefix. 37 | 38 | // <0=> Default 39 | // <1=> Black 40 | // <2=> Red 41 | // <3=> Green 42 | // <4=> Yellow 43 | // <5=> Blue 44 | // <6=> Magenta 45 | // <7=> Cyan 46 | // <8=> White 47 | 48 | #ifndef COMMON_CONFIG_INFO_COLOR 49 | #define COMMON_CONFIG_INFO_COLOR 0 50 | #endif 51 | 52 | // COMMON_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 53 | 54 | // <0=> Default 55 | // <1=> Black 56 | // <2=> Red 57 | // <3=> Green 58 | // <4=> Yellow 59 | // <5=> Blue 60 | // <6=> Magenta 61 | // <7=> Cyan 62 | // <8=> White 63 | 64 | #ifndef COMMON_CONFIG_DEBUG_COLOR 65 | #define COMMON_CONFIG_DEBUG_COLOR 0 66 | #endif 67 | 68 | #endif //COMMON_CONFIG_LOG_ENABLED 69 | // 70 | 71 | #endif //PERIPHERAL_RESOURCE_SHARING_ENABLED 72 | // 73 | 74 | // POWER_ENABLED - nrf_drv_power - POWER peripheral driver 75 | //========================================================== 76 | #ifndef POWER_ENABLED 77 | #define POWER_ENABLED 0 78 | #endif 79 | #if POWER_ENABLED 80 | // POWER_CONFIG_IRQ_PRIORITY - Interrupt priority 81 | 82 | 83 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 84 | // <0=> 0 (highest) 85 | // <1=> 1 86 | // <2=> 2 87 | // <3=> 3 88 | // <4=> 4 89 | // <5=> 5 90 | // <6=> 6 91 | // <7=> 7 92 | 93 | #ifndef POWER_CONFIG_IRQ_PRIORITY 94 | #define POWER_CONFIG_IRQ_PRIORITY 7 95 | #endif 96 | 97 | // POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator 98 | 99 | 100 | // This settings means only that components for DCDC regulator are installed and it can be enabled. 101 | 102 | #ifndef POWER_CONFIG_DEFAULT_DCDCEN 103 | #define POWER_CONFIG_DEFAULT_DCDCEN 1 104 | #endif 105 | 106 | // POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator 107 | 108 | 109 | // This settings means only that components for DCDC regulator are installed and it can be enabled. 110 | 111 | #ifndef POWER_CONFIG_DEFAULT_DCDCENHV 112 | #define POWER_CONFIG_DEFAULT_DCDCENHV 0 113 | #endif 114 | 115 | #endif //POWER_ENABLED 116 | // 117 | 118 | // PPI_ENABLED - nrf_drv_ppi - PPI peripheral driver 119 | //========================================================== 120 | #ifndef PPI_ENABLED 121 | #define PPI_ENABLED 1 122 | #endif 123 | #if PPI_ENABLED 124 | // PPI_CONFIG_LOG_ENABLED - Enables logging in the module. 125 | //========================================================== 126 | #ifndef PPI_CONFIG_LOG_ENABLED 127 | #define PPI_CONFIG_LOG_ENABLED 0 128 | #endif 129 | #if PPI_CONFIG_LOG_ENABLED 130 | // PPI_CONFIG_LOG_LEVEL - Default Severity level 131 | 132 | // <0=> Off 133 | // <1=> Error 134 | // <2=> Warning 135 | // <3=> Info 136 | // <4=> Debug 137 | 138 | #ifndef PPI_CONFIG_LOG_LEVEL 139 | #define PPI_CONFIG_LOG_LEVEL 3 140 | #endif 141 | 142 | // PPI_CONFIG_INFO_COLOR - ANSI escape code prefix. 143 | 144 | // <0=> Default 145 | // <1=> Black 146 | // <2=> Red 147 | // <3=> Green 148 | // <4=> Yellow 149 | // <5=> Blue 150 | // <6=> Magenta 151 | // <7=> Cyan 152 | // <8=> White 153 | 154 | #ifndef PPI_CONFIG_INFO_COLOR 155 | #define PPI_CONFIG_INFO_COLOR 0 156 | #endif 157 | 158 | // PPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 159 | 160 | // <0=> Default 161 | // <1=> Black 162 | // <2=> Red 163 | // <3=> Green 164 | // <4=> Yellow 165 | // <5=> Blue 166 | // <6=> Magenta 167 | // <7=> Cyan 168 | // <8=> White 169 | 170 | #ifndef PPI_CONFIG_DEBUG_COLOR 171 | #define PPI_CONFIG_DEBUG_COLOR 0 172 | #endif 173 | 174 | #endif //PPI_CONFIG_LOG_ENABLED 175 | // 176 | 177 | #endif //PPI_ENABLED 178 | // 179 | 180 | // SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver 181 | //========================================================== 182 | #ifndef SAADC_ENABLED 183 | #define SAADC_ENABLED 1 184 | #endif 185 | #if SAADC_ENABLED 186 | // SAADC_CONFIG_RESOLUTION - Resolution 187 | 188 | // <0=> 8 bit 189 | // <1=> 10 bit 190 | // <2=> 12 bit 191 | // <3=> 14 bit 192 | 193 | #ifndef SAADC_CONFIG_RESOLUTION 194 | #define SAADC_CONFIG_RESOLUTION 1 195 | #endif 196 | 197 | // SAADC_CONFIG_OVERSAMPLE - Sample period 198 | 199 | // <0=> Disabled 200 | // <1=> 2x 201 | // <2=> 4x 202 | // <3=> 8x 203 | // <4=> 16x 204 | // <5=> 32x 205 | // <6=> 64x 206 | // <7=> 128x 207 | // <8=> 256x 208 | 209 | #ifndef SAADC_CONFIG_OVERSAMPLE 210 | #define SAADC_CONFIG_OVERSAMPLE 0 211 | #endif 212 | 213 | // SAADC_CONFIG_LP_MODE - Enabling low power mode 214 | 215 | 216 | #ifndef SAADC_CONFIG_LP_MODE 217 | #define SAADC_CONFIG_LP_MODE 0 218 | #endif 219 | 220 | // SAADC_CONFIG_IRQ_PRIORITY - Interrupt priority 221 | 222 | 223 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 224 | // <0=> 0 (highest) 225 | // <1=> 1 226 | // <2=> 2 227 | // <3=> 3 228 | // <4=> 4 229 | // <5=> 5 230 | // <6=> 6 231 | // <7=> 7 232 | 233 | #ifndef SAADC_CONFIG_IRQ_PRIORITY 234 | #define SAADC_CONFIG_IRQ_PRIORITY 7 235 | #endif 236 | 237 | // SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. 238 | //========================================================== 239 | #ifndef SAADC_CONFIG_LOG_ENABLED 240 | #define SAADC_CONFIG_LOG_ENABLED 0 241 | #endif 242 | #if SAADC_CONFIG_LOG_ENABLED 243 | // SAADC_CONFIG_LOG_LEVEL - Default Severity level 244 | 245 | // <0=> Off 246 | // <1=> Error 247 | // <2=> Warning 248 | // <3=> Info 249 | // <4=> Debug 250 | 251 | #ifndef SAADC_CONFIG_LOG_LEVEL 252 | #define SAADC_CONFIG_LOG_LEVEL 3 253 | #endif 254 | 255 | // SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix. 256 | 257 | // <0=> Default 258 | // <1=> Black 259 | // <2=> Red 260 | // <3=> Green 261 | // <4=> Yellow 262 | // <5=> Blue 263 | // <6=> Magenta 264 | // <7=> Cyan 265 | // <8=> White 266 | 267 | #ifndef SAADC_CONFIG_INFO_COLOR 268 | #define SAADC_CONFIG_INFO_COLOR 0 269 | #endif 270 | 271 | // SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 272 | 273 | // <0=> Default 274 | // <1=> Black 275 | // <2=> Red 276 | // <3=> Green 277 | // <4=> Yellow 278 | // <5=> Blue 279 | // <6=> Magenta 280 | // <7=> Cyan 281 | // <8=> White 282 | 283 | #ifndef SAADC_CONFIG_DEBUG_COLOR 284 | #define SAADC_CONFIG_DEBUG_COLOR 0 285 | #endif 286 | 287 | #endif //SAADC_CONFIG_LOG_ENABLED 288 | // 289 | 290 | #endif //SAADC_ENABLED 291 | // 292 | 293 | // TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver 294 | //========================================================== 295 | #ifndef TIMER_ENABLED 296 | #define TIMER_ENABLED 1 297 | #endif 298 | #if TIMER_ENABLED 299 | // TIMER_DEFAULT_CONFIG_FREQUENCY - Timer frequency if in Timer mode 300 | 301 | // <0=> 16 MHz 302 | // <1=> 8 MHz 303 | // <2=> 4 MHz 304 | // <3=> 2 MHz 305 | // <4=> 1 MHz 306 | // <5=> 500 kHz 307 | // <6=> 250 kHz 308 | // <7=> 125 kHz 309 | // <8=> 62.5 kHz 310 | // <9=> 31.25 kHz 311 | 312 | #ifndef TIMER_DEFAULT_CONFIG_FREQUENCY 313 | #define TIMER_DEFAULT_CONFIG_FREQUENCY 0 314 | #endif 315 | 316 | // TIMER_DEFAULT_CONFIG_MODE - Timer mode or operation 317 | 318 | // <0=> Timer 319 | // <1=> Counter 320 | 321 | #ifndef TIMER_DEFAULT_CONFIG_MODE 322 | #define TIMER_DEFAULT_CONFIG_MODE 0 323 | #endif 324 | 325 | // TIMER_DEFAULT_CONFIG_BIT_WIDTH - Timer counter bit width 326 | 327 | // <0=> 16 bit 328 | // <1=> 8 bit 329 | // <2=> 24 bit 330 | // <3=> 32 bit 331 | 332 | #ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH 333 | #define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0 334 | #endif 335 | 336 | // TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority 337 | 338 | 339 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 340 | // <0=> 0 (highest) 341 | // <1=> 1 342 | // <2=> 2 343 | // <3=> 3 344 | // <4=> 4 345 | // <5=> 5 346 | // <6=> 6 347 | // <7=> 7 348 | 349 | #ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 350 | #define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 351 | #endif 352 | 353 | // TIMER0_ENABLED - Enable TIMER0 instance 354 | 355 | 356 | #ifndef TIMER0_ENABLED 357 | #define TIMER0_ENABLED 1 358 | #endif 359 | 360 | // TIMER1_ENABLED - Enable TIMER1 instance 361 | 362 | 363 | #ifndef TIMER1_ENABLED 364 | #define TIMER1_ENABLED 1 365 | #endif 366 | 367 | // TIMER2_ENABLED - Enable TIMER2 instance 368 | 369 | 370 | #ifndef TIMER2_ENABLED 371 | #define TIMER2_ENABLED 1 372 | #endif 373 | 374 | // TIMER3_ENABLED - Enable TIMER3 instance 375 | 376 | 377 | #ifndef TIMER3_ENABLED 378 | #define TIMER3_ENABLED 0 379 | #endif 380 | 381 | // TIMER4_ENABLED - Enable TIMER4 instance 382 | 383 | 384 | #ifndef TIMER4_ENABLED 385 | #define TIMER4_ENABLED 0 386 | #endif 387 | 388 | // TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. 389 | //========================================================== 390 | #ifndef TIMER_CONFIG_LOG_ENABLED 391 | #define TIMER_CONFIG_LOG_ENABLED 0 392 | #endif 393 | #if TIMER_CONFIG_LOG_ENABLED 394 | // TIMER_CONFIG_LOG_LEVEL - Default Severity level 395 | 396 | // <0=> Off 397 | // <1=> Error 398 | // <2=> Warning 399 | // <3=> Info 400 | // <4=> Debug 401 | 402 | #ifndef TIMER_CONFIG_LOG_LEVEL 403 | #define TIMER_CONFIG_LOG_LEVEL 3 404 | #endif 405 | 406 | // TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. 407 | 408 | // <0=> Default 409 | // <1=> Black 410 | // <2=> Red 411 | // <3=> Green 412 | // <4=> Yellow 413 | // <5=> Blue 414 | // <6=> Magenta 415 | // <7=> Cyan 416 | // <8=> White 417 | 418 | #ifndef TIMER_CONFIG_INFO_COLOR 419 | #define TIMER_CONFIG_INFO_COLOR 0 420 | #endif 421 | 422 | // TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 423 | 424 | // <0=> Default 425 | // <1=> Black 426 | // <2=> Red 427 | // <3=> Green 428 | // <4=> Yellow 429 | // <5=> Blue 430 | // <6=> Magenta 431 | // <7=> Cyan 432 | // <8=> White 433 | 434 | #ifndef TIMER_CONFIG_DEBUG_COLOR 435 | #define TIMER_CONFIG_DEBUG_COLOR 0 436 | #endif 437 | 438 | #endif //TIMER_CONFIG_LOG_ENABLED 439 | // 440 | 441 | #endif //TIMER_ENABLED 442 | // 443 | 444 | // UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver 445 | //========================================================== 446 | #ifndef UART_ENABLED 447 | #define UART_ENABLED 0 448 | #endif 449 | #if UART_ENABLED 450 | // UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control 451 | 452 | // <0=> Disabled 453 | // <1=> Enabled 454 | 455 | #ifndef UART_DEFAULT_CONFIG_HWFC 456 | #define UART_DEFAULT_CONFIG_HWFC 0 457 | #endif 458 | 459 | // UART_DEFAULT_CONFIG_PARITY - Parity 460 | 461 | // <0=> Excluded 462 | // <14=> Included 463 | 464 | #ifndef UART_DEFAULT_CONFIG_PARITY 465 | #define UART_DEFAULT_CONFIG_PARITY 0 466 | #endif 467 | 468 | // UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate 469 | 470 | // <323584=> 1200 baud 471 | // <643072=> 2400 baud 472 | // <1290240=> 4800 baud 473 | // <2576384=> 9600 baud 474 | // <3862528=> 14400 baud 475 | // <5152768=> 19200 baud 476 | // <7716864=> 28800 baud 477 | // <10289152=> 38400 baud 478 | // <15400960=> 57600 baud 479 | // <20615168=> 76800 baud 480 | // <30801920=> 115200 baud 481 | // <61865984=> 230400 baud 482 | // <67108864=> 250000 baud 483 | // <121634816=> 460800 baud 484 | // <251658240=> 921600 baud 485 | // <268435456=> 57600 baud 486 | 487 | #ifndef UART_DEFAULT_CONFIG_BAUDRATE 488 | #define UART_DEFAULT_CONFIG_BAUDRATE 30801920 489 | #endif 490 | 491 | // UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority 492 | 493 | 494 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 495 | // <0=> 0 (highest) 496 | // <1=> 1 497 | // <2=> 2 498 | // <3=> 3 499 | // <4=> 4 500 | // <5=> 5 501 | // <6=> 6 502 | // <7=> 7 503 | 504 | #ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY 505 | #define UART_DEFAULT_CONFIG_IRQ_PRIORITY 7 506 | #endif 507 | 508 | // UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA 509 | 510 | 511 | #ifndef UART_EASY_DMA_SUPPORT 512 | #define UART_EASY_DMA_SUPPORT 1 513 | #endif 514 | 515 | // UART_LEGACY_SUPPORT - Driver supporting Legacy mode 516 | 517 | 518 | #ifndef UART_LEGACY_SUPPORT 519 | #define UART_LEGACY_SUPPORT 1 520 | #endif 521 | 522 | // UART0_ENABLED - Enable UART0 instance 523 | //========================================================== 524 | #ifndef UART0_ENABLED 525 | #define UART0_ENABLED 1 526 | #endif 527 | #if UART0_ENABLED 528 | // UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA 529 | 530 | 531 | #ifndef UART0_CONFIG_USE_EASY_DMA 532 | #define UART0_CONFIG_USE_EASY_DMA 1 533 | #endif 534 | 535 | #endif //UART0_ENABLED 536 | // 537 | 538 | // UART_CONFIG_LOG_ENABLED - Enables logging in the module. 539 | //========================================================== 540 | #ifndef UART_CONFIG_LOG_ENABLED 541 | #define UART_CONFIG_LOG_ENABLED 0 542 | #endif 543 | #if UART_CONFIG_LOG_ENABLED 544 | // UART_CONFIG_LOG_LEVEL - Default Severity level 545 | 546 | // <0=> Off 547 | // <1=> Error 548 | // <2=> Warning 549 | // <3=> Info 550 | // <4=> Debug 551 | 552 | #ifndef UART_CONFIG_LOG_LEVEL 553 | #define UART_CONFIG_LOG_LEVEL 3 554 | #endif 555 | 556 | // UART_CONFIG_INFO_COLOR - ANSI escape code prefix. 557 | 558 | // <0=> Default 559 | // <1=> Black 560 | // <2=> Red 561 | // <3=> Green 562 | // <4=> Yellow 563 | // <5=> Blue 564 | // <6=> Magenta 565 | // <7=> Cyan 566 | // <8=> White 567 | 568 | #ifndef UART_CONFIG_INFO_COLOR 569 | #define UART_CONFIG_INFO_COLOR 0 570 | #endif 571 | 572 | // UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 573 | 574 | // <0=> Default 575 | // <1=> Black 576 | // <2=> Red 577 | // <3=> Green 578 | // <4=> Yellow 579 | // <5=> Blue 580 | // <6=> Magenta 581 | // <7=> Cyan 582 | // <8=> White 583 | 584 | #ifndef UART_CONFIG_DEBUG_COLOR 585 | #define UART_CONFIG_DEBUG_COLOR 0 586 | #endif 587 | 588 | #endif //UART_CONFIG_LOG_ENABLED 589 | // 590 | 591 | #endif //UART_ENABLED 592 | // 593 | 594 | // 595 | //========================================================== 596 | 597 | // nRF_Libraries 598 | 599 | //========================================================== 600 | // NRF_PWR_MGMT_ENABLED - nrf_pwr_mgmt - Power management module 601 | //========================================================== 602 | #ifndef NRF_PWR_MGMT_ENABLED 603 | #define NRF_PWR_MGMT_ENABLED 1 604 | #endif 605 | #if NRF_PWR_MGMT_ENABLED 606 | // NRF_PWR_MGMT_CONFIG_LOG_ENABLED - Enables logging in the module. 607 | //========================================================== 608 | #ifndef NRF_PWR_MGMT_CONFIG_LOG_ENABLED 609 | #define NRF_PWR_MGMT_CONFIG_LOG_ENABLED 0 610 | #endif 611 | #if NRF_PWR_MGMT_CONFIG_LOG_ENABLED 612 | // NRF_PWR_MGMT_CONFIG_LOG_LEVEL - Default Severity level 613 | 614 | // <0=> Off 615 | // <1=> Error 616 | // <2=> Warning 617 | // <3=> Info 618 | // <4=> Debug 619 | 620 | #ifndef NRF_PWR_MGMT_CONFIG_LOG_LEVEL 621 | #define NRF_PWR_MGMT_CONFIG_LOG_LEVEL 3 622 | #endif 623 | 624 | // NRF_PWR_MGMT_CONFIG_INFO_COLOR - ANSI escape code prefix. 625 | 626 | // <0=> Default 627 | // <1=> Black 628 | // <2=> Red 629 | // <3=> Green 630 | // <4=> Yellow 631 | // <5=> Blue 632 | // <6=> Magenta 633 | // <7=> Cyan 634 | // <8=> White 635 | 636 | #ifndef NRF_PWR_MGMT_CONFIG_INFO_COLOR 637 | #define NRF_PWR_MGMT_CONFIG_INFO_COLOR 0 638 | #endif 639 | 640 | // NRF_PWR_MGMT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 641 | 642 | // <0=> Default 643 | // <1=> Black 644 | // <2=> Red 645 | // <3=> Green 646 | // <4=> Yellow 647 | // <5=> Blue 648 | // <6=> Magenta 649 | // <7=> Cyan 650 | // <8=> White 651 | 652 | #ifndef NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 653 | #define NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 0 654 | #endif 655 | 656 | #endif //NRF_PWR_MGMT_CONFIG_LOG_ENABLED 657 | // 658 | 659 | // NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED - Enables pin debug in the module. 660 | 661 | // Selected pin will be set when CPU is in sleep mode. 662 | //========================================================== 663 | #ifndef NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 664 | #define NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 0 665 | #endif 666 | #if NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 667 | // NRF_PWR_MGMT_SLEEP_DEBUG_PIN - Pin number 668 | 669 | // <0=> 0 (P0.0) 670 | // <1=> 1 (P0.1) 671 | // <2=> 2 (P0.2) 672 | // <3=> 3 (P0.3) 673 | // <4=> 4 (P0.4) 674 | // <5=> 5 (P0.5) 675 | // <6=> 6 (P0.6) 676 | // <7=> 7 (P0.7) 677 | // <8=> 8 (P0.8) 678 | // <9=> 9 (P0.9) 679 | // <10=> 10 (P0.10) 680 | // <11=> 11 (P0.11) 681 | // <12=> 12 (P0.12) 682 | // <13=> 13 (P0.13) 683 | // <14=> 14 (P0.14) 684 | // <15=> 15 (P0.15) 685 | // <16=> 16 (P0.16) 686 | // <17=> 17 (P0.17) 687 | // <18=> 18 (P0.18) 688 | // <19=> 19 (P0.19) 689 | // <20=> 20 (P0.20) 690 | // <21=> 21 (P0.21) 691 | // <22=> 22 (P0.22) 692 | // <23=> 23 (P0.23) 693 | // <24=> 24 (P0.24) 694 | // <25=> 25 (P0.25) 695 | // <26=> 26 (P0.26) 696 | // <27=> 27 (P0.27) 697 | // <28=> 28 (P0.28) 698 | // <29=> 29 (P0.29) 699 | // <30=> 30 (P0.30) 700 | // <31=> 31 (P0.31) 701 | // <4294967295=> Not connected 702 | 703 | #ifndef NRF_PWR_MGMT_SLEEP_DEBUG_PIN 704 | #define NRF_PWR_MGMT_SLEEP_DEBUG_PIN 31 705 | #endif 706 | 707 | #endif //NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 708 | // 709 | 710 | // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED - Enables CPU usage monitor. 711 | 712 | 713 | // Module will trace percentage of CPU usage in one second intervals. 714 | 715 | #ifndef NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED 716 | #define NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED 0 717 | #endif 718 | 719 | // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED - Enable standby timeout. 720 | //========================================================== 721 | #ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 722 | #define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 0 723 | #endif 724 | #if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 725 | // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S - Standby timeout (in seconds). 726 | // Shutdown procedure will begin no earlier than after this number of seconds. 727 | 728 | #ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S 729 | #define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S 3 730 | #endif 731 | 732 | #endif //NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 733 | // 734 | 735 | // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED - Enables FPU event cleaning. 736 | 737 | 738 | #ifndef NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED 739 | #define NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED 1 740 | #endif 741 | 742 | // NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY - Blocked shutdown procedure will be retried every second. 743 | 744 | 745 | #ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 746 | #define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 0 747 | #endif 748 | 749 | // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER - Module will use @ref app_scheduler. 750 | 751 | 752 | #ifndef NRF_PWR_MGMT_CONFIG_USE_SCHEDULER 753 | #define NRF_PWR_MGMT_CONFIG_USE_SCHEDULER 0 754 | #endif 755 | 756 | // NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT - The number of priorities for module handlers. 757 | // The number of stages of the shutdown process. 758 | 759 | #ifndef NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT 760 | #define NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT 3 761 | #endif 762 | 763 | #endif //NRF_PWR_MGMT_ENABLED 764 | // 765 | 766 | // NRF_SECTION_ITER_ENABLED - nrf_section_iter - Section iterator 767 | 768 | 769 | #ifndef NRF_SECTION_ITER_ENABLED 770 | #define NRF_SECTION_ITER_ENABLED 1 771 | #endif 772 | 773 | // NRF_STRERROR_ENABLED - nrf_strerror - Library for converting error code to string. 774 | 775 | 776 | #ifndef NRF_STRERROR_ENABLED 777 | #define NRF_STRERROR_ENABLED 1 778 | #endif 779 | 780 | // 781 | //========================================================== 782 | 783 | // nRF_Log 784 | 785 | //========================================================== 786 | // NRF_LOG_ENABLED - nrf_log - Logging 787 | //========================================================== 788 | #ifndef NRF_LOG_ENABLED 789 | #define NRF_LOG_ENABLED 1 790 | #endif 791 | #if NRF_LOG_ENABLED 792 | // NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string 793 | //========================================================== 794 | #ifndef NRF_LOG_USES_COLORS 795 | #define NRF_LOG_USES_COLORS 0 796 | #endif 797 | #if NRF_LOG_USES_COLORS 798 | // NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix. 799 | 800 | // <0=> Default 801 | // <1=> Black 802 | // <2=> Red 803 | // <3=> Green 804 | // <4=> Yellow 805 | // <5=> Blue 806 | // <6=> Magenta 807 | // <7=> Cyan 808 | // <8=> White 809 | 810 | #ifndef NRF_LOG_COLOR_DEFAULT 811 | #define NRF_LOG_COLOR_DEFAULT 0 812 | #endif 813 | 814 | // NRF_LOG_ERROR_COLOR - ANSI escape code prefix. 815 | 816 | // <0=> Default 817 | // <1=> Black 818 | // <2=> Red 819 | // <3=> Green 820 | // <4=> Yellow 821 | // <5=> Blue 822 | // <6=> Magenta 823 | // <7=> Cyan 824 | // <8=> White 825 | 826 | #ifndef NRF_LOG_ERROR_COLOR 827 | #define NRF_LOG_ERROR_COLOR 0 828 | #endif 829 | 830 | // NRF_LOG_WARNING_COLOR - ANSI escape code prefix. 831 | 832 | // <0=> Default 833 | // <1=> Black 834 | // <2=> Red 835 | // <3=> Green 836 | // <4=> Yellow 837 | // <5=> Blue 838 | // <6=> Magenta 839 | // <7=> Cyan 840 | // <8=> White 841 | 842 | #ifndef NRF_LOG_WARNING_COLOR 843 | #define NRF_LOG_WARNING_COLOR 0 844 | #endif 845 | 846 | #endif //NRF_LOG_USES_COLORS 847 | // 848 | 849 | // NRF_LOG_DEFAULT_LEVEL - Default Severity level 850 | 851 | // <0=> Off 852 | // <1=> Error 853 | // <2=> Warning 854 | // <3=> Info 855 | // <4=> Debug 856 | 857 | #ifndef NRF_LOG_DEFAULT_LEVEL 858 | #define NRF_LOG_DEFAULT_LEVEL 3 859 | #endif 860 | 861 | // NRF_LOG_DEFERRED - Enable deffered logger. 862 | 863 | // Log data is buffered and can be processed in idle. 864 | //========================================================== 865 | #ifndef NRF_LOG_DEFERRED 866 | #define NRF_LOG_DEFERRED 1 867 | #endif 868 | #if NRF_LOG_DEFERRED 869 | // NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words. 870 | // Must be power of 2 871 | 872 | #ifndef NRF_LOG_DEFERRED_BUFSIZE 873 | #define NRF_LOG_DEFERRED_BUFSIZE 256 874 | #endif 875 | 876 | #endif //NRF_LOG_DEFERRED 877 | // 878 | 879 | // NRF_LOG_USES_TIMESTAMP - Enable timestamping 880 | 881 | 882 | // Function for getting the timestamp is provided by the user 883 | 884 | #ifndef NRF_LOG_USES_TIMESTAMP 885 | #define NRF_LOG_USES_TIMESTAMP 0 886 | #endif 887 | 888 | #endif //NRF_LOG_ENABLED 889 | // 890 | 891 | // nrf_log_backend - Logging sink 892 | 893 | //========================================================== 894 | // NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string 895 | // Logger backend RAM usage is determined by this value. 896 | 897 | #ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH 898 | #define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256 899 | #endif 900 | 901 | // NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp 902 | // If higher resolution timestamp source is used it might be needed to increase that 903 | 904 | #ifndef NRF_LOG_TIMESTAMP_DIGITS 905 | #define NRF_LOG_TIMESTAMP_DIGITS 8 906 | #endif 907 | 908 | // NRF_LOG_BACKEND_SERIAL_USES_UART - If enabled data is printed over UART 909 | //========================================================== 910 | #ifndef NRF_LOG_BACKEND_SERIAL_USES_UART 911 | #define NRF_LOG_BACKEND_SERIAL_USES_UART 0 912 | #endif 913 | #if NRF_LOG_BACKEND_SERIAL_USES_UART 914 | // NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE - Default Baudrate 915 | 916 | // <323584=> 1200 baud 917 | // <643072=> 2400 baud 918 | // <1290240=> 4800 baud 919 | // <2576384=> 9600 baud 920 | // <3862528=> 14400 baud 921 | // <5152768=> 19200 baud 922 | // <7716864=> 28800 baud 923 | // <10289152=> 38400 baud 924 | // <15400960=> 57600 baud 925 | // <20615168=> 76800 baud 926 | // <30801920=> 115200 baud 927 | // <61865984=> 230400 baud 928 | // <67108864=> 250000 baud 929 | // <121634816=> 460800 baud 930 | // <251658240=> 921600 baud 931 | // <268435456=> 57600 baud 932 | 933 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 934 | #define NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 30801920 935 | #endif 936 | 937 | // NRF_LOG_BACKEND_SERIAL_UART_TX_PIN - UART TX pin 938 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 939 | #define NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 6 940 | #endif 941 | 942 | // NRF_LOG_BACKEND_SERIAL_UART_RX_PIN - UART RX pin 943 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 944 | #define NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 8 945 | #endif 946 | 947 | // NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN - UART RTS pin 948 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 949 | #define NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 5 950 | #endif 951 | 952 | // NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN - UART CTS pin 953 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 954 | #define NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 7 955 | #endif 956 | 957 | // NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL - Hardware Flow Control 958 | 959 | // <0=> Disabled 960 | // <1=> Enabled 961 | 962 | #ifndef NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 963 | #define NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 0 964 | #endif 965 | 966 | // NRF_LOG_BACKEND_UART_INSTANCE - UART instance used 967 | 968 | // <0=> 0 969 | 970 | #ifndef NRF_LOG_BACKEND_UART_INSTANCE 971 | #define NRF_LOG_BACKEND_UART_INSTANCE 0 972 | #endif 973 | 974 | #endif //NRF_LOG_BACKEND_SERIAL_USES_UART 975 | // 976 | 977 | // NRF_LOG_BACKEND_SERIAL_USES_RTT - If enabled data is printed using RTT 978 | //========================================================== 979 | #ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT 980 | #define NRF_LOG_BACKEND_SERIAL_USES_RTT 1 981 | #endif 982 | #if NRF_LOG_BACKEND_SERIAL_USES_RTT 983 | // NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE - RTT output buffer size. 984 | // Should be equal or bigger than \ref NRF_LOG_BACKEND_MAX_STRING_LENGTH. 985 | // This value is used in Segger RTT configuration to set the buffer size 986 | // if it is bigger than default RTT buffer size. 987 | 988 | #ifndef NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 989 | #define NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 512 990 | #endif 991 | 992 | #endif //NRF_LOG_BACKEND_SERIAL_USES_RTT 993 | // 994 | 995 | // 996 | //========================================================== 997 | 998 | // 999 | //========================================================== 1000 | 1001 | // nRF_Segger_RTT 1002 | 1003 | //========================================================== 1004 | // segger_rtt - SEGGER RTT 1005 | 1006 | //========================================================== 1007 | // SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. 1008 | // Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 1009 | // or this value is actually used. It depends on which one is bigger. 1010 | 1011 | #ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 1012 | #define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 64 1013 | #endif 1014 | 1015 | // SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer. 1016 | #ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 1017 | #define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 1018 | #endif 1019 | 1020 | // SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer. 1021 | #ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 1022 | #define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 1023 | #endif 1024 | 1025 | // SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer. 1026 | #ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 1027 | #define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 1028 | #endif 1029 | 1030 | // SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full. 1031 | 1032 | 1033 | // The following modes are supported: 1034 | // - SKIP - Do not block, output nothing. 1035 | // - TRIM - Do not block, output as much as fits. 1036 | // - BLOCK - Wait until there is space in the buffer. 1037 | // <0=> SKIP 1038 | // <1=> TRIM 1039 | // <2=> BLOCK_IF_FIFO_FULL 1040 | 1041 | #ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE 1042 | #define SEGGER_RTT_CONFIG_DEFAULT_MODE 0 1043 | #endif 1044 | 1045 | // 1046 | //========================================================== 1047 | 1048 | // 1049 | //========================================================== 1050 | 1051 | 1052 | // PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver 1053 | //========================================================== 1054 | #ifndef PWM_ENABLED 1055 | #define PWM_ENABLED 1 1056 | #endif 1057 | #if PWM_ENABLED 1058 | // PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin <0-31> 1059 | 1060 | 1061 | #ifndef PWM_DEFAULT_CONFIG_OUT0_PIN 1062 | #define PWM_DEFAULT_CONFIG_OUT0_PIN 31 1063 | #endif 1064 | 1065 | // PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin <0-31> 1066 | 1067 | 1068 | #ifndef PWM_DEFAULT_CONFIG_OUT1_PIN 1069 | #define PWM_DEFAULT_CONFIG_OUT1_PIN 31 1070 | #endif 1071 | 1072 | // PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin <0-31> 1073 | 1074 | 1075 | #ifndef PWM_DEFAULT_CONFIG_OUT2_PIN 1076 | #define PWM_DEFAULT_CONFIG_OUT2_PIN 31 1077 | #endif 1078 | 1079 | // PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin <0-31> 1080 | 1081 | 1082 | #ifndef PWM_DEFAULT_CONFIG_OUT3_PIN 1083 | #define PWM_DEFAULT_CONFIG_OUT3_PIN 31 1084 | #endif 1085 | 1086 | // PWM_DEFAULT_CONFIG_BASE_CLOCK - Base clock 1087 | 1088 | // <0=> 16 MHz 1089 | // <1=> 8 MHz 1090 | // <2=> 4 MHz 1091 | // <3=> 2 MHz 1092 | // <4=> 1 MHz 1093 | // <5=> 500 kHz 1094 | // <6=> 250 kHz 1095 | // <7=> 125 MHz 1096 | 1097 | #ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK 1098 | #define PWM_DEFAULT_CONFIG_BASE_CLOCK 4 1099 | #endif 1100 | 1101 | // PWM_DEFAULT_CONFIG_COUNT_MODE - Count mode 1102 | 1103 | // <0=> Up 1104 | // <1=> Up and Down 1105 | 1106 | #ifndef PWM_DEFAULT_CONFIG_COUNT_MODE 1107 | #define PWM_DEFAULT_CONFIG_COUNT_MODE 0 1108 | #endif 1109 | 1110 | // PWM_DEFAULT_CONFIG_TOP_VALUE - Top value 1111 | #ifndef PWM_DEFAULT_CONFIG_TOP_VALUE 1112 | #define PWM_DEFAULT_CONFIG_TOP_VALUE 20000 1113 | #endif 1114 | 1115 | // PWM_DEFAULT_CONFIG_LOAD_MODE - Load mode 1116 | 1117 | // <0=> Common 1118 | // <1=> Grouped 1119 | // <2=> Individual 1120 | // <3=> Waveform 1121 | 1122 | #ifndef PWM_DEFAULT_CONFIG_LOAD_MODE 1123 | #define PWM_DEFAULT_CONFIG_LOAD_MODE 0 1124 | #endif 1125 | 1126 | // PWM_DEFAULT_CONFIG_STEP_MODE - Step mode 1127 | 1128 | // <0=> Auto 1129 | // <1=> Triggered 1130 | 1131 | #ifndef PWM_DEFAULT_CONFIG_STEP_MODE 1132 | #define PWM_DEFAULT_CONFIG_STEP_MODE 0 1133 | #endif 1134 | 1135 | // PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority 1136 | 1137 | 1138 | // Priorities 0,1,4,5 (nRF52) are reserved for SoftDevice 1139 | // <0=> 0 (highest) 1140 | // <1=> 1 1141 | // <2=> 2 1142 | // <3=> 3 1143 | // <4=> 4 1144 | // <5=> 5 1145 | // <6=> 6 1146 | // <7=> 7 1147 | 1148 | #ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY 1149 | #define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 7 1150 | #endif 1151 | 1152 | // PWM0_ENABLED - Enable PWM0 instance 1153 | 1154 | 1155 | #ifndef PWM0_ENABLED 1156 | #define PWM0_ENABLED 1 1157 | #endif 1158 | 1159 | // PWM1_ENABLED - Enable PWM1 instance 1160 | 1161 | 1162 | #ifndef PWM1_ENABLED 1163 | #define PWM1_ENABLED 0 1164 | #endif 1165 | 1166 | // PWM2_ENABLED - Enable PWM2 instance 1167 | 1168 | 1169 | #ifndef PWM2_ENABLED 1170 | #define PWM2_ENABLED 0 1171 | #endif 1172 | 1173 | // PWM_CONFIG_LOG_ENABLED - Enables logging in the module. 1174 | //========================================================== 1175 | #ifndef PWM_CONFIG_LOG_ENABLED 1176 | #define PWM_CONFIG_LOG_ENABLED 0 1177 | #endif 1178 | #if PWM_CONFIG_LOG_ENABLED 1179 | // PWM_CONFIG_LOG_LEVEL - Default Severity level 1180 | 1181 | // <0=> Off 1182 | // <1=> Error 1183 | // <2=> Warning 1184 | // <3=> Info 1185 | // <4=> Debug 1186 | 1187 | #ifndef PWM_CONFIG_LOG_LEVEL 1188 | #define PWM_CONFIG_LOG_LEVEL 3 1189 | #endif 1190 | 1191 | // PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. 1192 | 1193 | // <0=> Default 1194 | // <1=> Black 1195 | // <2=> Red 1196 | // <3=> Green 1197 | // <4=> Yellow 1198 | // <5=> Blue 1199 | // <6=> Magenta 1200 | // <7=> Cyan 1201 | // <8=> White 1202 | 1203 | #ifndef PWM_CONFIG_INFO_COLOR 1204 | #define PWM_CONFIG_INFO_COLOR 0 1205 | #endif 1206 | 1207 | // PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 1208 | 1209 | // <0=> Default 1210 | // <1=> Black 1211 | // <2=> Red 1212 | // <3=> Green 1213 | // <4=> Yellow 1214 | // <5=> Blue 1215 | // <6=> Magenta 1216 | // <7=> Cyan 1217 | // <8=> White 1218 | 1219 | #ifndef PWM_CONFIG_DEBUG_COLOR 1220 | #define PWM_CONFIG_DEBUG_COLOR 0 1221 | #endif 1222 | 1223 | #endif //PWM_CONFIG_LOG_ENABLED 1224 | // 1225 | 1226 | // PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround for PWM. 1227 | 1228 | // The workaround uses interrupts to wake up the CPU and ensure 1229 | // it is active when PWM is about to start a DMA transfer. For 1230 | // initial transfer, done when a playback is started via PPI, 1231 | // a specific EGU instance is used to generate the interrupt. 1232 | // During the playback, the PWM interrupt triggered on SEQEND 1233 | // event of a preceding sequence is used to protect the transfer 1234 | // done for the next sequence to be played. 1235 | //========================================================== 1236 | #ifndef PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1237 | #define PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1 1238 | #endif 1239 | #if PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1240 | // PWM_NRF52_ANOMALY_109_EGU_INSTANCE - EGU instance used by the nRF52 Anomaly 109 workaround for PWM. 1241 | 1242 | // <0=> EGU0 1243 | // <1=> EGU1 1244 | // <2=> EGU2 1245 | // <3=> EGU3 1246 | // <4=> EGU4 1247 | // <5=> EGU5 1248 | 1249 | #ifndef PWM_NRF52_ANOMALY_109_EGU_INSTANCE 1250 | #define PWM_NRF52_ANOMALY_109_EGU_INSTANCE 5 1251 | #endif 1252 | 1253 | #endif //PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1254 | // 1255 | 1256 | #endif //PWM_ENABLED 1257 | // 1258 | 1259 | // BUTTON_ENABLED - app_button - buttons handling module 1260 | 1261 | #ifndef BUTTON_ENABLED 1262 | #define BUTTON_ENABLED 1 1263 | #endif 1264 | 1265 | //========================================================== 1266 | // GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver 1267 | //========================================================== 1268 | #ifndef GPIOTE_ENABLED 1269 | #define GPIOTE_ENABLED 1 1270 | #endif 1271 | #if GPIOTE_ENABLED 1272 | // GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins 1273 | #ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1274 | #define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 3 1275 | #endif 1276 | 1277 | // GPIOTE_CONFIG_IRQ_PRIORITY - Interrupt priority 1278 | 1279 | 1280 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 1281 | // <0=> 0 (highest) 1282 | // <1=> 1 1283 | // <2=> 2 1284 | // <3=> 3 1285 | // <4=> 4 1286 | // <5=> 5 1287 | // <6=> 6 1288 | // <7=> 7 1289 | 1290 | #ifndef GPIOTE_CONFIG_IRQ_PRIORITY 1291 | #define GPIOTE_CONFIG_IRQ_PRIORITY 7 1292 | #endif 1293 | 1294 | // GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module. 1295 | //========================================================== 1296 | #ifndef GPIOTE_CONFIG_LOG_ENABLED 1297 | #define GPIOTE_CONFIG_LOG_ENABLED 1 1298 | #endif 1299 | #if GPIOTE_CONFIG_LOG_ENABLED 1300 | // GPIOTE_CONFIG_LOG_LEVEL - Default Severity level 1301 | 1302 | // <0=> Off 1303 | // <1=> Error 1304 | // <2=> Warning 1305 | // <3=> Info 1306 | // <4=> Debug 1307 | 1308 | #ifndef GPIOTE_CONFIG_LOG_LEVEL 1309 | #define GPIOTE_CONFIG_LOG_LEVEL 4 1310 | #endif 1311 | 1312 | // GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix. 1313 | 1314 | // <0=> Default 1315 | // <1=> Black 1316 | // <2=> Red 1317 | // <3=> Green 1318 | // <4=> Yellow 1319 | // <5=> Blue 1320 | // <6=> Magenta 1321 | // <7=> Cyan 1322 | // <8=> White 1323 | 1324 | #ifndef GPIOTE_CONFIG_INFO_COLOR 1325 | #define GPIOTE_CONFIG_INFO_COLOR 0 1326 | #endif 1327 | 1328 | // GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. 1329 | 1330 | // <0=> Default 1331 | // <1=> Black 1332 | // <2=> Red 1333 | // <3=> Green 1334 | // <4=> Yellow 1335 | // <5=> Blue 1336 | // <6=> Magenta 1337 | // <7=> Cyan 1338 | // <8=> White 1339 | 1340 | #ifndef GPIOTE_CONFIG_DEBUG_COLOR 1341 | #define GPIOTE_CONFIG_DEBUG_COLOR 0 1342 | #endif 1343 | 1344 | #endif //GPIOTE_CONFIG_LOG_ENABLED 1345 | // 1346 | 1347 | #endif //GPIOTE_ENABLED 1348 | // 1349 | 1350 | // APP_TIMER_ENABLED - app_timer - Application timer functionality 1351 | //========================================================== 1352 | #ifndef APP_TIMER_ENABLED 1353 | #define APP_TIMER_ENABLED 1 1354 | #endif 1355 | #if APP_TIMER_ENABLED 1356 | // APP_TIMER_CONFIG_RTC_FREQUENCY - Configure RTC prescaler. 1357 | 1358 | // <0=> 32768 Hz 1359 | // <1=> 16384 Hz 1360 | // <3=> 8192 Hz 1361 | // <7=> 4096 Hz 1362 | // <15=> 2048 Hz 1363 | // <31=> 1024 Hz 1364 | 1365 | #ifndef APP_TIMER_CONFIG_RTC_FREQUENCY 1366 | #define APP_TIMER_CONFIG_RTC_FREQUENCY 0 1367 | #endif 1368 | 1369 | // APP_TIMER_CONFIG_IRQ_PRIORITY - Interrupt priority 1370 | 1371 | 1372 | // Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice 1373 | // <0=> 0 (highest) 1374 | // <1=> 1 1375 | // <2=> 2 1376 | // <3=> 3 1377 | // <4=> 4 1378 | // <5=> 5 1379 | // <6=> 6 1380 | // <7=> 7 1381 | 1382 | #ifndef APP_TIMER_CONFIG_IRQ_PRIORITY 1383 | #define APP_TIMER_CONFIG_IRQ_PRIORITY 7 1384 | #endif 1385 | 1386 | // APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. 1387 | // Size of the queue depends on how many timers are used 1388 | // in the system, how often timers are started and overall 1389 | // system latency. If queue size is too small app_timer calls 1390 | // will fail. 1391 | 1392 | #ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE 1393 | #define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10 1394 | #endif 1395 | 1396 | // APP_TIMER_CONFIG_USE_SCHEDULER - Enable scheduling app_timer events to app_scheduler 1397 | 1398 | 1399 | #ifndef APP_TIMER_CONFIG_USE_SCHEDULER 1400 | #define APP_TIMER_CONFIG_USE_SCHEDULER 0 1401 | #endif 1402 | 1403 | // APP_TIMER_WITH_PROFILER - Enable app_timer profiling 1404 | 1405 | 1406 | #ifndef APP_TIMER_WITH_PROFILER 1407 | #define APP_TIMER_WITH_PROFILER 0 1408 | #endif 1409 | 1410 | // APP_TIMER_KEEPS_RTC_ACTIVE - Enable RTC always on 1411 | 1412 | 1413 | // If option is enabled RTC is kept running even if there is no active timers. 1414 | // This option can be used when app_timer is used for timestamping. 1415 | 1416 | #ifndef APP_TIMER_KEEPS_RTC_ACTIVE 1417 | #define APP_TIMER_KEEPS_RTC_ACTIVE 1 1418 | #endif 1419 | 1420 | // APP_TIMER_CONFIG_SWI_NUMBER - Configure SWI instance used. 1421 | 1422 | // <0=> 0 1423 | // <1=> 1 1424 | 1425 | #ifndef APP_TIMER_CONFIG_SWI_NUMBER 1426 | #define APP_TIMER_CONFIG_SWI_NUMBER 1 1427 | #endif 1428 | 1429 | #endif //APP_TIMER_ENABLED 1430 | // 1431 | 1432 | // HARDFAULT_HANDLER_ENABLED - hardfault_default - HardFault default handler for debugging and release 1433 | 1434 | 1435 | #ifndef HARDFAULT_HANDLER_ENABLED 1436 | #define HARDFAULT_HANDLER_ENABLED 1 1437 | #endif 1438 | 1439 | // <<< end of configuration section >>> 1440 | #endif //SDK_CONFIG_H 1441 | 1442 | -------------------------------------------------------------------------------- /src/examples/tx/pca10056/blank/armgcc/Makefile: -------------------------------------------------------------------------------- 1 | # The PROJECT_NAME can be changed arbitrarily (it does not depend on anything). 2 | PROJECT_NAME := poly_tx 3 | 4 | SHAREDFLAGS := -DINVERT_L_X_AXIS=1 \ 5 | -DINVERT_R_Y_AXIS=1 6 | 7 | # The LINKER_SCRIPT is usually in the same directory as the Makefile. 8 | LINKER_SCRIPT := poly_tx_gcc_nrf52.ld 9 | 10 | BOARD := PCA10056 11 | 12 | DBG_BUILD_DIR := ./_debug 13 | REL_BUILD_DIR := ./_release 14 | DEPS_DIR := ./_deps 15 | 16 | SDK_ROOT := ../../../../../../../../.. 17 | PROJ_DIR := ../../.. 18 | 19 | # JLINK_MON_DEBUG_DIR should point to the directory that contains the files 20 | # in JLINK_MON_DEBUG_FILES plus JLINK_MONITOR.h. If Monitor Mode Debugging is 21 | # not required then leave JLINK_MON_DEBUG_DIR empty. 22 | JLINK_MON_DEBUG_DIR := 23 | 24 | # The offset of the application needs to be specified so the J-Link knows 25 | # the location of the DebugMon_Handler. For the S132 v4 this is 0x1F000. 26 | JLINK_MON_DEBUG_APP_FLASH_LOCATION := 0x00 27 | 28 | # If the JLINK_MON_DEBUG_DIR is empty then make sure it is evaluated correctly. 29 | JLINK_MON_DEBUG_DIR := $(strip $(JLINK_MON_DEBUG_DIR)) 30 | 31 | # These are the required files as of version 6.12a of the J-Link driver. 32 | JLINK_MON_DEBUG_FILES := JLINK_MONITOR.c JLINK_MONITOR_ISR_SES.s 33 | 34 | # Init commands will be written to a file and then specified when starting GDB 35 | # instead of relying on .gdbinit (to avoid having to enable .gbdinit files). 36 | GDB_CMD_PATH := $(DBG_BUILD_DIR)/gdb.txt 37 | 38 | # Include the correct template Makefile depending on platform. 39 | TEMPLATE_PATH = $(SDK_ROOT)/components/toolchain/gcc 40 | ifeq ($(OS),Windows_NT) 41 | include $(TEMPLATE_PATH)/Makefile.windows 42 | # The Windows command shell 'start' function is used so the executable 43 | # is started in its own window. 44 | TERMINAL := cmd /c start "" 45 | TERMINAL_END := 46 | NRFJPROG := nrfjprog.exe 47 | GDBSERVER := JLinkGDBServerCL.exe 48 | RTT_CLIENT := JLinkRTTClient.exe 49 | else 50 | include $(TEMPLATE_PATH)/Makefile.posix 51 | TERMINAL := gnome-terminal -e " 52 | TERMINAL_END := " 53 | NRFJPROG := nrfjprog 54 | GDBSERVER := JLinkGDBServer 55 | RTT_CLIENT := JLinkRTTClient 56 | endif 57 | 58 | # If multiple J-Links are attached to the computer then "SN=1234" can be used 59 | # to specify a serial number for GDB and flash targets. A random GDB port will 60 | # be generated so multiple targets can be debugged simultaneously. 61 | GDB_PORT := 2331 62 | ifdef SN 63 | NRFJPROG_SN := --snr $(SN) 64 | GDB_SERVER_SN := -select usb=$(SN) 65 | GDB_PORT := $(shell awk 'BEGIN{srand();printf("%4.4s", 1000+9999*rand())}') 66 | endif 67 | 68 | # Toolchain commands (these rely on the inclusion of the template Makefile) 69 | CC := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc 70 | AS := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as 71 | AR := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar -r 72 | LD := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld 73 | NM := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm 74 | OBJDUMP := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump 75 | OBJCOPY := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy 76 | SIZE := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size 77 | GDB := $(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gdb 78 | 79 | SHAREDFLAGS += \ 80 | -mcpu=cortex-m4 \ 81 | -mthumb \ 82 | -DNRF52840_XXAA \ 83 | -DCONFIG_GPIO_AS_PINRESET \ 84 | -DBOARD_$(BOARD) \ 85 | -DNRF52_PAN_74 \ 86 | -DBSP_DEFINES_ONLY \ 87 | -DESB_PRESENT 88 | 89 | CFLAGS += \ 90 | --std=gnu99 \ 91 | -Wall \ 92 | -Werror \ 93 | -mfloat-abi=hard \ 94 | -mfpu=fpv4-sp-d16 \ 95 | -ffunction-sections \ 96 | -fdata-sections \ 97 | -fno-strict-aliasing \ 98 | -fno-builtin \ 99 | --short-enums \ 100 | -mabi=aapcs \ 101 | $(SHAREDFLAGS) 102 | 103 | ASMFLAGS += \ 104 | -x assembler-with-cpp \ 105 | $(SHAREDFLAGS) 106 | 107 | LDFLAGS += \ 108 | -mthumb \ 109 | -mabi=aapcs \ 110 | -L $(TEMPLATE_PATH) \ 111 | -T$(LINKER_SCRIPT) \ 112 | -mcpu=cortex-m4 \ 113 | -mfloat-abi=hard \ 114 | -mfpu=fpv4-sp-d16 \ 115 | -Wl,--gc-sections \ 116 | --specs=nano.specs \ 117 | -lc \ 118 | -lnosys 119 | 120 | SRC_FILES += \ 121 | $(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \ 122 | $(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \ 123 | $(SDK_ROOT)/components/boards/boards.c \ 124 | $(SDK_ROOT)/components/libraries/util/app_error.c \ 125 | $(SDK_ROOT)/components/libraries/util/app_error_weak.c \ 126 | $(SDK_ROOT)/components/libraries/util/app_util_platform.c \ 127 | $(SDK_ROOT)/components/libraries/util/nrf_assert.c \ 128 | $(SDK_ROOT)/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c \ 129 | $(SDK_ROOT)/components/libraries/experimental_section_vars/nrf_section_iter.c \ 130 | $(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \ 131 | $(SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \ 132 | $(SDK_ROOT)/components/drivers_nrf/power/nrf_drv_power.c \ 133 | $(SDK_ROOT)/components/drivers_nrf/ppi/nrf_drv_ppi.c \ 134 | $(SDK_ROOT)/components/drivers_nrf/saadc/nrf_drv_saadc.c \ 135 | $(SDK_ROOT)/components/drivers_nrf/timer/nrf_drv_timer.c \ 136 | $(SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \ 137 | $(SDK_ROOT)/components/drivers_nrf/hal/nrf_saadc.c \ 138 | $(PROJ_DIR)/main.c \ 139 | $(PROJ_DIR)/../common/sainsmart_joystick.c \ 140 | $(PROJ_DIR)/../../rc_radio.c \ 141 | $(PROJ_DIR)/../common/utility.c \ 142 | $(SDK_ROOT)/external/segger_rtt/RTT_Syscalls_GCC.c \ 143 | $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \ 144 | $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \ 145 | $(SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52840.S \ 146 | $(SDK_ROOT)/components/toolchain/system_nrf52840.c \ 147 | $(SDK_ROOT)/components/drivers_nrf/pwm/nrf_drv_pwm.c \ 148 | $(SDK_ROOT)/components/proprietary_rf/esb/nrf_esb.c \ 149 | $(SDK_ROOT)/components/libraries/button/app_button.c \ 150 | $(SDK_ROOT)/components/libraries/timer/app_timer.c \ 151 | $(SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c 152 | 153 | INC_DIRS += \ 154 | $(SDK_ROOT)/components \ 155 | $(PROJ_DIR) \ 156 | $(PROJ_DIR)/../common \ 157 | $(PROJ_DIR)/../.. \ 158 | $(SDK_ROOT)/components/libraries/pwr_mgmt \ 159 | $(SDK_ROOT)/components/libraries/strerror \ 160 | $(SDK_ROOT)/components/drivers_nrf/delay \ 161 | $(SDK_ROOT)/components/toolchain/cmsis/include \ 162 | $(SDK_ROOT)/components/drivers_nrf/timer \ 163 | $(SDK_ROOT)/components/libraries/util \ 164 | $(SDK_ROOT)/components/drivers_nrf/uart \ 165 | $(SDK_ROOT)/components/libraries/bsp \ 166 | $(SDK_ROOT)/components/device \ 167 | $(SDK_ROOT)/external/segger_rtt \ 168 | $(SDK_ROOT)/components/libraries/log \ 169 | $(SDK_ROOT)/components/libraries/experimental_section_vars \ 170 | $(SDK_ROOT)/components/libraries/mutex \ 171 | $(SDK_ROOT)/components/drivers_nrf/saadc \ 172 | $(SDK_ROOT)/components/drivers_nrf/power \ 173 | $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \ 174 | ../config \ 175 | $(SDK_ROOT)/components/libraries/atomic \ 176 | $(SDK_ROOT)/components/boards \ 177 | $(SDK_ROOT)/components/drivers_nrf/hal \ 178 | $(SDK_ROOT)/components/toolchain/gcc \ 179 | $(SDK_ROOT)/components/toolchain \ 180 | $(SDK_ROOT)/components/drivers_nrf/common \ 181 | $(SDK_ROOT)/components/drivers_nrf/ppi \ 182 | $(SDK_ROOT)/components/libraries/log/src \ 183 | $(SDK_ROOT)/components/proprietary_rf/esb \ 184 | $(SDK_ROOT)/components/drivers_nrf/pwm \ 185 | $(SDK_ROOT)/components/libraries/button \ 186 | $(SDK_ROOT)/components/libraries/timer \ 187 | $(SDK_ROOT)/components/drivers_nrf/gpiote 188 | 189 | # The Monitor Mode debugging files will always be tracked by make if they are 190 | # used during debugging. They won't be passed to the linker for the release 191 | # version of the build. 192 | DBG_SRC_FILES := 193 | ifneq "$(JLINK_MON_DEBUG_DIR)" "" 194 | INC_DIRS += $(JLINK_MON_DEBUG_DIR) 195 | DBG_SRC_FILES += $(addprefix $(JLINK_MON_DEBUG_DIR)/, $(JLINK_MON_DEBUG_FILES)) 196 | else 197 | $(warning Define JLINK_MON_DEBUG_DIR to enable Monitor Mode Debugging.) 198 | endif 199 | 200 | ASSEMBLY_EXTS := s S 201 | 202 | # Convert to absolute paths and sort to remove duplicates. 203 | SRC_FILES := $(sort $(foreach f,$(SRC_FILES),$(abspath $(f)))) 204 | DBG_SRC_FILES := $(sort $(foreach f,$(DBG_SRC_FILES),$(abspath $(f)))) 205 | INC_DIRS := $(sort $(foreach d,$(INC_DIRS),$(abspath $(d)))) 206 | 207 | # Split the file paths into file names and directories. And remove duplicates. 208 | SRC_DIRS := $(sort $(dir $(SRC_FILES))) 209 | SRC_FILE_NAMES := $(notdir $(SRC_FILES)) 210 | DBG_SRC_DIRS := $(sort $(dir $(DBG_SRC_FILES))) 211 | DBG_SRC_FILE_NAMES := $(notdir $(DBG_SRC_FILES)) 212 | 213 | # Convert each source file name into the form '$(OBJ_DIR)/$(SRC_FILE).o'. 214 | OBJ := $(patsubst %,%.o,$(basename $(SRC_FILE_NAMES))) 215 | DBG_OBJ := $(patsubst %,%.o,$(basename $(DBG_SRC_FILE_NAMES))) 216 | DBG_OBJ := $(addprefix $(DBG_BUILD_DIR)/,$(OBJ) $(DBG_OBJ)) 217 | REL_OBJ := $(addprefix $(REL_BUILD_DIR)/,$(OBJ)) 218 | 219 | .PHONY: default 220 | default: CFLAGS += -O0 -ggdb -DDEBUG -DDEBUG_NRF 221 | default: OBJ_DIR := $(DBG_BUILD_DIR) 222 | default: $(DBG_BUILD_DIR)/$(PROJECT_NAME).hex 223 | $(call echosize,$(DBG_BUILD_DIR)/$(PROJECT_NAME).out) 224 | 225 | .PHONY: release 226 | release: CFLAGS += -O3 -g3 227 | release: OBJ_DIR := $(REL_BUILD_DIR) 228 | release: $(REL_BUILD_DIR)/$(PROJECT_NAME).bin $(REL_BUILD_DIR)/$(PROJECT_NAME).hex 229 | $(call echosize,$(REL_BUILD_DIR)/$(PROJECT_NAME).out) 230 | 231 | .PHONY: all 232 | all: default release 233 | 234 | DEPS := $(addprefix $(DEPS_DIR)/,$(OBJ:.o=.d)) 235 | -include $(DEPS) 236 | 237 | INCLUDES := $(patsubst %,-I%,$(INC_DIRS)) 238 | 239 | # Look for all source files in SRC_DIRS. 240 | vpath % $(SRC_DIRS) $(DBG_SRC_DIRS) 241 | 242 | define echosize 243 | @echo '' 244 | @'$(SIZE)' $1; 245 | @echo '' 246 | endef 247 | 248 | define flash 249 | @"$(NRFJPROG)" $(NRFJPROG_SN) --program $1 -f nrf52 --sectorerase --verify 250 | @"$(NRFJPROG)" $(NRFJPROG_SN) --reset -f nrf52 251 | endef 252 | 253 | $(DBG_BUILD_DIR)/%.o: %.c | $(DBG_BUILD_DIR) 254 | @echo Compiling file: $(notdir $<) 255 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c -o $@ $< 256 | 257 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).hex: $(DBG_BUILD_DIR)/$(PROJECT_NAME).out 258 | @echo Creating hex file: $(notdir $@) 259 | @'$(OBJCOPY)' -O ihex $(DBG_BUILD_DIR)/$(PROJECT_NAME).out $@ 260 | 261 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).bin: $(DBG_BUILD_DIR)/$(PROJECT_NAME).out 262 | @echo Creating bin file: $(notdir $@) 263 | @'$(OBJCOPY)' -O binary $(DBG_BUILD_DIR)/$(PROJECT_NAME).out $@ 264 | 265 | $(DBG_BUILD_DIR)/$(PROJECT_NAME).out: $(DBG_OBJ) 266 | @echo Linking ELF file: $(notdir $@) 267 | @'$(CC)' $(LDFLAGS) $(DBG_OBJ) -lm -o $@ 268 | 269 | $(REL_BUILD_DIR)/%.o: %.c | $(REL_BUILD_DIR) 270 | @echo Compiling file: $(notdir $<) 271 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c -o $@ $< 272 | 273 | $(REL_BUILD_DIR)/$(PROJECT_NAME).hex: $(REL_BUILD_DIR)/$(PROJECT_NAME).out 274 | @echo Creating hex file: $(notdir $@) 275 | @'$(OBJCOPY)' -O ihex $(REL_BUILD_DIR)/$(PROJECT_NAME).out $@ 276 | 277 | $(REL_BUILD_DIR)/$(PROJECT_NAME).bin: $(REL_BUILD_DIR)/$(PROJECT_NAME).out 278 | @echo Creating bin file: $(notdir $@) 279 | @'$(OBJCOPY)' -O binary $(REL_BUILD_DIR)/$(PROJECT_NAME).out $@ 280 | 281 | $(REL_BUILD_DIR)/$(PROJECT_NAME).out: $(REL_OBJ) 282 | @echo Linking ELF file: $(notdir $@) 283 | @'$(CC)' $(LDFLAGS) $(REL_OBJ) -lm -o $@ 284 | 285 | $(DEPS_DIR)/%.d: %.c | $(DEPS_DIR) 286 | @echo Adding dependency for file: $(notdir $<) 287 | @echo -n "$(DBG_BUILD_DIR)/$(notdir $(<:.c=.o)) " > $@ 288 | @'$(CC)' $(CFLAGS) $(INCLUDES) -c $< -MM \ 289 | -MT $(REL_BUILD_DIR)/$(notdir $(<:.c=.o)) >> $@ 290 | 291 | # The eval command is used to create a different version of these targets for 292 | # each extension in the ASSEMBLY_EXTS list. 293 | define assembly_targets 294 | $$(DBG_BUILD_DIR)/%.o: %.$1 | $$(DBG_BUILD_DIR) 295 | @echo Compiling assembly file: $$(notdir $$<) 296 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c -o $$@ $$< 297 | 298 | $$(REL_BUILD_DIR)/%.o: %.$1 | $$(REL_BUILD_DIR) 299 | @echo Compiling assembly file: $$(notdir $$<) 300 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c -o $$@ $$< 301 | 302 | $$(DEPS_DIR)/%.d: %.$1 | $$(DEPS_DIR) 303 | @echo Adding dependency for file: $$(notdir $$<) 304 | @echo -n "$$(DBG_BUILD_DIR)/$$(notdir $$(<:.$1=.o)) " > $$@ 305 | @'$$(CC)' $$(ASMFLAGS) $$(INCLUDES) -c $$< -MM \ 306 | -MT $$(REL_BUILD_DIR)/$$(notdir $$(<:.$1=.o)) >> $$@ 307 | endef 308 | $(foreach EXT,$(ASSEMBLY_EXTS),$(eval $(call assembly_targets,$(EXT)))) 309 | 310 | $(DEPS_DIR) $(DBG_BUILD_DIR) $(REL_BUILD_DIR):; @mkdir $@ 311 | 312 | .PHONY: flash_debug 313 | flash_debug: default 314 | $(call flash,$(DBG_BUILD_DIR)/$(PROJECT_NAME).hex) 315 | 316 | .PHONY: flash_release 317 | flash_release: release 318 | $(call flash,$(REL_BUILD_DIR)/$(PROJECT_NAME).hex) 319 | 320 | .PHONY: gdb_cmd_file 321 | gdb_cmd_file: default 322 | @echo "target remote localhost:$(GDB_PORT)" > $(GDB_CMD_PATH) 323 | @echo "mon speed 10000" >> $(GDB_CMD_PATH) 324 | @echo "mon flash download=1" >> $(GDB_CMD_PATH) 325 | @echo "load $(DBG_BUILD_DIR)/$(PROJECT_NAME).out" >> $(GDB_CMD_PATH) 326 | @echo "break main" >> $(GDB_CMD_PATH) 327 | @echo "mon reset 0" >> $(GDB_CMD_PATH) 328 | @echo "c" >> $(GDB_CMD_PATH) 329 | 330 | .PHONY: gdb_mon_cmd_file 331 | gdb_mon_cmd_file: gdb_cmd_file 332 | @echo "mon exec SetMonModeDebug=1" >> $(GDB_CMD_PATH) 333 | @echo "mon exec SetMonModeVTableAddr=$(JLINK_MON_DEBUG_APP_FLASH_LOCATION)" >> $(GDB_CMD_PATH) 334 | 335 | .PHONY: gdb_cli 336 | gdb_cli: 337 | @$(TERMINAL) '$(GDBSERVER)' $(GDB_SERVER_SN) -device nrf52840_XXAA \ 338 | -if swd -port $(GDB_PORT) $(TERMINAL_END) 339 | @$(TERMINAL) '$(GDB)' $(DBG_BUILD_DIR)/$(PROJECT_NAME).out -x $(GDB_CMD_PATH) $(TERMINAL_END) 340 | 341 | .PHONY: rtt 342 | rtt: 343 | @$(TERMINAL) '$(RTT_CLIENT)' $(TERMINAL_END) 344 | 345 | .PHONY: gdb 346 | gdb: gdb_cmd_file gdb_cli 347 | 348 | .PHONY: gdb_mon 349 | gdb_mon: gdb_mon_cmd_file gdb_cli 350 | 351 | .PHONY: gdb_rtt 352 | gdb_rtt: gdb rtt 353 | 354 | .PHONY: gdb_mon_rtt 355 | gdb_mon_rtt: gdb_mon rtt 356 | 357 | .PHONY: clean 358 | clean: 359 | @rm -rf $(DBG_BUILD_DIR) 360 | @rm -rf $(REL_BUILD_DIR) 361 | @rm -rf $(DEPS_DIR) 362 | 363 | .PHONY: help 364 | help: 365 | @echo "The following targets are available:" 366 | @echo " (default) - Compile with debug flags" 367 | @echo " release - Compile with release flags" 368 | @echo " all - Compile debug and release targets" 369 | @echo " clean - Remove object and dependency directories" 370 | @echo " gdb [SN=1234] - Perform debug compile and then launch gdb" 371 | @echo " gdb_rtt [SN=1234] - Call gdb target and then open RTT Client" 372 | ifneq "$(JLINK_MON_DEBUG_DIR)" "" 373 | @echo " gdb_mon [SN=1234] - Enable Monitor Mode Debugging" 374 | @echo " gdb_mon_rtt [SN=1234] - Enable Mon Debugging and open RTT Client" 375 | endif 376 | @echo " flash_debug [SN=1234] - Flash the debug build" 377 | @echo " flash_release [SN=1234]- Flash the release build" 378 | 379 | # This is a special target that tells make to delete a file if an error occurs 380 | # while the file is being generated. 381 | .DELETE_ON_ERROR: 382 | -------------------------------------------------------------------------------- /src/examples/tx/pca10056/blank/armgcc/poly_tx_gcc_nrf52.ld: -------------------------------------------------------------------------------- 1 | /* Linker script to configure memory regions. */ 2 | 3 | SEARCH_DIR(.) 4 | GROUP(-lgcc -lc -lnosys) 5 | 6 | MEMORY 7 | { 8 | FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x100000 9 | RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 10 | } 11 | 12 | SECTIONS 13 | { 14 | .fs_data : 15 | { 16 | PROVIDE(__start_fs_data = .); 17 | KEEP(*(.fs_data)) 18 | PROVIDE(__stop_fs_data = .); 19 | } > RAM 20 | } INSERT AFTER .data; 21 | 22 | SECTIONS 23 | { 24 | .pwr_mgmt_data : 25 | { 26 | PROVIDE(__start_pwr_mgmt_data = .); 27 | KEEP(*(SORT(.pwr_mgmt_data*))) 28 | PROVIDE(__stop_pwr_mgmt_data = .); 29 | } > FLASH 30 | } INSERT AFTER .text 31 | 32 | INCLUDE "nrf5x_common.ld" 33 | -------------------------------------------------------------------------------- /src/rc_radio.c: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | #include "nrf_esb.h" 4 | #include "app_error.h" 5 | #include "nrf_clock.h" 6 | #include "nrf_drv_timer.h" 7 | #include "nrf_gpio.h" 8 | 9 | #include "rc_radio.h" 10 | 11 | 12 | #define ENABLE_GPIO_DBG (1UL) 13 | #define GPIO_DBG_PIN_1 (26UL) 14 | #define GPIO_DBG_PIN_2 (27UL) 15 | 16 | #define BITRATE (1000000UL) 17 | #define ADDR_LEN (5UL) 18 | #define CHANNEL_MAP_LEN (10UL) 19 | #define BIND_CHANNEL (10UL) 20 | #define DATA_BUFF_COUNT (2UL) 21 | #define MIN_TX_RATE_HZ (10UL) 22 | #define MAX_TX_RATE_HZ (500UL) 23 | #define TIMER_ISR_PRIORITY (1UL) 24 | 25 | #define ADDR_BITS (ADDR_LEN * 8UL) 26 | #define DATA_BITS (sizeof(rc_radio_data_t) * 8UL) 27 | #define PREAMBLE_BITS (8UL) 28 | #define PCF_BITS (11UL) /* Packet Control Field from ESB */ 29 | #define CRC_BITS (16UL) 30 | #define PKT_OVERHEAD_BITS (PREAMBLE_BITS + PCF_BITS + CRC_BITS) 31 | 32 | #define CEILING(n,d) (((n) + (d) - 1) / (d)) 33 | #define LEN_US(x_bits) CEILING((x_bits * 10000000), (BITRATE*10)) 34 | 35 | #define PKT_LEN_US LEN_US(PKT_OVERHEAD_BITS + ADDR_BITS + DATA_BITS) 36 | #define OVERHEAD_US (300UL) /* Empirical, includes f.e. radio ramp up. */ 37 | #define RX_WIDENING_US (100UL) 38 | #define RX_SAFETY_US (100UL) 39 | 40 | 41 | typedef enum 42 | { 43 | RC_RADIO_STATE_DISABLED, 44 | RC_RADIO_STATE_ENABLED, 45 | RC_RADIO_STATE_BINDING, 46 | RC_RADIO_STATE_STARTED, 47 | RC_RADIO_STATE_COUNT 48 | } rc_radio_state_t; 49 | 50 | 51 | static const uint8_t 52 | BIND_ADDRESS[ADDR_LEN] = {0xAA, 0xBB, 0x55, 0xAA, 0x5A}; 53 | 54 | static const uint8_t 55 | CHANNEL_MAP[RC_RADIO_TRANSMITTER_CHANNEL_COUNT][CHANNEL_MAP_LEN] = { 56 | {0, 32, 62, 92, 22, 52, 82, 12, 42, 72}, 57 | {2, 34, 64, 94, 24, 54, 84, 14, 44, 74}, 58 | {4, 36, 66, 96, 26, 56, 86, 16, 46, 76}, 59 | {6, 38, 68, 98, 28, 58, 88, 18, 48, 78}, 60 | {8, 40, 70, 100, 30, 60, 90, 20, 50, 80} 61 | }; 62 | 63 | static const uint8_t 64 | ADDRESSES[RC_RADIO_TRANSMITTER_CHANNEL_COUNT][ADDR_LEN] = { 65 | {0xAA, 0xBB, 0xD5, 0x95, 0x55}, 66 | {0xAA, 0xBB, 0x6A, 0x4A, 0xAA}, 67 | {0xAA, 0xBB, 0xB5, 0x52, 0x5A}, 68 | {0xAA, 0xBB, 0xAD, 0xA9, 0xA5}, 69 | {0xAA, 0xBB, 0x56, 0x54, 0x2A} 70 | }; 71 | 72 | static const uint8_t 73 | BINDING_ACK_PAYLOAD[] = "RC_RADIO"; 74 | 75 | 76 | static nrf_esb_payload_t m_rx_payload; 77 | static nrf_esb_payload_t m_tx_payload; 78 | 79 | static nrf_esb_mode_t m_mode; 80 | static rc_radio_event_handler_t m_callback; 81 | static nrf_drv_timer_t m_timer; 82 | static bool m_hfclk_was_running; 83 | static uint8_t m_tx_data_index; 84 | static rc_radio_data_t m_tx_data[DATA_BUFF_COUNT]; 85 | 86 | static volatile rc_radio_state_t m_state=RC_RADIO_STATE_DISABLED; 87 | static volatile rc_radio_bind_info_t m_bind_info; 88 | static volatile uint32_t m_missed_packets; 89 | static volatile uint8_t m_channel_index; 90 | 91 | 92 | static uint32_t m_radio_start(void); 93 | 94 | 95 | static inline uint32_t m_channel_lookup(void) 96 | { 97 | return CHANNEL_MAP[m_bind_info.transmitter_channel][m_channel_index]; 98 | } 99 | 100 | 101 | static inline void m_channel_increment(void) 102 | { 103 | m_channel_index = ((m_channel_index + 1) % CHANNEL_MAP_LEN); 104 | } 105 | 106 | 107 | static inline uint32_t m_timer_interval_calc(void) 108 | { 109 | return (1000000UL / m_bind_info.transmit_rate_hz); 110 | } 111 | 112 | 113 | static inline uint32_t m_write_bind_info_pl(void) 114 | { 115 | m_tx_payload.length = sizeof(rc_radio_bind_info_t); 116 | m_tx_payload.noack = false; 117 | memcpy(m_tx_payload.data, 118 | (uint8_t*)&m_bind_info, 119 | sizeof(rc_radio_bind_info_t)); 120 | 121 | return nrf_esb_write_payload(&m_tx_payload); 122 | } 123 | 124 | 125 | static inline uint8_t m_write_ack_pl(void) 126 | { 127 | // Preload a particular ACK payload so the transmitter will know 128 | // that it's binding with a valid receiver. 129 | m_tx_payload.length = sizeof(BINDING_ACK_PAYLOAD); 130 | memcpy(m_tx_payload.data, 131 | BINDING_ACK_PAYLOAD, 132 | sizeof(BINDING_ACK_PAYLOAD)); 133 | 134 | return nrf_esb_write_payload(&m_tx_payload); 135 | } 136 | 137 | 138 | static void m_timer_handler(nrf_timer_event_t event_type, void * p_context) 139 | { 140 | #if ENABLE_GPIO_DBG 141 | nrf_gpio_pin_set(GPIO_DBG_PIN_1); 142 | #endif 143 | 144 | switch (event_type) 145 | { 146 | case NRF_TIMER_EVENT_COMPARE0: 147 | if (NRF_ESB_MODE_PTX == m_mode) 148 | { 149 | // Writing a payload starts the transmission immediately. 150 | if (RC_RADIO_STATE_BINDING == m_state) 151 | { 152 | uint32_t err_code = m_write_bind_info_pl(); 153 | 154 | if (NRF_ERROR_NO_MEM == err_code) 155 | { 156 | nrf_esb_flush_tx(); 157 | } 158 | else 159 | { 160 | APP_ERROR_CHECK(err_code); 161 | } 162 | } 163 | else 164 | { 165 | m_tx_payload.length = sizeof(rc_radio_data_t); 166 | m_tx_payload.noack = true; 167 | memcpy(&m_tx_payload.data[0], 168 | (uint8_t*)&m_tx_data[m_tx_data_index], 169 | sizeof(rc_radio_data_t)); 170 | APP_ERROR_CHECK(nrf_esb_write_payload(&m_tx_payload)); 171 | } 172 | } 173 | else 174 | { 175 | APP_ERROR_CHECK(nrf_esb_start_rx()); 176 | } 177 | break; 178 | case NRF_TIMER_EVENT_COMPARE2: 179 | #if ENABLE_GPIO_DBG 180 | nrf_gpio_pin_clear(GPIO_DBG_PIN_1); 181 | nrf_gpio_pin_set(GPIO_DBG_PIN_1); 182 | nrf_gpio_pin_clear(GPIO_DBG_PIN_1); 183 | nrf_gpio_pin_set(GPIO_DBG_PIN_1); 184 | #endif 185 | 186 | APP_ERROR_CHECK(nrf_esb_start_rx()); 187 | break; 188 | case NRF_TIMER_EVENT_COMPARE1: 189 | #if ENABLE_GPIO_DBG 190 | nrf_gpio_pin_clear(GPIO_DBG_PIN_1); 191 | nrf_gpio_pin_set(GPIO_DBG_PIN_1); 192 | #endif 193 | 194 | m_missed_packets++; 195 | 196 | if (RC_RADIO_MISSED_PACKET_TOLERANCE > m_missed_packets) 197 | { 198 | if (1 == m_missed_packets) 199 | { 200 | uint32_t ticks; 201 | 202 | ticks = nrf_drv_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL0); 203 | nrf_timer_cc_write(m_timer.p_reg, 204 | NRF_TIMER_CC_CHANNEL0, 205 | (ticks - RX_SAFETY_US)); 206 | 207 | ticks = nrf_drv_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL1); 208 | nrf_timer_cc_write(m_timer.p_reg, 209 | NRF_TIMER_CC_CHANNEL1, 210 | (ticks - RX_SAFETY_US)); 211 | } 212 | 213 | m_channel_increment(); 214 | 215 | APP_ERROR_CHECK(nrf_esb_stop_rx()); 216 | APP_ERROR_CHECK(nrf_esb_set_rf_channel(m_channel_lookup())); 217 | 218 | m_callback(RC_RADIO_EVENT_PACKET_DROPPED, NULL); 219 | } 220 | else 221 | { 222 | // The transmitter has gone away. 223 | nrf_drv_timer_disable(&m_timer); 224 | APP_ERROR_CHECK(nrf_esb_stop_rx()); 225 | 226 | m_callback(RC_RADIO_EVENT_PACKET_DROPPED, NULL); 227 | 228 | // NOTE: Calling m_esb_init seems like a good idea. Unfortunately, 229 | // that sometimes causes a situation where the receiver does 230 | // not appear to be properly enabled. 231 | APP_ERROR_CHECK(nrf_esb_set_base_address_0(BIND_ADDRESS)); 232 | APP_ERROR_CHECK(nrf_esb_set_prefixes(&BIND_ADDRESS[ADDR_LEN-1],1)); 233 | APP_ERROR_CHECK(nrf_esb_set_rf_channel(BIND_CHANNEL)); 234 | APP_ERROR_CHECK(m_write_ack_pl()); 235 | APP_ERROR_CHECK(nrf_esb_start_rx()); 236 | 237 | m_state = RC_RADIO_STATE_BINDING; 238 | m_callback(RC_RADIO_EVENT_BINDING, NULL); 239 | } 240 | break; 241 | default: 242 | break; 243 | } 244 | 245 | #if ENABLE_GPIO_DBG 246 | nrf_gpio_pin_clear(GPIO_DBG_PIN_1); 247 | #endif 248 | } 249 | 250 | 251 | static inline bool m_reciver_ackd(void) 252 | { 253 | if (sizeof(BINDING_ACK_PAYLOAD) != m_rx_payload.length) 254 | { 255 | return false; 256 | } 257 | 258 | return (0 == memcmp(m_rx_payload.data, 259 | BINDING_ACK_PAYLOAD, 260 | sizeof(BINDING_ACK_PAYLOAD))); 261 | } 262 | 263 | 264 | static inline void m_bind_info_received(void) 265 | { 266 | uint32_t interval_us; 267 | uint32_t ticks; 268 | const uint8_t *addr; 269 | rc_radio_bind_info_t *p_info; 270 | 271 | if (sizeof(rc_radio_bind_info_t) != m_rx_payload.length) 272 | { 273 | m_write_ack_pl(); 274 | return; 275 | } 276 | 277 | p_info = (rc_radio_bind_info_t*)m_rx_payload.data; 278 | 279 | if ((RC_RADIO_TRANSMITTER_CHANNEL_COUNT <= p_info->transmitter_channel) || 280 | (MIN_TX_RATE_HZ > p_info->transmit_rate_hz) || 281 | (MAX_TX_RATE_HZ < p_info->transmit_rate_hz)) 282 | { 283 | m_write_ack_pl(); 284 | return; 285 | } 286 | 287 | m_bind_info.transmitter_channel = p_info->transmitter_channel; 288 | m_bind_info.transmit_rate_hz = p_info->transmit_rate_hz; 289 | m_channel_index = 0; 290 | m_missed_packets = 0; 291 | 292 | // CC0 fires when it's time to put the radio into receiver mode. 293 | // If a packet is received then the timer is cleared. 294 | // 295 | // If no packet is received, CC1 moves the receiver to the next channel. 296 | 297 | interval_us = m_timer_interval_calc(); 298 | 299 | ticks = (interval_us + RX_SAFETY_US); 300 | nrf_drv_timer_extended_compare(&m_timer, 301 | NRF_TIMER_CC_CHANNEL1, 302 | ticks, 303 | NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, 304 | true); 305 | 306 | ticks = (interval_us - 307 | OVERHEAD_US - 308 | PKT_LEN_US - 309 | RX_WIDENING_US); 310 | nrf_drv_timer_compare(&m_timer, 311 | NRF_TIMER_CC_CHANNEL0, 312 | ticks, 313 | true); 314 | 315 | // Clear the events in case this is a re-binding event. 316 | nrf_timer_event_clear(m_timer.p_reg, NRF_TIMER_EVENT_COMPARE0); 317 | nrf_timer_event_clear(m_timer.p_reg, NRF_TIMER_EVENT_COMPARE1); 318 | 319 | nrf_drv_timer_enable(&m_timer); 320 | 321 | while (NRF_SUCCESS != nrf_esb_stop_rx()) 322 | { 323 | // The radio still needs to send an ACK payload. The ESB library 324 | // can't be disabled until this completes. In the meantime, 325 | // nrf_esb_stop_rx will return NRF_ESB_ERROR_NOT_IN_RX_MODE. 326 | // 327 | // NOTE: The NRF_ESB_EVENT_TX_SUCCESS event won't be received until 328 | // another packet is received from the transmitter. 329 | } 330 | 331 | addr = ADDRESSES[m_bind_info.transmitter_channel]; 332 | 333 | APP_ERROR_CHECK(nrf_esb_set_base_address_0(addr)); 334 | APP_ERROR_CHECK(nrf_esb_set_prefixes(&addr[ADDR_LEN - 1], 1)); 335 | APP_ERROR_CHECK(nrf_esb_set_rf_channel(m_channel_lookup())); 336 | 337 | m_state = RC_RADIO_STATE_STARTED; 338 | m_callback(RC_RADIO_EVENT_BOUND, (void*)&m_bind_info); 339 | } 340 | 341 | 342 | static inline void m_data_received(void) 343 | { 344 | if (sizeof(rc_radio_data_t) == m_rx_payload.length) 345 | { 346 | // Reset the timer to keep it in sync. 347 | nrf_drv_timer_clear(&m_timer); 348 | 349 | m_channel_increment(); 350 | 351 | APP_ERROR_CHECK(nrf_esb_stop_rx()); 352 | APP_ERROR_CHECK(nrf_esb_set_rf_channel(m_channel_lookup())); 353 | 354 | if (m_missed_packets) 355 | { 356 | uint32_t ticks; 357 | 358 | ticks = nrf_drv_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL0); 359 | nrf_timer_cc_write(m_timer.p_reg, 360 | NRF_TIMER_CC_CHANNEL0, 361 | (ticks + RX_SAFETY_US)); 362 | 363 | ticks = nrf_drv_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL1); 364 | nrf_timer_cc_write(m_timer.p_reg, 365 | NRF_TIMER_CC_CHANNEL1, 366 | (ticks + RX_SAFETY_US)); 367 | 368 | m_missed_packets = 0; 369 | } 370 | 371 | m_callback(RC_RADIO_EVENT_DATA_RECEIVED, m_rx_payload.data); 372 | } 373 | } 374 | 375 | 376 | static void m_nrf_esb_event_handler(nrf_esb_evt_t const * p_event) 377 | { 378 | #if ENABLE_GPIO_DBG 379 | nrf_gpio_pin_set(GPIO_DBG_PIN_2); 380 | #endif 381 | 382 | switch (p_event->evt_id) 383 | { 384 | case NRF_ESB_EVENT_TX_SUCCESS: 385 | // NOTE: The NRF_ESB_EVENT_TX_SUCCESS event will also be delivered for 386 | // the receiver when it gets a packet after ACK'ing the bind 387 | // packet. 388 | if (NRF_ESB_MODE_PTX == m_mode) 389 | { 390 | // NOTE: The NRF_ESB_EVENT_TX_SUCCESS event is delivered before 391 | // the NRF_ESB_EVENT_RX_RECEIVED event when binding. 392 | if (RC_RADIO_STATE_STARTED == m_state) 393 | { 394 | m_channel_increment(); 395 | nrf_esb_set_rf_channel(m_channel_lookup()); 396 | 397 | if (NULL != m_callback) 398 | { 399 | m_callback(RC_RADIO_EVENT_DATA_SENT, NULL); 400 | } 401 | } 402 | } 403 | break; 404 | case NRF_ESB_EVENT_TX_FAILED: 405 | nrf_esb_flush_tx(); 406 | break; 407 | case NRF_ESB_EVENT_RX_RECEIVED: 408 | APP_ERROR_CHECK(nrf_esb_read_rx_payload(&m_rx_payload)); 409 | if (NRF_ESB_MODE_PRX == m_mode) 410 | { 411 | if (RC_RADIO_STATE_BINDING == m_state) 412 | { 413 | m_bind_info_received(); 414 | } 415 | else 416 | { 417 | m_data_received(); 418 | } 419 | } 420 | else if (m_reciver_ackd()) 421 | { 422 | // A valid response to the bind packet was received so it's time 423 | // to move to the data address and channels. 424 | const uint8_t * addr = ADDRESSES[m_bind_info.transmitter_channel]; 425 | 426 | m_channel_index = 0; 427 | 428 | APP_ERROR_CHECK(nrf_esb_set_base_address_0(addr)); 429 | APP_ERROR_CHECK(nrf_esb_set_prefixes(&addr[ADDR_LEN - 1], 1)); 430 | APP_ERROR_CHECK(nrf_esb_set_tx_power(RC_RADIO_TX_POWER)); 431 | APP_ERROR_CHECK(nrf_esb_set_rf_channel(m_channel_lookup())); 432 | 433 | m_state = RC_RADIO_STATE_STARTED; 434 | if (NULL != m_callback) 435 | { 436 | m_callback(RC_RADIO_EVENT_BOUND, (void*)&m_bind_info); 437 | } 438 | } 439 | break; 440 | } 441 | 442 | #if ENABLE_GPIO_DBG 443 | nrf_gpio_pin_clear(GPIO_DBG_PIN_2); 444 | #endif 445 | } 446 | 447 | 448 | static uint32_t m_esb_init(void) 449 | { 450 | uint32_t err_code; 451 | 452 | nrf_esb_config_t nrf_esb_config = NRF_ESB_DEFAULT_CONFIG; 453 | nrf_esb_config.payload_length = sizeof(rc_radio_data_t); 454 | nrf_esb_config.bitrate = NRF_ESB_BITRATE_1MBPS; 455 | nrf_esb_config.mode = m_mode; 456 | nrf_esb_config.event_handler = m_nrf_esb_event_handler; 457 | nrf_esb_config.selective_auto_ack = true; 458 | nrf_esb_config.tx_output_power = RC_RADIO_BINDING_TX_POWER; 459 | nrf_esb_config.retransmit_count = 0; 460 | nrf_esb_config.radio_irq_priority = 0; 461 | nrf_esb_config.event_irq_priority = TIMER_ISR_PRIORITY; 462 | 463 | err_code = nrf_esb_init(&nrf_esb_config); 464 | if (NRF_SUCCESS != err_code) 465 | { 466 | return err_code; 467 | } 468 | 469 | err_code = nrf_esb_set_base_address_0(BIND_ADDRESS); 470 | if (NRF_SUCCESS != err_code) 471 | { 472 | return err_code; 473 | } 474 | 475 | err_code = nrf_esb_set_prefixes(&BIND_ADDRESS[ADDR_LEN - 1], 1); 476 | if (NRF_SUCCESS != err_code) 477 | { 478 | return err_code; 479 | } 480 | 481 | err_code = nrf_esb_set_rf_channel(BIND_CHANNEL); 482 | if (NRF_SUCCESS != err_code) 483 | { 484 | return err_code; 485 | } 486 | 487 | return NRF_SUCCESS; 488 | } 489 | 490 | 491 | static void m_clocks_start(void) 492 | { 493 | nrf_clock_hfclk_t clk_src = nrf_clock_hf_src_get(); 494 | 495 | m_hfclk_was_running = (NRF_CLOCK_HFCLK_HIGH_ACCURACY==clk_src); 496 | 497 | if (!m_hfclk_was_running) 498 | { 499 | NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; 500 | NRF_CLOCK->TASKS_HFCLKSTART = 1; 501 | 502 | while (0 == NRF_CLOCK->EVENTS_HFCLKSTARTED) 503 | { 504 | }; 505 | } 506 | } 507 | 508 | 509 | static void m_clocks_stop(void) 510 | { 511 | if (!m_hfclk_was_running) 512 | { 513 | NRF_CLOCK->TASKS_HFCLKSTOP = 1; 514 | 515 | while (NRF_CLOCK_HFCLK_HIGH_ACCURACY == nrf_clock_hf_src_get()) 516 | { 517 | }; 518 | } 519 | } 520 | 521 | 522 | static uint32_t m_radio_start(void) 523 | { 524 | uint32_t err_code; 525 | 526 | m_state = RC_RADIO_STATE_BINDING; 527 | 528 | if (NRF_ESB_MODE_PRX == m_mode) 529 | { 530 | err_code = m_esb_init(); 531 | if (NRF_SUCCESS != err_code) 532 | { 533 | return err_code; 534 | } 535 | 536 | err_code = m_write_ack_pl(); 537 | if (NRF_SUCCESS != err_code) 538 | { 539 | return err_code; 540 | } 541 | 542 | err_code = nrf_esb_start_rx(); 543 | if (NRF_SUCCESS != err_code) 544 | { 545 | return err_code; 546 | } 547 | } 548 | else 549 | { 550 | uint32_t delay_us = m_timer_interval_calc(); 551 | 552 | err_code = m_esb_init(); 553 | if (NRF_SUCCESS != err_code) 554 | { 555 | return err_code; 556 | } 557 | 558 | err_code = m_write_bind_info_pl(); 559 | if (NRF_SUCCESS != err_code) 560 | { 561 | return err_code; 562 | } 563 | 564 | nrf_drv_timer_extended_compare(&m_timer, 565 | NRF_TIMER_CC_CHANNEL0, 566 | delay_us, 567 | NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, 568 | true); 569 | nrf_drv_timer_enable(&m_timer); 570 | } 571 | 572 | if (NULL != m_callback) 573 | { 574 | m_callback(RC_RADIO_EVENT_BINDING, NULL); 575 | } 576 | 577 | return NRF_SUCCESS; 578 | } 579 | 580 | 581 | static uint32_t m_rc_radio_init(uint8_t timer_instance_index) 582 | { 583 | uint32_t err_code; 584 | nrf_drv_timer_config_t timer_cfg; 585 | 586 | timer_cfg.mode = TIMER_MODE_MODE_Timer; 587 | timer_cfg.frequency = NRF_TIMER_FREQ_1MHz; 588 | timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32; 589 | timer_cfg.interrupt_priority = TIMER_ISR_PRIORITY; 590 | 591 | // Only pipe 0 is used in this library. 592 | m_tx_payload.pipe = 0; 593 | 594 | if (RC_RADIO_STATE_DISABLED != m_state) 595 | { 596 | return NRF_ERROR_INVALID_STATE; 597 | } 598 | 599 | switch (timer_instance_index) 600 | { 601 | case 0: 602 | m_timer.p_reg = NRF_TIMER0; 603 | m_timer.instance_id = TIMER0_INSTANCE_INDEX; 604 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(0); 605 | break; 606 | case 1: 607 | m_timer.p_reg = NRF_TIMER1; 608 | m_timer.instance_id = TIMER1_INSTANCE_INDEX; 609 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(1); 610 | break; 611 | case 2: 612 | m_timer.p_reg = NRF_TIMER2; 613 | m_timer.instance_id = TIMER2_INSTANCE_INDEX; 614 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(2); 615 | break; 616 | case 3: 617 | m_timer.p_reg = NRF_TIMER3; 618 | m_timer.instance_id = TIMER3_INSTANCE_INDEX; 619 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(3); 620 | break; 621 | case 4: 622 | m_timer.p_reg = NRF_TIMER4; 623 | m_timer.instance_id = TIMER4_INSTANCE_INDEX; 624 | m_timer.cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(4); 625 | break; 626 | default: 627 | return NRF_ERROR_INVALID_PARAM; 628 | } 629 | 630 | #if ENABLE_GPIO_DBG 631 | nrf_gpio_cfg_output(GPIO_DBG_PIN_1); 632 | nrf_gpio_cfg_output(GPIO_DBG_PIN_2); 633 | nrf_gpio_pin_clear(GPIO_DBG_PIN_1); 634 | nrf_gpio_pin_clear(GPIO_DBG_PIN_2); 635 | #endif 636 | 637 | err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, m_timer_handler); 638 | if (NRF_SUCCESS != err_code) 639 | { 640 | return err_code; 641 | } 642 | 643 | return NRF_SUCCESS; 644 | } 645 | 646 | 647 | uint32_t rc_radio_transmitter_init(uint8_t timer_instance_index, 648 | uint16_t transmit_rate_hz, 649 | rc_radio_transmitter_channel_t channel, 650 | rc_radio_event_handler_t callback) 651 | { 652 | if ((MIN_TX_RATE_HZ>transmit_rate_hz) || (MAX_TX_RATE_HZ