이번 예제는 Radio Test 예제입니다.
Radio와 관련된 각종 세팅들을 UART를 통해서
간단히 설정하는 예제입니다.
main함수가 긴 관계로 잘라서 설명할께요.
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | int main(void) { uint32_t err_code; radio_tests_t test = RADIO_TEST_NOP; radio_tests_t cur_test = RADIO_TEST_NOP; init(); const app_uart_comm_params_t comm_params = { RX_PIN_NUMBER, TX_PIN_NUMBER, RTS_PIN_NUMBER, CTS_PIN_NUMBER, APP_UART_FLOW_CONTROL_ENABLED, false, UART_BAUDRATE_BAUDRATE_Baud38400 }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_error_handle, APP_IRQ_PRIORITY_LOW, err_code); APP_ERROR_CHECK(err_code); printf("RF Test\r\n"); NVIC_EnableIRQ(TIMER0_IRQn); __enable_irq(); | cs |
초기화 부분입니다.
Line 4~5 : radio_tests_t는 enum으로 선언되어 있는데 테스트 모드를 알려주기 위한 변수 같네요.
1 2 3 4 5 6 7 8 9 | typedef enum { RADIO_TEST_NOP, /**< No test running. */ RADIO_TEST_TXCC, /**< TX constant carrier. */ RADIO_TEST_TXMC, /**< TX modulated carrier. */ RADIO_TEST_TXSWEEP, /**< TX sweep. */ RADIO_TEST_RXC, /**< RX constant carrier. */ RADIO_TEST_RXSWEEP, /**< RX sweep. */ } radio_tests_t; | cs |
Line 7 : 클럭과 난수발생기를 작동시킵니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void init(void) { NRF_RNG->TASKS_START = 1; // Start 16 MHz crystal oscillator NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; // Wait for the external oscillator to start up while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { // Do nothing. } } | cs |
3 : 난수발생기를 동작시킵니다.
5~10 : HFCLK를 동작시킵니다.
Line 8~26 : uart 초기화 입니다.
Line 28~29 : Timer0 인터럽트를 enable 시킵니다.
Timer0 초기화와 인터럽트는 radio_test.c에 있습니다.(자세한건 뒤에서~)
이어서 main의 입력을 받는 부분입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | while (true) { uint8_t control; scanf("%c",&control); switch (control) { case 'a': while (true) { printf("Enter start channel \ (two decimal digits, 00 to 80):"); scanf("%d",&channel_start_); if ((channel_start_ <= 80)&&(channel_start_ >= 0)) { printf("%d\r\n", channel_start_); break; } printf("Channel must be between 0 and 80\r\n"); } test = cur_test; break; case 'b': while (true) { printf("Enter end channel \ (two decimal digits, 00 to 80):"); scanf("%d",&channel_end_); if ((channel_end_ <= 80)&&(channel_start_ >= 0)) { printf("%d\r\n", channel_end_); break; } printf("Channel must be between 0 and 80\r\n"); } test = cur_test; break; case 'c': test = RADIO_TEST_TXCC; break; case 'd': while (true) { printf("Enter delay in ms \ (two decimal digits, 01 to 99):"); scanf("%d",&delayms_); if ((delayms_ > 0) && (delayms_ < 100)) { printf("%d\r\n", delayms_); break; } printf("Delay must be between 1 and 99\r\n"); } test = cur_test; break; case 'e': radio_sweep_end(); cur_test = RADIO_TEST_NOP; break; case 'm': get_datarate(); test = cur_test; break; case 'o': test = RADIO_TEST_TXMC; printf("TX modulated carrier\r\n"); break; case 'p': get_power(); test = cur_test; break; case 'r': test = RADIO_TEST_RXSWEEP; printf("RX Sweep\r\n"); break; case 's': print_parameters(); break; case 't': test = RADIO_TEST_TXSWEEP; printf("TX Sweep\r\n"); break; case 'x': test = RADIO_TEST_RXC; printf("RX constant carrier\r\n"); break; case 'h': // Fall through. default: help(); break; } | cs |
Line 3~4 : scanf로 터미널에서 char형 문자하나를 입력받습니다.
Line 5~105 : 받은 문자로 처리를 하는 switch 구문입니다.
Line 7~22 : 입력된 문자가 'a'일 경우 실행되며, sweep할 start channel을 설정합니다.
숫자를 입력하라고 메세지가 뜬 후, 숫자를 입력해주면, channel_start_에 저장이 되고,
입력된 숫자가 0~80이면, 빠져나오고, 범위에 벗어나면 다시 입력하라고 뜹니다.
Line 24~38 : 입력된 문자가 'b'일 경우 실행되며, sweep할 End channel을 설정합니다.
역시 숫자를 입력하라고 메세지가 뜨고, 숫자는 channel_end_에 저장이 됩니다.
입력된 값이 0~80이면, 빠져나오고, 범위에 벗어나면 다시 입력하라고 뜹니다.
Line 40~42 : 입력된 문자가 'c'일 경우 실행되며, Tx carrier을 Start합니다.
test값에 radio_tests_t 의 RADIO_TEST_TXCC(enum 1)가 입력됩니다.
Line 44~58 : 입력된 문자가 'd'일 경우 실행되며, channel간 delay시간을 설정합니다.
1~99사이의 숫자를 입력하라는 메세지가 뜨고, 입력된 숫자는 delayms_에 저장됩니다.
1~99의 숫자가 입력되면 빠져나오고, 범위를 벗어나면 다시한번 입력하라고 뜹니다.
Line 60~63 : 입력된 문자가 'e'일 경우 실행되며 sweep나 carrier을 취소합니다.
Line 61 : radio_sweep_end 함수를 호출합니다.
1 2 3 4 5 | void radio_sweep_end(void) { NRF_TIMER0->TASKS_STOP = 1; radio_disable(); } | cs |
3 : Timer0을 종료하고,
4: radio를 disable 시킵니다.
Line 62 : test값에 RADIO_TEST_NOP(enum 0)을 입력합니다.
Line 65~68 : 입력된 문자가 'm'일 경우 실행되며 data rate를 설정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | void get_datarate(void) { uint8_t c; printf("Enter data rate ('0'=250 Kbit/s, '1'=1 Mbit/s and '2'=2 Mbit/s):"); while (true) { scanf("%c",&c); if ((c >= '0') && (c <= '2')) { printf("%c",c); break; } else { printf("%c",BELL); } } if (c == '0') { mode_ = RADIO_MODE_MODE_Nrf_250Kbit; } else if (c == '1') { mode_ = RADIO_MODE_MODE_Nrf_1Mbit; } else { mode_ = RADIO_MODE_MODE_Nrf_2Mbit; } printf("\r\n"); } | cs |
5 : 0~2중 선택가능하며, 0이면 mode_가 250Kbit로 1이면 1Mbit로 2이면 2Mbit로 설정됩니다.
만약 범위를 벗어난 숫자가 입력되면 BELL이 출력되며,범위안의 숫자가 입력될 때까지 재입력을 해야 합니다.
Line 70~73 : 입력된 문자가 'o'일때 실행되며, 변조된 TX carrier를 보냅니다.
test값은 RADIO_TEST_TXMC가 됩니다.
Line 75~78 : 입력된 문자가 'p'일때 실행되며, 출력 파워를 설정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | void get_power(void) { uint8_t c; printf("Enter output power ('0'=+4 dBm, '1'=0 dBm,...,'7'=-30 dBm):"); while (true) { scanf("%c",&c); if ((c >= '0') && (c <= '7')) { UNUSED_VARIABLE(app_uart_put(c)); break; } else { UNUSED_VARIABLE(app_uart_put(BELL)); } } switch(c) { case '0': txpower_ = RADIO_TXPOWER_TXPOWER_Pos4dBm; break; case '1': txpower_ = RADIO_TXPOWER_TXPOWER_0dBm; break; case '2': txpower_ = RADIO_TXPOWER_TXPOWER_Neg4dBm; break; case '3': txpower_ = RADIO_TXPOWER_TXPOWER_Neg8dBm; break; case '4': txpower_ = RADIO_TXPOWER_TXPOWER_Neg12dBm; break; case '5': txpower_ = RADIO_TXPOWER_TXPOWER_Neg16dBm; break; case '6': txpower_ = RADIO_TXPOWER_TXPOWER_Neg20dBm; break; case '7': // fall through default: txpower_ = RADIO_TXPOWER_TXPOWER_Neg30dBm; break; } printf("\r\n"); } | cs |
출력 파워범위는 0~7이며, 0일때 4dBm,1일때 0dBm, 2일때 -4dBm, 3일때 -8dBm,
4일때 -12dBm, 5일때 -16dBm, 6일떄 -20dBm, 7일때 -30dBm이며,
범위를 벗어나면 -30dBm이 설정 됩니다.
Line 80~83 : 입력된 문자가 'r'일때 실행되며, RX sweep를 시작합니다.
test는 RADIO_TEST_RXSWEEP가 됩니다.
Line 85~87 : 입력된 문자가 's'일때 실행되며, 앞에서 설정한 내용들이 출력됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | void print_parameters(void) { printf("Parameters:\r\n"); switch(mode_) { case RADIO_MODE_MODE_Nrf_250Kbit: printf("Data rate...........: 250 Kbit/s\r\n"); break; case RADIO_MODE_MODE_Nrf_1Mbit: printf("Data rate...........: 1 Mbit/s\r\n"); break; case RADIO_MODE_MODE_Nrf_2Mbit: printf("Data rate...........: 2 Mbit/s\r\n"); break; } switch(txpower_) { case RADIO_TXPOWER_TXPOWER_Pos4dBm: printf("TX Power............: +4 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_0dBm: printf("TX Power............: 0 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_Neg4dBm: printf("TX Power............: -4 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_Neg8dBm: printf("TX Power............: -8 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_Neg12dBm: printf("TX Power............: -12 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_Neg16dBm: printf("TX Power............: -16 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_Neg20dBm: printf("TX Power............: -20 dBm\r\n"); break; case RADIO_TXPOWER_TXPOWER_Neg30dBm: printf("TX Power............: -30 dBm\r\n"); break; default: // No implementation needed. break; } printf("(Start) Channel.....: %d",channel_start_); printf("\r\nEnd Channel.........: %d",channel_end_); printf("\r\nTime on each channel: %d",delayms_); printf(" ms\r\n"); } | cs |
Data rate, Tx power, Start channel, End channel, channel delay.
Line 89~92 : 입력된 문자가 't'일때 실행되며 TX sweep를 시작합니다.
test는 RADIO_TEST_TXSWEEP가 됩니다.
Line 94~97 : 입력된 문자가 'x'일때 실행되며 Rx carrier를 시작합니다.
test는 RADIO_TEST_RXC가 됩니다.
Line 99~104 : 나머지 문자가 입력되면, 도움말을 실행합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | static void help(void) { printf("Usage:\r\n"); printf("a: Enter start channel for sweep/channel for constant carrier\r\n"); printf("b: Enter end channel for sweep\r\n"); printf("c: Start TX carrier\r\n"); printf("d: Enter time on each channel (1ms-99ms)\r\n"); printf("e: Cancel sweep/carrier\r\n"); printf("m: Enter data rate\r\n"); printf("o: Start modulated TX carrier\r\n"); printf("p: Enter output power\r\n"); printf("s: Print current delay, channels and so on\r\n"); printf("r: Start RX sweep\r\n"); printf("t: Start TX sweep\r\n"); printf("x: Start RX carrier\r\n"); } | cs |
너무 기네요;;;
test에 들어간 값에따라 실행되는 부분은 다음에 포스팅할께요.^^
'Study > nRF51xxx(BLE)' 카테고리의 다른 글
nRF51 SDK 업데이트 (0) | 2015.03.09 |
---|---|
nRF51 DK 예제 11 - radiotest (2) (2) | 2015.03.06 |
nRF51 DK 예제 10 - PWM (2) | 2015.03.04 |
nRF51 DK 예제 9 - PPI (0) | 2015.03.04 |
nRF51 DK 예제 8 - Pin change interrupt (0) | 2015.03.03 |