Skip to content

Commit 1bfa411

Browse files
committed
pbdrv/bluetooth: platform.c bluetooth cleanup
Moves almost all EV3 bluetooth related configuration out of platform.c. EDMA3 interrupts still need to be routed from platform.c, but that's it. Bluetooth controller still initializes as before.
1 parent a63ce10 commit 1bfa411

File tree

9 files changed

+182
-120
lines changed

9 files changed

+182
-120
lines changed

bricks/_common/sources.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ PBIO_SRC_C = $(addprefix lib/pbio/,\
112112
drv/block_device/block_device_test.c \
113113
drv/block_device/block_device_w25qxx_stm32.c \
114114
drv/bluetooth/bluetooth.c \
115+
drv/bluetooth/bluetooth_btstack_control_ev3.c \
115116
drv/bluetooth/bluetooth_btstack_control_gpio.c \
116117
drv/bluetooth/bluetooth_btstack_uart_block_ev3.c \
117118
drv/bluetooth/bluetooth_btstack_uart_block_stm32_hal.c \
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include "bluetooth_btstack_control_ev3.h"
2+
3+
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3
4+
5+
#include <math.h>
6+
7+
#include <btstack.h>
8+
#include <tiam1808/ecap.h>
9+
#include <tiam1808/hw/hw_syscfg0_AM1808.h>
10+
#include <tiam1808/hw/hw_syscfg1_AM1808.h>
11+
#include <tiam1808/hw/hw_types.h>
12+
#include <tiam1808/hw/soc_AM1808.h>
13+
14+
#include <pbio/error.h>
15+
#include <pbio/os.h>
16+
#include "../gpio/gpio_ev3.h"
17+
18+
static const pbdrv_gpio_t pin_bluetooth_enable = PBDRV_GPIO_EV3_PIN(9, 27, 24, 4, 9);
19+
20+
static int ev3_control_off();
21+
22+
static void ev3_control_init(const void *config) {
23+
// From the ev3dev configuration:
24+
//
25+
// There is a PIC microcontroller for interfacing with an Apple MFi
26+
// chip. This interferes with normal Bluetooth operation, so we need
27+
// to make sure it is turned off. Note: The publicly available
28+
// schematics from LEGO don't show that these pins are connected to
29+
// anything, but they are present in the source code from LEGO.
30+
const pbdrv_gpio_t bt_pic_en = PBDRV_GPIO_EV3_PIN(8, 19, 16, 3, 3);
31+
pbdrv_gpio_alt(&bt_pic_en, SYSCFG_PINMUX8_PINMUX8_19_16_GPIO3_3);
32+
pbdrv_gpio_out_low(&bt_pic_en);
33+
// Hold RTS high (we're not ready to receive anything from the PIC).
34+
const pbdrv_gpio_t bt_pic_rts = PBDRV_GPIO_EV3_PIN(9, 7, 4, 4, 14);
35+
pbdrv_gpio_alt(&bt_pic_rts, SYSCFG_PINMUX9_PINMUX9_7_4_GPIO4_14);
36+
pbdrv_gpio_out_high(&bt_pic_rts);
37+
// CTS technically does not need to be configured, but for documentation
38+
// purposes we do.
39+
const pbdrv_gpio_t bt_pic_cts = PBDRV_GPIO_EV3_PIN(12, 3, 0, 5, 7);
40+
pbdrv_gpio_alt(&bt_pic_cts, SYSCFG_PINMUX12_PINMUX12_3_0_GPIO5_7);
41+
pbdrv_gpio_input(&bt_pic_cts);
42+
// Don't interfere with the BT clock's enable pin.
43+
const pbdrv_gpio_t bt_clock_en = PBDRV_GPIO_EV3_PIN(1, 11, 8, 0, 5);
44+
pbdrv_gpio_alt(&bt_clock_en, SYSCFG_PINMUX1_PINMUX1_11_8_GPIO0_5);
45+
pbdrv_gpio_input(&bt_clock_en);
46+
47+
// Configure ECAP2 to emit the slow clock signal for the bluetooth module.
48+
ECAPOperatingModeSelect(SOC_ECAP_2_REGS, ECAP_APWM_MODE);
49+
// Calculate the number of clock ticks the APWM period should last. Note
50+
// that the following float operations are all constant and optimized away.
51+
// APWM is clocked by sysclk2 by default.
52+
// Target frequency is 32.767 kHz, see cc2560 datasheet.
53+
// Note that the APWM module wraps on the cycle after reaching the period
54+
// value, which means we need to subtract one from the desired period to get
55+
// a period length in cycles that matches the desired frequency.
56+
const int aprd = round(SOC_SYSCLK_2_FREQ / 32767.0) - 1;
57+
ECAPAPWMCaptureConfig(SOC_ECAP_2_REGS, aprd / 2, aprd);
58+
// Set the polarity to active high. It doesn't matter which it is but for
59+
// the sake of determinism we set it explicitly.
60+
ECAPAPWMPolarityConfig(SOC_ECAP_2_REGS, ECAP_APWM_ACTIVE_HIGH);
61+
// Disable input and output synchronization.
62+
ECAPSyncInOutSelect(SOC_ECAP_2_REGS, ECAP_SYNC_IN_DISABLE, ECAP_SYNC_OUT_DISABLE);
63+
// Start the counter running.
64+
ECAPCounterControl(SOC_ECAP_2_REGS, ECAP_COUNTER_FREE_RUNNING);
65+
// Set gp0[7] to output the ECAP2 APWM signal.
66+
const pbdrv_gpio_t bluetooth_slow_clock = PBDRV_GPIO_EV3_PIN(1, 3, 0, 0, 7);
67+
pbdrv_gpio_alt(&bluetooth_slow_clock, SYSCFG_PINMUX1_PINMUX1_3_0_ECAP2);
68+
69+
pbdrv_gpio_alt(&pin_bluetooth_enable, SYSCFG_PINMUX9_PINMUX9_27_24_GPIO4_9);
70+
71+
// Start the module in a defined (and disabled) state.
72+
ev3_control_off();
73+
}
74+
75+
static int ev3_control_on() {
76+
// Note: the module is not actually "on" yet, however, the way it signals
77+
// its on-ness is by unblocking our ability to send UART messages. We
78+
// use auto flow control on the UART, so we don't actually need to wait
79+
// for the module to come up here.
80+
pbdrv_gpio_out_high(&pin_bluetooth_enable);
81+
return 0;
82+
}
83+
84+
static int ev3_control_off() {
85+
pbdrv_gpio_out_low(&pin_bluetooth_enable);
86+
return 0;
87+
}
88+
89+
static const btstack_control_t ev3_control = {
90+
.init = &ev3_control_init,
91+
.on = &ev3_control_on,
92+
.off = &ev3_control_off,
93+
.sleep = NULL,
94+
.wake = NULL,
95+
.register_for_power_notifications = NULL,
96+
};
97+
98+
const btstack_control_t *pbdrv_bluetooth_control_ev3_instance(void) {
99+
return &ev3_control;
100+
}
101+
102+
#endif
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef PBIO_DRV_BLUETOOTH_BLUETOOTH_BTSTACK_CONTROL_EV3
2+
#define PBIO_DRV_BLUETOOTH_BLUETOOTH_BTSTACK_CONTROL_EV3
3+
4+
#include <pbdrvconfig.h>
5+
6+
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3
7+
8+
#include <btstack.h>
9+
#include <pbio/os.h>
10+
11+
// Returns the control instance for the EV3. This does a little more than
12+
// the typical control instance -- it's responsible for configuring the slow
13+
// clock and configuring certain pins that interfere with bluetooth operation.
14+
const btstack_control_t *pbdrv_bluetooth_control_ev3_instance(void);
15+
16+
#else
17+
18+
static inline const btstack_control_t *pbdrv_bluetooth_control_ev3_instance(void) {
19+
return NULL;
20+
}
21+
22+
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3
23+
24+
#endif // PBIO_DRV_BLUETOOTH_BLUETOOTH_BTSTACK_CONTROL_EV3

lib/pbio/drv/bluetooth/bluetooth_btstack_uart_block_ev3.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include <pbdrv/config.h>
77

8-
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3_UART
8+
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3
99

1010
#include <assert.h>
1111
#include <stdbool.h>
@@ -14,19 +14,24 @@
1414
#include <btstack.h>
1515
#include <btstack_uart_block.h>
1616
#include <btstack_run_loop.h>
17+
#include <pbdrv/gpio.h>
1718
#include <pbdrv/uart.h>
1819
#include <pbdrv/cache.h>
1920
#include <pbio/os.h>
2021

2122
#include "bluetooth_btstack_uart_block_ev3.h"
23+
#include "../gpio/gpio_ev3.h"
2224
#include "../uart/uart_ev3.h"
2325

2426
#include <tiam1808/armv5/am1808/edma_event.h>
2527
#include <tiam1808/armv5/am1808/interrupt.h>
2628
#include <tiam1808/edma.h>
2729
#include <tiam1808/hw/hw_edma3cc.h>
2830
#include <tiam1808/hw/hw_types.h>
31+
#include <tiam1808/hw/hw_syscfg0_AM1808.h>
32+
#include <tiam1808/hw/hw_syscfg1_AM1808.h>
2933
#include <tiam1808/hw/soc_AM1808.h>
34+
#include <tiam1808/psc.h>
3035
#include <tiam1808/uart.h>
3136

3237
#define DEBUG 0
@@ -119,26 +124,43 @@ static void pbdrv_bluetooth_btstack_classic_poll(struct btstack_data_source *ds,
119124
}
120125

121126
static int pbdrv_bluetooth_btstack_uart_block_ev3_init(const btstack_uart_config_t *config) {
127+
DEBUG_PRINT("[btc] Initializing UART block EV3\n");
122128
block_received = NULL;
123129
block_sent = NULL;
124130

131+
// Before setting up the bluetooth module, turn on the UART.
132+
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
133+
134+
// Configure the UART pins.
135+
const pbdrv_gpio_t bluetooth_uart_rx = PBDRV_GPIO_EV3_PIN(4, 19, 16, 1, 3);
136+
const pbdrv_gpio_t bluetooth_uart_tx = PBDRV_GPIO_EV3_PIN(4, 23, 20, 1, 2);
137+
const pbdrv_gpio_t bluetooth_uart_rts = PBDRV_GPIO_EV3_PIN(0, 27, 24, 0, 9);
138+
const pbdrv_gpio_t bluetooth_uart_cts = PBDRV_GPIO_EV3_PIN(0, 31, 28, 0, 8);
139+
pbdrv_gpio_alt(&bluetooth_uart_rx, SYSCFG_PINMUX4_PINMUX4_19_16_UART2_RXD);
140+
pbdrv_gpio_alt(&bluetooth_uart_tx, SYSCFG_PINMUX4_PINMUX4_23_20_UART2_TXD);
141+
pbdrv_gpio_alt(&bluetooth_uart_rts, SYSCFG_PINMUX0_PINMUX0_27_24_UART2_RTS);
142+
pbdrv_gpio_alt(&bluetooth_uart_cts, SYSCFG_PINMUX0_PINMUX0_31_28_UART2_CTS);
143+
125144
UARTEnable(UART_PORT);
126145
UARTConfigSetExpClk(UART_PORT, SOC_UART_2_MODULE_FREQ, config->baudrate, UART_WORDL_8BITS, UART_OVER_SAMP_RATE_16);
127146

128147
return 0;
129148
}
130149

131150
static int pbdrv_bluetooth_btstack_uart_block_ev3_open(void) {
151+
DEBUG_PRINT("Bluetooth: Opening UART block EV3\n");
132152
write_buf = NULL;
133153
write_buf_len = 0;
134154
read_buf = NULL;
135155
read_buf_len = 0;
136156
dma_write_complete = false;
137157
dma_read_complete = false;
138158

139-
// Set up the FIFOs and auto flow control. The fifo interrupt triggers on
140-
// the first byte received. Note that enabling the FIFO also flushes it.
159+
// Note: this also clears the FIFO in case it contained anything before.
141160
UARTFIFOEnable(UART_PORT);
161+
// Flow control is important for the CC256x: for one thing, the volume of
162+
// data is such that without it we could get into trouble. For another
163+
// thing, pulling CTS low is how the module signals that it's ready to talk.
142164
UARTModemControlSet(UART_PORT, UART_RTS | UART_AUTOFLOW);
143165

144166
// Set up the UART DMA channels.
@@ -155,6 +177,11 @@ static int pbdrv_bluetooth_btstack_uart_block_ev3_open(void) {
155177
static int pbdrv_bluetooth_btstack_uart_block_ev3_close(void) {
156178
btstack_run_loop_disable_data_source_callbacks(&pbdrv_bluetooth_btstack_classic_poll_data_source, DATA_SOURCE_CALLBACK_POLL);
157179
btstack_run_loop_remove_data_source(&pbdrv_bluetooth_btstack_classic_poll_data_source);
180+
181+
UARTDMADisable(UART_PORT, (UART_RX_TRIG_LEVEL_1 | UART_FIFO_MODE));
182+
EDMA3FreeChannel(EDMA_BASE, EDMA3_CHANNEL_TYPE_DMA, DMA_CHA_TX, EDMA3_TRIG_MODE_EVENT, DMA_CHA_TX, DMA_EVENT_QUEUE);
183+
EDMA3FreeChannel(EDMA_BASE, EDMA3_CHANNEL_TYPE_DMA, DMA_CHA_RX, EDMA3_TRIG_MODE_EVENT, DMA_CHA_RX, DMA_EVENT_QUEUE);
184+
UARTDisable(UART_PORT);
158185
return 0;
159186
}
160187

@@ -272,4 +299,4 @@ const btstack_uart_block_t *pbdrv_bluetooth_btstack_uart_block_ev3_instance(void
272299
return &pbdrv_bluetooth_btstack_uart_block_ev3_block_ev3;
273300
}
274301

275-
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3_UART
302+
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3

lib/pbio/drv/bluetooth/bluetooth_btstack_uart_block_ev3.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#include <pbdrv/config.h>
1111

12-
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3_UART
12+
#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3
1313

1414
#include <btstack_uart_block.h>
1515
#include <pbdrv/uart.h>
@@ -23,6 +23,17 @@ const btstack_uart_block_t *pbdrv_bluetooth_btstack_uart_block_ev3_instance(
2323
void pbdrv_bluetooth_btstack_uart_block_ev3_handle_tx_complete(void);
2424
void pbdrv_bluetooth_btstack_uart_block_ev3_handle_rx_complete(void);
2525

26-
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3_UART
26+
#else
27+
28+
static const btstack_uart_block_t *pbdrv_bluetooth_btstack_uart_block_ev3_instance(
29+
void) {
30+
return NULL;
31+
}
32+
static inline void pbdrv_bluetooth_btstack_uart_block_ev3_handle_tx_complete(void) {
33+
}
34+
static inline void pbdrv_bluetooth_btstack_uart_block_ev3_handle_rx_complete(void) {
35+
}
36+
37+
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3
2738

2839
#endif // PBDRV_BLUETOOTH_BLUETOOTH_BTSTACK_UART_BLOCK_EV3_H

lib/pbio/drv/bluetooth/bluetooth_init_cc2560x.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4311,4 +4311,9 @@ pbio_error_t pbdrv_bluetooth_get_init_script(uint16_t lmp_subversion, pbdrv_blue
43114311
}
43124312
}
43134313

4314+
// Note: the cc256x chipset code requres these symbols to be defined, or a link
4315+
// error results. However, we never use them at runtime.
4316+
const uint32_t cc256x_init_script_size;
4317+
const uint8_t cc256x_init_script[] = {};
4318+
43144319
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_CLASSIC

lib/pbio/drv/uart/uart_ev3.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,6 @@ void pbdrv_uart_init(void) {
383383

384384
for (int i = 0; i < PBDRV_CONFIG_UART_EV3_NUM_UART; i++) {
385385
const pbdrv_uart_ev3_platform_data_t *pdata = &pbdrv_uart_ev3_platform_data[i];
386-
if (pdata->base_address == SOC_UART_2_REGS && PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3_UART) {
387-
// UART2 is set up in the Bluetooth driver, since it is fully managed there.
388-
continue;
389-
}
390386
uint8_t *rx_data = pbdrv_uart_rx_data[i];
391387
pbdrv_uart_dev_t *uart = &uart_devs[i];
392388
uart->pdata = pdata;

lib/pbio/platform/ev3/pbdrvconfig.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
#define PBDRV_CONFIG_UART_DEBUG_FIRST_PORT (0)
9494
#define PBDRV_CONFIG_UART_EV3 (1)
9595
#define PBDRV_CONFIG_UART_EV3_PRU (1)
96-
#define PBDRV_CONFIG_UART_EV3_NUM_UART (5)
96+
#define PBDRV_CONFIG_UART_EV3_NUM_UART (4)
9797

9898
#define PBDRV_CONFIG_USB (1)
9999
#define PBDRV_CONFIG_USB_MAX_PACKET_SIZE (512)
@@ -111,5 +111,4 @@
111111

112112
#define PBDRV_CONFIG_BLUETOOTH_CLASSIC (1)
113113
#define PBDRV_CONFIG_BLUETOOTH_BTSTACK_CLASSIC (1)
114-
#define PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3_UART (1)
115-
#define PBDRV_CONFIG_BLUETOOTH_BTSTACK_CONTROL_GPIO (1)
114+
#define PBDRV_CONFIG_BLUETOOTH_BTSTACK_EV3 (1)

0 commit comments

Comments
 (0)