Решил я сделать первое RF устройство в своей жизни...
Думаю, какой чип выбрать, ну наверное нужно ориентироваться на батарею, чтобы работало годами... сделал сортировку на Digikey по току потребления в режиме передачи и приема.
Выбрал Bluetooth v4.0 (интересно что у v4.2 чипов потребление больше)
Первыми оказались, купленые у кого-то, Microchip устройства, которые распространяются без даташита, информации нету, люди ругаются.
Вторые были устройства Dialog, программатор дорогой, ребята не особенно известные, изобрели какую-то "One time write memory" т.е. записать в флеш можно только один раз, скипаем.
Ну и тут, если правильно помню, идет STMicroelectronics, со своим чипом BlueNrg-MS, который уже устарел, и более современная версия BlueNRG-1.
По потреблению BlueNrg-MS лучше, но BlueNRG-1 не сильно хуже.
Вот так я пришел к BlueNRG-1.
BlueNRG-1/BlueNRG-2 это практически единственная активная разработка STM на данный момент для Bluetooth...
Начнем с того, что желание обьединить RF с микроконтроллером вполне естественная потребность, потому как ставить отдельный чип, и общаться с ним сериально или через SPI это слишком сложно.
И почти у каждого уважающего себя производителя (кроме Microchip) есть такой чип.
У разных производителей разной степени "гадкости" маркетинговые приемы, у STM уж точно не самые страшные, но сегодня именно о них.
Чип поддерживает SWD протокол, это несомненно плюс, и тут претензий быть не может, но дьявол в деталях.
Программатор стоит 12$, или даже меньше, у меня STM32L1DISCOVERY kit.
Я никогда не покупаю киты производителя для разработки, не пользуюсь модулями готовыми и т.д., это все не православно.
Поэтому я сразу решил сделать свою печатку.
Для этого мне нужна схема, с детальными данными, в даташите такой схемы нету, компоненты не подписаны.
https://www.mouser.com/pdfdocs/enDM00262983.pdf При этом STM активно впаривает всем свой board:
STEVAL-IDB007V1
Без него, работать трудно, так-как в нем, как оказалось есть firmware (без исходников) в котором есть USB to Serial протокол, proprietary, который позволяет заливать на чип (жестко припаян на STEVAL-IDB007V1) все примеры из документации, и специальный "пример" который называется DTM, Direct Test Mode. Который в процессе производства содержит некий "test bench"
Вообщем документация крайне скуда, она перешла в Soft, под названием BlueNRG GUI и BlueNRG Navigator, но вот проблема, без STEVAL-IDB007V1 она у вас работать не будет.
Ну не беда подумал я, можно ведь схему срисовать с STEVAL-IDB007V1, а программатор и отладчик попробовать переделать из STM32L1 DISCOVERY board.
Смотрим в схему от STEVAL-IDB007V1:
http://www.st.com/content/ccc/resource/technical/layouts_and_diagrams/schematic_pack/group0/44/43/db/96/8b/6c/40/bd/STEVAL-IDB007V1%20schematic/files/steval-idb007v1_schematic.pdf/jcr:content/translations/en.steval-idb007v1_schematic.pdf Тут тоже есть целых три непонятных детали,
l1, l5: TBD_0402
И какое-то чудо, под назвнием D1: Solder 10u_0805 between 1-2
посмотрел фотографии готовых бордов, там запаяно именно так.
ну думаю запаяю кондентсатор 10u 0805, с этим понятно.
С L1, просто, у меня вообще не будет Low-Speed oscillator, так-как он optional, что в даташите описано.
Остается L5, ну думаю странное решение, почему они не пошли таким же путем как с L1, не фильтруют GND на входе и выходе а только на входе? может кто-то знает?
Думаю, дроссель там нужен такой, который отфильтрует 2.4GHZ, прикинул, 10 nH будет надежно фильтровать, все, определились.
Получили вот такую схему, и отправили в производство:
Тут нужно оговорить особо, что никакой документации по выводам не существует, я бы например хотел знать какие из выводов могут делать PWM??
Я не нашел такой документации НИГДЕ кроме исходного кода в примере.
Если бы я знал, то мог подключить контроллер двигателя именно к ним, чтобы иметь возможность управлять скоростью (правильный ответ: DIO2, DIO3).
А к какому выводу подсоединить счетчик импульсов? (правильный ответ: к любому DIOx, счетчик может считать с любого, а выводить PWM только на DIO2 и DIO3)
Вообщем стоит плата, нужно узнать как к ней подсоединится по SWD.
По аналогии с STM32 ST Link utility, находим BlueNRG-1 ST Link utility
пробуем подсоединится и получаем сообщение о том, что подсоединится не удается.
В чем может быть проблема? Ну наверное нужно проверить питание на чипе.
Вот эта область на схеме:
из названия пина, можно сделать вывод что на нем должно быть 1.2V (VDD1V2). Но их нету!!
И тут я нашел файл, который называется STEVAL-IDB007V1 BOM
http://www.st.com/content/ccc/resource/technical/document/bill_of_materials/group0/64/17/e7/4a/da/f9/41/59/STEVAL-IDB007V1%20BOM/files/steval-idb007v1_bom.pdf/jcr:content/translations/en.steval-idb007v1_bom.pdf И тут оказалось что C3, у меня должен быть индуктором на 10uH.
A L5 в их схеме оказался не дросселем а резистором 0 Ом (я поставил 10нГ).
Перепаял, оказалось снова не подключается, питания снова нету, осциллограф меандр на дросселе не показывает.
Думаю ну что за черт, нужно попробовать вариант без SMPS.
Подал просто напряжение на SMPSFIL2.
1.2 Вольта появилось, но снова не могу подсоединится.
Начал пробовать на более низких скоростях. Бинго, коннектится на 100кhz но выше не хочет. В логах идут ошибки.
Посмотрим в интернете, многие грешат на то что чип дефектный и они его перегрели в процессе пайки и т.д. Никто им не помог...
Но как позже выяснилось дело было в ресете....
В отличии от STM32 где RST пин подтянут внутри чипа к VDD,
тут такой подтяжки нету, напряжение на нем плавает, и поэтому на низких скоростях можно подключится, а на высоких нет!
Это кстати не отражено в документации, насколько помню, тоже.
Ну ладно, подтянул к 3.3 вольта хардварно, хорошо что хоть вывод развел.
И бинго, подключается теперь на 4MHZ, все как по маслу.
Теперь нужно закачать какой пример...
Скачал BlueNRG-1 DK 2.5.0 и IAR for ARM 2016 (EWARM).
В списке чипов от STM BlueNRG-1 нету.
Каким-то чюдом, начел в DK папку Utils, где был внезапно: EWARM_BlueNRG-1_Flasher.exe
который оказался самораспоковывающимся архивом, и внутри него есть настройки и плагины для EWARM.
Ну отлично, дальше идем в папку Project\BlueNRG1_Periph_Examples\GPIO\IOToggle\EWARM\BlueNRG-1
Открываем воркспейс, делаем билд, и выбираем Download and Debug.
И все срабатывает с первого раза и дебуггер встает на функцию main.
Делаем степ, и благополучно зависаем в первой же функции.
Все откадчик при этом больше не запускается, чип даже после хардварного ресета не запускается, BlueNRG-1 ST Link тоже больше не запускается.
И тут вы должны были заметить такую фразу в даташите, которая находится в секции "Debugging Tips"
T.e вы можете сами выстрелить себе в ногу, поэтому нужно DIO7 подтянуть к VDD, при этом чип остановится в бутлоадере, и вы сможете подключиться к нему снова.
Так и есть, после этого я смог подключиться, при этом магию перехода из бутлоадера на аппликацию, скрывает в себе, по всей видимости, плагин для EWARM.
Вообщем, с подтянутым пином можно отлаживать точно также как и без него.
Делаем снова откадку и выбираем Step Into.
и находим место где зависаем:
/* Wait until HS is ready. The slow clock period
* measurement is done automatically each time the
* device enters in active2 state and the HS is ready.
* The interrupt signals that a measurement is done.
*/
while(CKGEN_BLE->CLK32K_IT == 0);
CKGEN_BLE->CLK32K_IT = 1;
CKGEN_BLE->CLK32K_COUNT = 23; //Restore the window length for slow clock measurement.
CKGEN_BLE->CLK32K_PERIOD = 0;
Подсоединяем осциллограф к осциллятору, смотрим, что на одном из выводов слишком большое падение амплитуды.
И тут я вспомнил про дроссель 10nH, меняем его на резистор 0R. Падение амплитуды становится меньше, и это оказывается достаточным.
Запускаем снова дебуггер, и снова благополучно зависаем, теперь тут:
/* Wait until the RO or 32KHz is ready */
if (waitLS_Ready) {
current_time = *(volatile uint32_t *)0x48000010;
while(((*(volatile uint32_t *)0x48000010)&0x10) == (current_time&0x10));
}
Обращаем внимание на этот код:
/* Low Speed Crystal Source */
#if (LS_SOURCE == LS_SOURCE_EXTERNAL_32KHZ)
cold_start_config[20] = LOW_FREQ_XO;
#elif (LS_SOURCE == LS_SOURCE_INTERNAL_RO)
cold_start_config[20] = LOW_FREQ_RO;
#else
#error "No definition for Low Speed Crystal Source"
#endif
идем на дифиницию LS_SOURCE:
/**
* @brief Low Speed Crystal default source
*/
#ifndef LS_SOURCE
#define LS_SOURCE LS_SOURCE_EXTERNAL_32KHZ
#endif
и далее находим:
/**
* @brief Low Speed Internal RO
*/
#define LS_SOURCE_INTERNAL_RO 1
/**
* @brief Low Speed External 32 KHz
*/
#define LS_SOURCE_EXTERNAL_32KHZ 2
T.e по дефолту используется внешний осциллятор, низкоскоростной, хоть он и опциональный..странно и в документации не отражено..
ну ладно, делаем define на уровне проекта.
LS_SOURCE=1
И бинго, все заработало.
Вот только в примере, абсолютно дикий уровень абстракции, функции SdkEvalХХХ
абстрагируют нас от разных Evaluation боардов.
Этот слой пришлось выкинуть и я написал простой пример дерганья 5-м пином, подключил осциллограф, пин дергается:
int main(void)
{
GPIO_InitType GPIO_InitStructure;
/* System initialization function */
SystemInit();
/* Enable the GPIO Clock */
SysCtrl_PeripheralClockCmd(CLOCK_PERIPH_GPIO, ENABLE);
/* Configure the LED pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Output;
GPIO_InitStructure.GPIO_Pull = ENABLE;
GPIO_InitStructure.GPIO_HighPwr = DISABLE;
GPIO_Init(&GPIO_InitStructure);
/* Put the LED off */
GPIO_WriteBit(GPIO_Pin_5, Bit_RESET);
/* Configure SysTick to generate interrupt */
SysTick_Config(SYST_CLOCK/1000 - 1);
/* Infinite loop */
while(1) {
GPIO_ToggleBits(GPIO_Pin_5);
SdkDelayMs(1000);
}
}
Ну уже небольшая победа.
Нужно, думаю, теперь попробовать BLE пример.
Подключил измеритель мощности RF, нужно поверить мощность!
Нашел пример BLE_Beacon.
Запускаю, что такое?
EWARM падает с исключением.
Смотрю в настройки проекта, а там настроен Simulator, т.е. я запускаю в режиме симулятора...
Настроек "не в режиме симулятора" нету.
Ставим ST-LINK
Теперь что-то снова не работало, нужно было еще и две галочки поставить:
Теперь выдает ошибку, что не может записать в флеш в адрес 0х0.
Внимательно сравниваем два проекта. И находим вот эту настройку
т.е. в примере даже линковка стояла от другого чипа!!
После этого все заработало!
Но как протестировать мощность?
Находим в SDK функцию,
/**
* @brief This command is used to start a test where the DUT generates test reference
packets at a fixed interval. The Controller shall transmit at maximum power.
An LE Controller supporting the LE_Transmitter_Test command shall support
Packet_Payload values 0x00, 0x01 and 0x02. An LE Controller may support
other values of Packet_Payload.
(See Bluetooth Specification v.4.1, Vol. 2, Part E, 7.8.29)
* @param TX_Frequency N = (F - 2402) / 2
Frequency Range : 2402 MHz to 2480 MHz
* Values:
- 0x00 ... 0x27
* @param Length_Of_Test_Data Length in bytes of payload data in each packet.
* Values:
- 0x00 ... 0x25
* @param Packet_Payload Type of packet payload.
* Values:
- 0x00: Pseudo-Random bit sequence 9
- 0x01: Pattern of alternating bits '11110000'
- 0x02: Pattern of alternating bits '10101010'
- 0x03: Pseudo-Random bit sequence 15
- 0x04: Pattern of All '1' bits
- 0x05: Pattern of All '0' bits
- 0x06: Pattern of alternating bits '00001111'
- 0x07: Pattern of alternating bits '0101'
* @retval Value indicating success or error code.
*/
tBleStatus hci_le_transmitter_test(uint8_t TX_Frequency,
uint8_t Length_Of_Test_Data,
uint8_t Packet_Payload);
Справедливости ради очень хорошо откоментированную.
Пробую ее вставить после Start_Beaconing();
выдает ошибку, без пояснения причины.
Тут нужно отдельно сказать, что Bluetooth "stack" распространяется в виде архива обьектных файлов, исходников нету.
Есть только заголовочный файл и ассемблер в режиме дебуггера.
Ладно, думаю, наверное Start_Beaconing() занимает какой-то важный ресурс.
Удаляю Start_Beaconing() и ставлю на ее место hci_le_transmitter_test()
И бинго, измеритель мощности показывает заявленую мощность. (идут пакеты) +/- 2дб.
Дальше загружаем пример чат сервера, подсоединяем антену, и все работает.
Но это был интересный квест.
Прибор выглядит вот так.