본문 바로가기

BLE/펌웨어

[Noise Detector] nRF51 (3) : NDS Message Sequence

일반적인 Message Sequence입니다. 세로축은 시간의 흐름, 화살표 위의 글자는 이벤트, 아래 글자는 이벤트와 함께 전달되는 내용입니다. 피어는 안드로이드 Noise Detector 어플리케이션을 의미합니다.

전체 과정을 ① Noise Detector ON 단계, ② Detected Value 전송 단계, ③ Noise Detector OFF 단계로 구분했습니다.

① Noise Detector ON 단계

이전 포스트에서 Noise Detector Controlpoint Characteristic(이하 NDCP 특성)은 쓰기 요청에 대해 어플리케이션의 인증이 필요하다고 했습니다. 따라서 피어가 NDCP 특성에 {0x02, 0x00} 쓰기 요청을하면, 요청을 수신한 소프트디바이스는 속성 테이블에 요청받은 값을 즉시 쓰지 않고 어플리케이션에게 "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST" 이벤트를 주어 어떻게 처리할지 물어봅니다. 

NDCP 쓰기 요청은 페리페럴 제어 과정을 동반하기 때문에, 요처에 대한 페리페럴 제어가 완료된 후에만 새로운 요청을 받아들일 수 있습니다. 따라서 어플리케이션은 서비스 객체(ble_nds_t 타입의 전역변수)의 ndcp_procedure_status가 "NDCP_STATE_NO_PROC_IN_PROGRESS"가 아니면 인증을 거부해버립니다. 또한 거부하면서 바로 함수를 종료하기 때문에 페리페럴 제어 과정도 수행되지 않습니다. 즉, 페리페럴 제어 블록은 ndcp_procedure_status에 의해 보호됩니다.  ble_nds.c의 on_ctrlpt_write() 함수를 보면 알 수 있습니다.

정상적으로 쓰기 요청이 수행되면 어플리케이션은 NDCP 특성 쓰기 요청에 대해 Indication을 합니다. 연산 증폭기에 전원을 공급하는 AMPLIFIER_SWITCH_PIN 핀을 Low로 만들고, 10ms마다 RTC 이벤트를 발생시키는 m_noise_detector_timer_id 앱 타이머를 켭니다. 이 과정이 성공적으로 수행되면 어프리케이션은 다시 NDCP 특성에 {0x02, 0x02}를 쓰고 이것을 피어에게 Indication합니다. 0번 인덱스는 이전에 피어가 요청한 명령을 의미하고 1번 인덱스는 요청이 성공적으로 수행되었다는 것을 의미합니다.

 

② Detected Value 전송 단계

m_noise_detector_timer_id 앱 타이머 이벤트 핸들러는 20회째에 모아진 20바이트 배열을 Detected Noise Value Characteristic(이하 DNV 특성)에 쓰고 Notification하는 동작을 반복합니다.

 

③ Noise Detector OFF 단계

이 동작은 NDCP 특성에 쓰여지는 내용만 다를 뿐 ① Noise Detector ON 단계와 동일합니다. 피어의 NDCP 특성에 {0x01, 0x00} 쓰기 요청이 성공적으로 수행되면 어플리케이션은 NDCP 특성에 다시 {0x01, 0x02}를 쓰고 피어에게 Indication합니다. 1번 인덱스는 피어가 보내준 명령인 0번 인덱스가 무엇이든 간에 그 동작이 성공하면 0x02, 실패하면 0x01을 씁니다. 역시 페리페럴 제어 동작은 ndcp_procedure_status에 의해 보호됩니다.

 

참고로 NDCP 특성은 BLE 프로토콜 요구사항의 컨트롤 포인트 개념(블루투스 4.2 코어스팩 2168페이지)을 그대로 구현한 것입니다.

또한 ADC 과정을 앱 타이머로 구현한 것은 STM32, nRF52 등과 달리 nRF51의 ADC는 원-샷 모드만 지원하기 때문에 연속 변환은 소프트웨어로 구성되어야 하고, 이때 선택된 방법이 앱 타이머일 뿐입니다.