1. Running the Example
cd ~/mcu/Ameba-rtos/ameba-rtos
source ameba.sh
cd amebadplus_gcc_project
1) Configure using menuconfig.py
CONFIG BT ---> [*] Enable BT ---> [*]BT Example Demo --> [*] BLE Peripheral
2) Build and Flash
build.py flash.py -p /dev/ttyCH341USB0
3) Run
Open a serial tool with baud rate 1500000. To enable BLE Peripheral mode, send the AT command:
AT+BTDEMO=peripheral,1
You will see several SERVICES become active:
Open a BLE debugging app on your phone: Search for RTK_BT_PEIPHERA and connect.
You will see the services provided by the example, and you can read a characteristic:
2. Feature Expansion
In the original example, BLE Peripheral must be enabled using an AT command, which is not convenient.
1) Enable BLE Peripheral in Code
cd ~/mcu/Ameba-rtos/ameba-rtos/component/bluetooth/example/ble_peripheralCreate two new files: ble_led.c and ble_led.h
ble_led.c
#include "platform_autoconf.h"#include "ameba_soc.h"#include "os_wrapper.h"#include "ble_led.h"
extern int ble_peripheral_main(uint8_t enable);
void raw_gpio_demo(void)
{
GPIO_InitTypeDef GPIO_InitStruct_LED;
// init LED control pins
GPIO_InitStruct_LED.GPIO_Pin = GPIO_LED_PIN1;
GPIO_InitStruct_LED.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(&GPIO_InitStruct_LED);
GPIO_InitStruct_LED.GPIO_Pin = GPIO_LED_PIN2;
GPIO_Init(&GPIO_InitStruct_LED);
GPIO_InitStruct_LED.GPIO_Pin = GPIO_LED_PIN3;
GPIO_Init(&GPIO_InitStruct_LED);
GPIO_InitStruct_LED.GPIO_Pin = GPIO_LED_PIN4;
GPIO_Init(&GPIO_InitStruct_LED);
GPIO_InitStruct_LED.GPIO_Pin = GPIO_LED_PIN5;
GPIO_Init(&GPIO_InitStruct_LED);
// Enable BLE Peripheral mode
ble_peripheral_main(1);
rtos_task_delete(NULL);
}
void app_example(void)
{
if (RTK_SUCCESS != rtos_task_create(NULL, "RAW_GPIO_DEMO_TASK",
(rtos_task_t)raw_gpio_demo, (void *)NULL, (128 * 16), (1))) {
printf("Create RAW_GPIO_DEMO_TASK Err!!!\n");
}
}
void turn_off_leds(void)
{
GPIO_WriteBit(GPIO_LED_PIN1, 0);
GPIO_WriteBit(GPIO_LED_PIN2, 0);
GPIO_WriteBit(GPIO_LED_PIN3, 0);
GPIO_WriteBit(GPIO_LED_PIN4, 0);
GPIO_WriteBit(GPIO_LED_PIN5, 0);
}
void set_led(uint8_t i, u32 val)
{
switch (i) {
case 1: GPIO_WriteBit(GPIO_LED_PIN1, val); break;
case 2: GPIO_WriteBit(GPIO_LED_PIN2, val); break;
case 3: GPIO_WriteBit(GPIO_LED_PIN3, val); break;
case 4: GPIO_WriteBit(GPIO_LED_PIN4, val); break;
case 5: GPIO_WriteBit(GPIO_LED_PIN5, val); break;
}
}
This enables BLE Peripheral automatically by calling:
ble_peripheral_main(1);
ble_led.h
#ifndef BLE_LED_H#define BLE_LED_H
#include "ameba_soc.h"
#define GPIO_LED_PIN1 _PB_17#define GPIO_LED_PIN2 _PB_18#define GPIO_LED_PIN3 _PB_19#define GPIO_LED_PIN4 _PB_20#define GPIO_LED_PIN5 _PB_21
void turn_off_leds(void);void set_led(uint8_t i, u32 val);
#endif
Add ble_led.c to CMakeLists.txt
ameba_list_append(private_sources
peripheral.c
ble_led.c
)
peripheral.c
Added LED control logic:
case RTK_BT_LE_GAP_EVT_ADV_START_IND: {
rtk_bt_le_adv_start_ind_t *adv_start_ind = (rtk_bt_le_adv_start_ind_t *)param;
if (!adv_start_ind->err) {
BT_LOGA("[APP] ADV started: adv_type %d \r\n", adv_start_ind->adv_type);
set_led(1, 1); // Turn on the LED when advertising starts
} else {
BT_LOGE("[APP] ADV start failed, err 0x%x \r\n", adv_start_ind->err);
}
BT_AT_PRINT("+BLEGAP:adv,start,%d,%d\r\n",
(adv_start_ind->err == 0) ? 0 : -1,
adv_start_ind->adv_type);
break;
}
case RTK_BT_LE_GAP_EVT_ADV_STOP_IND: {
rtk_bt_le_adv_stop_ind_t *adv_stop_ind = (rtk_bt_le_adv_stop_ind_t *)param;
if (!adv_stop_ind->err) {
BT_LOGA("[APP] ADV stopped: reason 0x%x \r\n", adv_stop_ind->stop_reason);
set_led(1, 0); // Turn off the LED when advertising stops
} else {
BT_LOGE("[APP] ADV stop failed, err 0x%x \r\n", adv_stop_ind->err);
}
BT_AT_PRINT("+BLEGAP:adv,stop,%d,0x%x\r\n",
(adv_stop_ind->err == 0) ? 0 : -1,
adv_stop_ind->stop_reason);
break;
}
case RTK_BT_LE_GAP_EVT_CONNECT_IND: {
rtk_bt_le_conn_ind_t *conn_ind = (rtk_bt_le_conn_ind_t *)param;
rtk_bt_le_addr_to_str(&(conn_ind->peer_addr), le_addr, sizeof(le_addr));
if (!conn_ind->err) {
role = conn_ind->role ? "slave" : "master";
BT_LOGA("[APP] Connected, handle: %d, role: %s, remote device: %s\r\n",
conn_ind->conn_handle, role, le_addr);
set_led(4, 1); // Turn on LED when BLE connects successfully
} else {
BT_LOGE("[APP] Connection establish failed(err: 0x%x), remote device: %s\r\n",
conn_ind->err, le_addr);
set_led(4, 0); // Turn off LED when BLE connection fails
}
BT_AT_PRINT("+BLEGAP:conn,%d,%d,%s\r\n",
(conn_ind->err == 0) ? 0 : -1,
(int)conn_ind->conn_handle,
le_addr);
break;
}
2) Modify Characteristic to Control LED
Go to:
cd ~/mcu/Ameba-rtos/ameba-rtos/component/bluetooth/example/gatt_service/server
Modify rtk_long_uuid_service.c:
if (LONG_UUID_WRITE_INDEX == p_write_ind->index) {
BT_LOGA("[APP] Long uuid service write event, len: %d, type: %d, data:\r\n",
p_write_ind->len, p_write_ind->type);
BT_DUMPA("", p_write_ind->value, p_write_ind->len);
if ((uint8_t)*(p_write_ind->value) == 0x31) {
set_led(5, 1); // Write “1” → turn LED on
} else if ((uint8_t)*(p_write_ind->value) == 0x32) {
set_led(5, 0); // Write “2” → turn LED off
}
}
This adds functionality so that writing 0x31 (“1”) turns on LED 5 and writing 0x32 (“2”) turns it off.
Ai-Thinker