Skip to content

Commit 580f3de

Browse files
committed
platform/ev3: Finish bluetooth configuration.
1 parent b704379 commit 580f3de

File tree

1 file changed

+91
-61
lines changed

1 file changed

+91
-61
lines changed

lib/pbio/platform/ev3/platform.c

Lines changed: 91 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
#include <tiam1808/timer.h>
5656
#include <tiam1808/uart.h>
5757

58+
#include <btstack_chipset_cc256x.h>
59+
5860
#include <umm_malloc.h>
5961

6062
#include <pbio/port_interface.h>
@@ -70,6 +72,7 @@
7072
#include "../../drv/block_device/block_device_ev3.h"
7173
#include "../../drv/bluetooth/bluetooth_btstack_control_gpio.h"
7274
#include "../../drv/bluetooth/bluetooth_btstack_uart_block_ev3.h"
75+
#include "../../drv/bluetooth/bluetooth_btstack_classic.h"
7376
#include "../../drv/button/button_gpio.h"
7477
#include "../../drv/display/display_ev3.h"
7578
#include "../../drv/gpio/gpio_ev3.h"
@@ -769,6 +772,93 @@ const pbdrv_bluetooth_btstack_uart_block_ev3_platform_data_t pbdrv_bluetooth_bts
769772
.uart_id = UART2,
770773
};
771774

775+
const pbdrv_bluetooth_btstack_platform_data_t pbdrv_bluetooth_btstack_platform_data = {
776+
.uart_block_instance = pbdrv_bluetooth_btstack_uart_block_ev3_instance,
777+
.chipset_instance = btstack_chipset_cc256x_instance,
778+
.control_instance = pbdrv_bluetooth_btstack_control_gpio_instance,
779+
};
780+
781+
// The chipset requires for these symbols to be defined. We are not going to
782+
// use them on ev3, though, because the ev3 could have either the cc2560 or the
783+
// cc2560a, and they use different init scripts. We will detect which one to use
784+
// at runtime in the btstack driver.
785+
const uint32_t cc256x_init_script_size;
786+
const uint8_t cc256x_init_script[] = {};
787+
788+
static void setup_bluetooth_pins() {
789+
// Before setting up the bluetooth module, turn on the UART.
790+
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
791+
792+
// Enable UART1 for sync output.
793+
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART1, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
794+
UARTConfigSetExpClk(SOC_UART_1_REGS, SOC_UART_1_MODULE_FREQ, 115200, UART_WORDL_8BITS, UART_OVER_SAMP_RATE_13);
795+
UARTFIFOEnable(SOC_UART_1_REGS);
796+
797+
// From the ev3dev configuration:
798+
//
799+
// There is a PIC microcontroller for interfacing with an Apple MFi
800+
// chip. This interferes with normal Bluetooth operation, so we need
801+
// to make sure it is turned off. Note: The publicly available
802+
// schematics from LEGO don't show that these pins are connected to
803+
// anything, but they are present in the source code from LEGO.
804+
const pbdrv_gpio_t bt_pic_en = PBDRV_GPIO_EV3_PIN(8, 19, 16, 3, 3);
805+
pbdrv_gpio_alt(&bt_pic_en, SYSCFG_PINMUX8_PINMUX8_19_16_GPIO3_3);
806+
pbdrv_gpio_out_low(&bt_pic_en);
807+
// Hold RTS high (we're not ready to receive anything from the PIC).
808+
const pbdrv_gpio_t bt_pic_rts = PBDRV_GPIO_EV3_PIN(9, 7, 4, 4, 14);
809+
pbdrv_gpio_alt(&bt_pic_rts, SYSCFG_PINMUX9_PINMUX9_7_4_GPIO4_14);
810+
pbdrv_gpio_out_high(&bt_pic_rts);
811+
// CTS technically does not need to be configured, but for documentation
812+
// purposes we do.
813+
const pbdrv_gpio_t bt_pic_cts = PBDRV_GPIO_EV3_PIN(12, 3, 0, 5, 7);
814+
pbdrv_gpio_alt(&bt_pic_cts, SYSCFG_PINMUX12_PINMUX12_3_0_GPIO5_7);
815+
pbdrv_gpio_input(&bt_pic_cts);
816+
// Don't interfere with the BT clock's enable pin.
817+
const pbdrv_gpio_t bt_clock_en = PBDRV_GPIO_EV3_PIN(1, 11, 8, 0, 5);
818+
pbdrv_gpio_alt(&bt_clock_en, SYSCFG_PINMUX1_PINMUX1_11_8_GPIO0_5);
819+
pbdrv_gpio_input(&bt_clock_en);
820+
821+
// Configure ECAP2 to emit the slow clock signal for the bluetooth module.
822+
ECAPOperatingModeSelect(SOC_ECAP_2_REGS, ECAP_APWM_MODE);
823+
// Calculate the number of clock ticks the APWM period should last. Note
824+
// that the following float operations are all constant and optimized away.
825+
// APWM is clocked by sysclk2 by default.
826+
// Target frequency is 32.767 kHz, see cc2560 datasheet.
827+
// Note that the APWM module wraps on the cycle after reaching the period
828+
// value, which means we need to subtract one from the desired period to get
829+
// a period length in cycles that matches the desired frequency.
830+
const int aprd = round(SOC_SYSCLK_2_FREQ / 32767.0) - 1;
831+
ECAPAPWMCaptureConfig(SOC_ECAP_2_REGS, aprd / 2, aprd);
832+
// Set the polarity to active high. It doesn't matter which it is but for
833+
// the sake of determinism we set it explicitly.
834+
ECAPAPWMPolarityConfig(SOC_ECAP_2_REGS, ECAP_APWM_ACTIVE_HIGH);
835+
// Disable input and output synchronization.
836+
ECAPSyncInOutSelect(SOC_ECAP_2_REGS, ECAP_SYNC_IN_DISABLE, ECAP_SYNC_OUT_DISABLE);
837+
// Start the counter running.
838+
ECAPCounterControl(SOC_ECAP_2_REGS, ECAP_COUNTER_FREE_RUNNING);
839+
// Set gp0[7] to output the ECAP2 APWM signal.
840+
const pbdrv_gpio_t bluetooth_slow_clock = PBDRV_GPIO_EV3_PIN(1, 3, 0, 0, 7);
841+
pbdrv_gpio_alt(&bluetooth_slow_clock, SYSCFG_PINMUX1_PINMUX1_3_0_ECAP2);
842+
843+
// UART for Bluetooth. Other UARTS are configured by port module.
844+
const pbdrv_gpio_t bluetooth_uart_rx = PBDRV_GPIO_EV3_PIN(4, 19, 16, 1, 3);
845+
const pbdrv_gpio_t bluetooth_uart_tx = PBDRV_GPIO_EV3_PIN(4, 23, 20, 1, 2);
846+
const pbdrv_gpio_t bluetooth_uart_rts = PBDRV_GPIO_EV3_PIN(0, 27, 24, 0, 9);
847+
const pbdrv_gpio_t bluetooth_uart_cts = PBDRV_GPIO_EV3_PIN(0, 31, 28, 0, 8);
848+
pbdrv_gpio_alt(&bluetooth_uart_rx, SYSCFG_PINMUX4_PINMUX4_19_16_UART2_RXD);
849+
pbdrv_gpio_alt(&bluetooth_uart_tx, SYSCFG_PINMUX4_PINMUX4_23_20_UART2_TXD);
850+
pbdrv_gpio_alt(&bluetooth_uart_rts, SYSCFG_PINMUX0_PINMUX0_27_24_UART2_RTS);
851+
pbdrv_gpio_alt(&bluetooth_uart_cts, SYSCFG_PINMUX0_PINMUX0_31_28_UART2_CTS);
852+
853+
// bluetooth nSHUTDN pin low (module off).
854+
pbdrv_gpio_alt(&bluetooth_enable, SYSCFG_PINMUX9_PINMUX9_27_24_GPIO4_9);
855+
pbdrv_gpio_out_low(&bluetooth_enable);
856+
857+
// CTS/RTS aren't used on the other UARTs, so there is no general facility
858+
// for setting up flow control. Set it up directly here.
859+
UARTModemControlSet(SOC_UART_2_REGS, UART_RTS | UART_AUTOFLOW);
860+
}
861+
772862
// Called from assembly code in startup.s. After this, the "main" function in
773863
// lib/pbio/sys/main.c is called. That contains all calls to the driver
774864
// initialization (low level in pbdrv, high level in pbio), and system level
@@ -807,67 +897,7 @@ void SystemInit(void) {
807897
// Disable all pull-up/pull-down groups.
808898
HWREG(SOC_SYSCFG_1_REGS + SYSCFG1_PUPD_ENA) &= ~0xFFFFFFFF;
809899

810-
// UART for Bluetooth. Other UARTS are configured by port module.
811-
const pbdrv_gpio_t bluetooth_uart_rx = PBDRV_GPIO_EV3_PIN(4, 19, 16, 1, 3);
812-
const pbdrv_gpio_t bluetooth_uart_tx = PBDRV_GPIO_EV3_PIN(4, 23, 20, 1, 2);
813-
const pbdrv_gpio_t bluetooth_uart_cts = PBDRV_GPIO_EV3_PIN(0, 31, 28, 0, 8);
814-
const pbdrv_gpio_t bluetooth_uart_rts = PBDRV_GPIO_EV3_PIN(0, 27, 24, 0, 9);
815-
816-
pbdrv_gpio_alt(&bluetooth_uart_rx, SYSCFG_PINMUX4_PINMUX4_19_16_UART2_RXD);
817-
pbdrv_gpio_alt(&bluetooth_uart_tx, SYSCFG_PINMUX4_PINMUX4_23_20_UART2_TXD);
818-
pbdrv_gpio_alt(&bluetooth_uart_cts, SYSCFG_PINMUX0_PINMUX0_31_28_UART2_CTS);
819-
pbdrv_gpio_alt(&bluetooth_uart_rts, SYSCFG_PINMUX0_PINMUX0_27_24_UART2_RTS);
820-
pbdrv_gpio_alt(&bluetooth_enable, SYSCFG_PINMUX4_PINMUX4_27_24_GPIO1_1);
821-
// For power saving, the bluetooth module disabled until its use is
822-
// requested.
823-
pbdrv_gpio_out_low(&bluetooth_enable);
824-
825-
// Configure ECAP2 to emit the slow clock signal for the bluetooth module.
826-
ECAPOperatingModeSelect(SOC_ECAP_2_REGS, ECAP_APWM_MODE);
827-
// Calculate the number of clock ticks the APWM period should last. Note
828-
// that the following float operations are all constant and optimized away.
829-
// APWM is clocked by sysclk2 by default.
830-
// Target frequency is 32.767 kHz, see cc2560 datasheet.
831-
// Note that the APWM module wraps on the cycle after reaching the period
832-
// value, which means we need to subtract one from the desired period to get
833-
// a period length in cycles that matches the desired frequency.
834-
const int aprd = round(SOC_SYSCLK_2_FREQ / 32767.0) - 1;
835-
ECAPAPWMCaptureConfig(SOC_ECAP_2_REGS, aprd / 2, aprd);
836-
// Set the polarity to active high. It doesn't matter which it is but for
837-
// the sake of determinism we set it explicitly.
838-
ECAPAPWMPolarityConfig(SOC_ECAP_2_REGS, ECAP_APWM_ACTIVE_HIGH);
839-
// Disable input and output synchronization.
840-
ECAPSyncInOutSelect(SOC_ECAP_2_REGS, ECAP_SYNC_IN_DISABLE, ECAP_SYNC_OUT_DISABLE);
841-
// Start the counter running.
842-
ECAPCounterControl(SOC_ECAP_2_REGS, ECAP_COUNTER_FREE_RUNNING);
843-
// Set gp0[7] to output the ECAP2 APWM signal.
844-
const pbdrv_gpio_t bluetooth_slow_clock = PBDRV_GPIO_EV3_PIN(1, 3, 0, 0, 7);
845-
pbdrv_gpio_alt(&bluetooth_slow_clock, SYSCFG_PINMUX1_PINMUX1_3_0_ECAP2);
846-
847-
// Don't interfere with the BT clock's enable pin.
848-
const pbdrv_gpio_t bt_clock_en = PBDRV_GPIO_EV3_PIN(1, 11, 8, 0, 5);
849-
pbdrv_gpio_alt(&bt_clock_en, SYSCFG_PINMUX1_PINMUX1_11_8_GPIO0_5);
850-
pbdrv_gpio_input(&bt_clock_en);
851-
852-
// From the ev3dev configuration:
853-
//
854-
// There is a PIC microcontroller for interfacing with an Apple MFi
855-
// chip. This interferes with normal Bluetooth operation, so we need
856-
// to make sure it is turned off. Note: The publicly available
857-
// schematics from LEGO don't show that these pins are connected to
858-
// anything, but they are present in the source code from LEGO.
859-
const pbdrv_gpio_t bt_pic_en = PBDRV_GPIO_EV3_PIN(8, 19, 16, 3, 3);
860-
pbdrv_gpio_alt(&bt_pic_en, SYSCFG_PINMUX8_PINMUX8_19_16_GPIO3_3);
861-
pbdrv_gpio_out_low(&bt_pic_en);
862-
// Hold RTS high (we're not ready to receive anything from the PIC).
863-
const pbdrv_gpio_t bt_pic_rts = PBDRV_GPIO_EV3_PIN(9, 7, 4, 4, 14);
864-
pbdrv_gpio_alt(&bt_pic_rts, SYSCFG_PINMUX9_PINMUX9_7_4_GPIO4_14);
865-
pbdrv_gpio_out_high(&bt_pic_rts);
866-
// CTS technically does not need to be configured, but for documentation
867-
// purposes we do.
868-
const pbdrv_gpio_t bt_pic_cts = PBDRV_GPIO_EV3_PIN(12, 3, 0, 5, 7);
869-
pbdrv_gpio_alt(&bt_pic_cts, SYSCFG_PINMUX12_PINMUX12_3_0_GPIO5_7);
870-
pbdrv_gpio_input(&bt_pic_cts);
900+
setup_bluetooth_pins();
871901

872902
// Read the EV3 Bluetooth MAC address from the I2C boot EEPROM
873903

0 commit comments

Comments
 (0)