diff --git a/platforms/stm32-f103rb-nucleo/Makefile b/platforms/stm32-f103rb-nucleo/Makefile index e2bd898fa..612cfe03b 100644 --- a/platforms/stm32-f103rb-nucleo/Makefile +++ b/platforms/stm32-f103rb-nucleo/Makefile @@ -2,7 +2,8 @@ # Makefile for STM32-F103RB Nucleo board with CC256x Bluetooth modules # -BINARY=led_counter +# BINARY=led_counter +BINARY=gap_inquiry OPENCM3_DIR = libopencm3 LDSCRIPT = stm32f1-nucleo.ld @@ -16,13 +17,33 @@ CORE = \ ${BTSTACK_ROOT}/src/run_loop.c \ ${BTSTACK_ROOT}/src/run_loop_embedded.c +COMMON = \ + ${BTSTACK_ROOT}/chipset-cc256x/bt_control_cc256x.c \ + ${BTSTACK_ROOT}/chipset-cc256x/bluetooth_init_cc2560B_1.0_BT_Spec_4.1.c \ + ${BTSTACK_ROOT}/src/hci.c \ + ${BTSTACK_ROOT}/src/hci_cmds.c \ + ${BTSTACK_ROOT}/src/hci_dump.c \ + ${BTSTACK_ROOT}/src/hci_transport_h4_ehcill_dma.c \ + ${BTSTACK_ROOT}/src/l2cap.c \ + ${BTSTACK_ROOT}/src/l2cap_signaling.c \ + ${BTSTACK_ROOT}/src/remote_device_db_memory.c \ + ${BTSTACK_ROOT}/src/rfcomm.c \ + ${BTSTACK_ROOT}/src/sdp.c \ + ${BTSTACK_ROOT}/src/sdp_util.c \ + ${BTSTACK_ROOT}/src/utils.c \ + ${BTSTACK_ROOT}/src/sdp_parser.c \ + ${BTSTACK_ROOT}/src/sdp_client.c \ + ${BTSTACK_ROOT}/src/sdp_query_util.c \ + ${BTSTACK_ROOT}/src/sdp_query_rfcomm.c \ + CORE_OBJ = $(CORE:.c=.o) +COMMON_OBJ = $(COMMON:.c=.o) -OBJS += $(CORE_OBJ) +OBJS += $(CORE_OBJ) $(COMMON_OBJ) -CFLAGS = -I. -I$(BTSTACK_ROOT)/include -I$(BTSTACK_ROOT)/src +CFLAGS = -I. -I$(BTSTACK_ROOT)/include -I$(BTSTACK_ROOT)/src -I$(BTSTACK_ROOT)/chipset-cc256x -examples: libopencm3/lib/libopencm3_stm32f1.a led_counter.elf +examples: libopencm3/lib/libopencm3_stm32f1.a $(BINARY).elf include libopencm3.stm32f1.mk diff --git a/platforms/stm32-f103rb-nucleo/README b/platforms/stm32-f103rb-nucleo/README index d55aa9115..d7dfa41bb 100644 --- a/platforms/stm32-f103rb-nucleo/README +++ b/platforms/stm32-f103rb-nucleo/README @@ -12,9 +12,8 @@ Configuration: - Bluetooth: USART3 with Hardware Flowcontrol. TX PB10, RX PB11, CTS PB13 (in), RTS PB14 (out), N_SHUTDOWN PB15 TODO: -- figure out how to compile multiple examples with single Makefile/folder -- implement hal_uart_dma.h +- implement hal_uart_dma.h using DMA (fallback: regular UART) - implement hal_cpu.h -- create and implement hal_led.h +- figure out how to compile multiple examples with single Makefile/folder - extract classic and le examples into example/embedded - use examples from BTSTACK_ROOT/example/embedded directly diff --git a/platforms/stm32-f103rb-nucleo/gap_inquiry.c b/platforms/stm32-f103rb-nucleo/gap_inquiry.c new file mode 100644 index 000000000..032448568 --- /dev/null +++ b/platforms/stm32-f103rb-nucleo/gap_inquiry.c @@ -0,0 +1,217 @@ +//***************************************************************************** +// +// minimal setup for HCI code +// +//***************************************************************************** +#include +#include +#include +#include + +#include "bt_control_cc256x.h" + +#include +#include + +#include "hci.h" +#include "btstack_memory.h" +#include "remote_device_db.h" +#include "btstack-config.h" + +int btstack_main(void); + +#define MAX_DEVICES 10 +enum DEVICE_STATE { REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, REMOTE_NAME_FETCHED }; +struct device { + bd_addr_t address; + uint16_t clockOffset; + uint32_t classOfDevice; + uint8_t pageScanRepetitionMode; + uint8_t rssi; + enum DEVICE_STATE state; +}; + +#define INQUIRY_INTERVAL 5 +struct device devices[MAX_DEVICES]; +int deviceCount = 0; + + +enum STATE {INIT, W4_INQUIRY_MODE_COMPLETE, ACTIVE} ; +enum STATE state = INIT; + + +int getDeviceIndexForAddress( bd_addr_t addr){ + int j; + for (j=0; j< deviceCount; j++){ + if (BD_ADDR_CMP(addr, devices[j].address) == 0){ + return j; + } + } + return -1; +} + +void start_scan(void){ + printf("Starting inquiry scan..\n"); + hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); +} + +int has_more_remote_name_requests(void){ + int i; + for (i=0;i= 0) continue; // already in our list + memcpy(devices[deviceCount].address, addr, 6); + + devices[deviceCount].pageScanRepetitionMode = packet[offset]; + offset += 1; + + if (event == HCI_EVENT_INQUIRY_RESULT){ + offset += 2; // Reserved + Reserved + devices[deviceCount].classOfDevice = READ_BT_24(packet, offset); + offset += 3; + devices[deviceCount].clockOffset = READ_BT_16(packet, offset) & 0x7fff; + offset += 2; + devices[deviceCount].rssi = 0; + } else { + offset += 1; // Reserved + devices[deviceCount].classOfDevice = READ_BT_24(packet, offset); + offset += 3; + devices[deviceCount].clockOffset = READ_BT_16(packet, offset) & 0x7fff; + offset += 2; + devices[deviceCount].rssi = packet[offset]; + offset += 1; + } + devices[deviceCount].state = REMOTE_NAME_REQUEST; + printf("Device found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), + devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, + devices[deviceCount].clockOffset, devices[deviceCount].rssi); + deviceCount++; + } + + break; + } + case HCI_EVENT_INQUIRY_COMPLETE: + for (i=0;i= 0) { + if (packet[2] == 0) { + printf("Name: '%s'\n", &packet[9]); + devices[index].state = REMOTE_NAME_FETCHED; + } else { + printf("Failed to get name: page timeout\n"); + } + } + continue_remote_names(); + break; + + default: + break; + } + break; + + default: + break; + } +} + + +// main == setup +int btstack_main(void) +{ + btstack_memory_init(); + run_loop_init(RUN_LOOP_EMBEDDED); + + // init HCI + hci_transport_t * transport = hci_transport_h4_dma_instance(); + bt_control_t * control = bt_control_cc256x_instance(); + hci_uart_config_t * config = hci_uart_config_cc256x_instance(); + remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory; + hci_init(transport, config, control, remote_db); + hci_register_packet_handler(packet_handler); + + // turn on! + hci_power_control(HCI_POWER_ON); + + // go! + run_loop_execute(); + + // happy compiler! + return 0; +} + diff --git a/platforms/stm32-f103rb-nucleo/main.c b/platforms/stm32-f103rb-nucleo/main.c index 5af211c8a..9bcfbd3ad 100644 --- a/platforms/stm32-f103rb-nucleo/main.c +++ b/platforms/stm32-f103rb-nucleo/main.c @@ -8,6 +8,8 @@ #include #include +#include + // Configuration // LED2 on PA5 // Debug: USART2, TX on PA2 @@ -19,6 +21,8 @@ // btstack code starts there void btstack_main(void); +static void bluetooth_power_cycle(void); + // hal_tick.h inmplementation #include @@ -72,6 +76,59 @@ void hal_led_toggle(void){ gpio_toggle(GPIOA, GPIO_LED2); } +// hal_uart_dma.c implementation +#include + +// handlers +static void (*rx_done_handler)(void) = dummy_handler; +static void (*tx_done_handler)(void) = dummy_handler; +static void (*cts_irq_handler)(void) = dummy_handler; + +void hal_uart_dma_init(void){ + bluetooth_power_cycle(); +} +void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){ + rx_done_handler = the_block_handler; +} + +void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){ + tx_done_handler = the_block_handler; +} + +void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){ + // TODO: enable/disable interrupt + cts_irq_handler = the_irq_handler; +} + +int hal_uart_dma_set_baud(uint32_t baud){ + usart_disable(USART3); + usart_set_baudrate(USART3, baud); + usart_enable(USART3); +} + +void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t length){ + // TODO: use DMA for this + printf("TX: "); + while (length){ + printf("%02x ", *buffer); + usart_send_blocking(USART3, *buffer); + buffer++; + length--; + } + printf("\n"); + (*tx_done_handler)(); +} +void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){ + // TODO: use DMA for this + (void) buffer; + (void) len; +} + +void hal_uart_dma_set_sleep(uint8_t sleep){ + // TODO: + (void) sleep; +} + /** * Use USART_CONSOLE as a console. * This is a syscall for newlib @@ -81,8 +138,7 @@ void hal_led_toggle(void){ * @return */ int _write(int file, char *ptr, int len); -int _write(int file, char *ptr, int len) -{ +int _write(int file, char *ptr, int len){ int i; if (file == STDOUT_FILENO || file == STDERR_FILENO) { @@ -98,8 +154,7 @@ int _write(int file, char *ptr, int len) return -1; } -static void clock_setup(void) -{ +static void clock_setup(void){ /* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1 + USART2. */ /* needs to be done before initializing other peripherals */ rcc_periph_clock_enable(RCC_GPIOA); @@ -108,15 +163,12 @@ static void clock_setup(void) rcc_periph_clock_enable(RCC_USART3); } -static void gpio_setup(void) -{ +static void gpio_setup(void){ /* Set GPIO5 (in GPIO port A) to 'output push-pull'. [LED] */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO_LED2); } -void usart_setup(void); -void usart_setup(void) -{ +static void usart_setup(void){ /* Setup GPIO pin GPIO_USART2_TX/GPIO2 on GPIO port A for transmit. */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); @@ -132,12 +184,60 @@ void usart_setup(void) usart_enable(USART2); } +static void bluetooth_setup(void){ + printf("\nBluetooth starting...\n"); + + // n_shutdown as output + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,GPIO_BT_N_SHUTDOWN); + + // tx output + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART3_TX); + // rts output + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART3_RTS); + // rx input + gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART3_RX); + // cts as input + gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART3_CTS); + + /* Setup UART parameters. */ + usart_set_baudrate(USART3, 115200); + usart_set_databits(USART3, 8); + usart_set_stopbits(USART3, USART_STOPBITS_1); + usart_set_mode(USART3, USART_MODE_TX_RX); + usart_set_parity(USART3, USART_PARITY_NONE); + usart_set_flow_control(USART3, USART_FLOWCONTROL_RTS_CTS); + + /* Finally enable the USART. */ + usart_enable(USART3); +} + +// reset Bluetooth using n_shutdown + +static void msleep(uint32_t delay) +{ + uint32_t wake = embedded_get_ticks() + delay; + while (wake > embedded_get_ticks()); +} + +static void bluetooth_power_cycle(void){ + printf("n_shutdown low\n"); + gpio_clear(GPIOA, GPIO_LED2); + gpio_clear(GPIOB, GPIO_BT_N_SHUTDOWN); + msleep(1000); + printf("n_shutdown high\n"); + gpio_set(GPIOA, GPIO_LED2); + gpio_set(GPIOB, GPIO_BT_N_SHUTDOWN); + msleep(1000); + printf("n_shutdown toggling down\n"); +} + int main(void) { clock_setup(); gpio_setup(); - usart_setup(); hal_tick_init(); + usart_setup(); + bluetooth_setup(); // hand over to btstack embedded code btstack_main();