mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-03 20:54:18 +00:00
apollo2-em9304: port for em9304 shield on apollo2 evb
This commit is contained in:
parent
161a556908
commit
905e80ca54
38
port/apollo2-em9304/btstack_config.h
Normal file
38
port/apollo2-em9304/btstack_config.h
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// btstack_config.h for EM9304 DVK
|
||||
//
|
||||
|
||||
#ifndef __BTSTACK_CONFIG
|
||||
#define __BTSTACK_CONFIG
|
||||
|
||||
// Port related features
|
||||
#define HAVE_EMBEDDED_TIME_MS
|
||||
|
||||
// BTstack features that can be enabled
|
||||
#define ENABLE_BLE
|
||||
#define ENABLE_LE_PERIPHERAL
|
||||
#define ENABLE_LE_CENTRAL
|
||||
#define ENABLE_LE_DATA_LENGTH_EXTENSION
|
||||
#define ENABLE_LOG_INFO
|
||||
#define ENABLE_LOG_ERROR
|
||||
|
||||
// BTstack configuration. buffers, sizes, ...
|
||||
#define HCI_ACL_PAYLOAD_SIZE 100
|
||||
#define MAX_NR_WHITELIST_ENTRIES 1
|
||||
#define MAX_NR_HCI_CONNECTIONS 1
|
||||
#define MAX_NR_SM_LOOKUP_ENTRIES 3
|
||||
#define MAX_NR_L2CAP_SERVICES 1
|
||||
#define MAX_NR_L2CAP_CHANNELS 1
|
||||
#define MAX_NR_GATT_CLIENTS 1
|
||||
|
||||
#define MAX_NR_RFCOMM_MULTIPLEXERS 0
|
||||
#define MAX_NR_RFCOMM_SERVICES 0
|
||||
#define MAX_NR_RFCOMM_CHANNELS 0
|
||||
#define MAX_NR_HFP_CONNECTIONS 0
|
||||
#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 0
|
||||
#define MAX_NR_BNEP_SERVICES 0
|
||||
#define MAX_NR_BNEP_CHANNELS 0
|
||||
#define MAX_NR_SERVICE_RECORD_ITEMS 1
|
||||
#define MAX_NR_LE_DEVICE_DB_ENTRIES 1
|
||||
|
||||
#endif
|
508
port/apollo2-em9304/btstack_port.c
Normal file
508
port/apollo2-em9304/btstack_port.c
Normal file
@ -0,0 +1,508 @@
|
||||
//
|
||||
// BTstack port for Apolle 2 EVB with EM9304 shield
|
||||
//
|
||||
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp.h"
|
||||
#include "am_util.h"
|
||||
#include "am_devices_em9304.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Insert compiler version at compile time.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define STRINGIZE_VAL(n) STRINGIZE_VAL2(n)
|
||||
#define STRINGIZE_VAL2(n) #n
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define COMPILER_VERSION ("GCC " __VERSION__)
|
||||
#elif defined(__ARMCC_VERSION)
|
||||
#define COMPILER_VERSION ("ARMCC " STRINGIZE_VAL(__ARMCC_VERSION))
|
||||
#elif defined(__KEIL__)
|
||||
#define COMPILER_VERSION "KEIL_CARM " STRINGIZE_VAL(__CA__)
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#define COMPILER_VERSION __VERSION__
|
||||
#else
|
||||
#define COMPILER_VERSION "Compiler unknown"
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// IOM SPI Configuration for EM9304
|
||||
//
|
||||
//*****************************************************************************
|
||||
const am_hal_iom_config_t g_sEm9304IOMConfigSPI =
|
||||
{
|
||||
.ui32ClockFrequency = AM_HAL_IOM_8MHZ,
|
||||
.ui32InterfaceMode = AM_HAL_IOM_SPIMODE,
|
||||
.ui8WriteThreshold = 20,
|
||||
.ui8ReadThreshold = 20,
|
||||
.bSPHA = 0,
|
||||
.bSPOL = 0,
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// UART configuration settings.
|
||||
//
|
||||
//*****************************************************************************
|
||||
am_hal_uart_config_t g_sUartConfig =
|
||||
{
|
||||
.ui32BaudRate = 115200,
|
||||
.ui32DataBits = AM_HAL_UART_DATA_BITS_8,
|
||||
.bTwoStopBits = false,
|
||||
.ui32Parity = AM_HAL_UART_PARITY_NONE,
|
||||
.ui32FlowCtrl = AM_HAL_UART_FLOW_CTRL_NONE,
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Initialize the UART
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
uart_init(uint32_t ui32Module)
|
||||
{
|
||||
//
|
||||
// Make sure the UART RX and TX pins are enabled.
|
||||
//
|
||||
am_bsp_pin_enable(COM_UART_TX);
|
||||
am_bsp_pin_enable(COM_UART_RX);
|
||||
|
||||
//
|
||||
// Power on the selected UART
|
||||
//
|
||||
am_hal_uart_pwrctrl_enable(ui32Module);
|
||||
|
||||
//
|
||||
// Start the UART interface, apply the desired configuration settings, and
|
||||
// enable the FIFOs.
|
||||
//
|
||||
am_hal_uart_clock_enable(ui32Module);
|
||||
|
||||
//
|
||||
// Disable the UART before configuring it.
|
||||
//
|
||||
am_hal_uart_disable(ui32Module);
|
||||
|
||||
//
|
||||
// Configure the UART.
|
||||
//
|
||||
am_hal_uart_config(ui32Module, &g_sUartConfig);
|
||||
|
||||
//
|
||||
// Enable the UART FIFO.
|
||||
//
|
||||
am_hal_uart_fifo_config(ui32Module, AM_HAL_UART_TX_FIFO_1_2 | AM_HAL_UART_RX_FIFO_1_2);
|
||||
|
||||
//
|
||||
// Enable the UART.
|
||||
//
|
||||
am_hal_uart_enable(ui32Module);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Disable the UART
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
uart_disable(uint32_t ui32Module)
|
||||
{
|
||||
//
|
||||
// Clear all interrupts before sleeping as having a pending UART interrupt
|
||||
// burns power.
|
||||
//
|
||||
am_hal_uart_int_clear(ui32Module, 0xFFFFFFFF);
|
||||
|
||||
//
|
||||
// Disable the UART.
|
||||
//
|
||||
am_hal_uart_disable(ui32Module);
|
||||
|
||||
//
|
||||
// Disable the UART pins.
|
||||
//
|
||||
am_bsp_pin_disable(COM_UART_TX);
|
||||
am_bsp_pin_disable(COM_UART_RX);
|
||||
|
||||
//
|
||||
// Disable the UART clock.
|
||||
//
|
||||
am_hal_uart_clock_disable(ui32Module);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Initialize the EM9304 BLE Controller
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
am_devices_em9304_spi_init(uint32_t ui32Module, const am_hal_iom_config_t *psIomConfig)
|
||||
{
|
||||
if ( AM_REGn(IOMSTR, ui32Module, CFG) & AM_REG_IOMSTR_CFG_IFCEN_M )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(AM_PART_APOLLO2)
|
||||
am_hal_iom_pwrctrl_enable(ui32Module);
|
||||
#endif
|
||||
//
|
||||
// Setup the pins for SPI mode.
|
||||
//
|
||||
am_bsp_iom_spi_pins_enable(ui32Module);
|
||||
|
||||
//
|
||||
// Set the required configuration settings for the IOM.
|
||||
//
|
||||
am_hal_iom_config(ui32Module, psIomConfig);
|
||||
|
||||
// Enable spi
|
||||
am_hal_iom_enable(ui32Module);
|
||||
}
|
||||
|
||||
void
|
||||
configure_em9304_pins(void)
|
||||
{
|
||||
am_bsp_pin_enable(EM9304_CS);
|
||||
am_bsp_pin_enable(EM9304_INT);
|
||||
|
||||
am_hal_gpio_out_bit_set(AM_BSP_GPIO_EM9304_CS);
|
||||
|
||||
am_hal_gpio_int_polarity_bit_set(AM_BSP_GPIO_EM9304_INT, AM_HAL_GPIO_RISING);
|
||||
am_hal_gpio_int_clear(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT));
|
||||
am_hal_gpio_int_enable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT));
|
||||
}
|
||||
|
||||
void
|
||||
em9304_init(void)
|
||||
{
|
||||
//
|
||||
// Assert RESET to the Telink device.
|
||||
//
|
||||
am_hal_gpio_pin_config(AM_BSP_GPIO_EM9304_RESET, AM_HAL_GPIO_OUTPUT);
|
||||
am_hal_gpio_out_bit_clear(AM_BSP_GPIO_EM9304_RESET);
|
||||
|
||||
//
|
||||
// Setup SPI interface for EM9304
|
||||
//
|
||||
configure_em9304_pins();
|
||||
am_devices_em9304_spi_init(AM_BSP_EM9304_IOM, &g_sEm9304IOMConfigSPI);
|
||||
|
||||
//
|
||||
// Delay for 20ms to make sure the em device gets ready for commands.
|
||||
//
|
||||
am_util_delay_ms(5);
|
||||
|
||||
//
|
||||
// Enable the IOM and GPIO interrupt handlers.
|
||||
//
|
||||
am_hal_gpio_out_bit_set(AM_BSP_GPIO_EM9304_RESET);
|
||||
|
||||
am_util_delay_ms(20);
|
||||
}
|
||||
|
||||
// hal_cpu.h implementation
|
||||
#include "hal_cpu.h"
|
||||
|
||||
void hal_cpu_disable_irqs(void){
|
||||
am_hal_interrupt_master_disable();
|
||||
}
|
||||
|
||||
void hal_cpu_enable_irqs(void){
|
||||
am_hal_interrupt_master_enable();
|
||||
}
|
||||
|
||||
void hal_cpu_enable_irqs_and_sleep(void){
|
||||
am_hal_interrupt_master_enable();
|
||||
__asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag
|
||||
}
|
||||
|
||||
|
||||
// hal_time_ms.h
|
||||
#include "hal_time_ms.h"
|
||||
uint32_t hal_time_ms(void){
|
||||
return am_hal_systick_count();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use USART_CONSOLE as a console.
|
||||
* This is a syscall for newlib
|
||||
* @param file
|
||||
* @param ptr
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
int _write(int file, char *ptr, int len);
|
||||
int _write(int file, char *ptr, int len){
|
||||
#if 1
|
||||
uint8_t cr = '\r';
|
||||
int i;
|
||||
|
||||
if (file == STDOUT_FILENO || file == STDERR_FILENO) {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (ptr[i] == '\n') {
|
||||
am_hal_uart_char_transmit_polled( AM_BSP_UART_PRINT_INST, cr );
|
||||
}
|
||||
am_hal_uart_char_transmit_polled( AM_BSP_UART_PRINT_INST, ptr[i]);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
errno = EIO;
|
||||
return -1;
|
||||
#else
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
int _read(int file, char * ptr, int len){
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)len;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _close(int file){
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _isatty(int file){
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _lseek(int file){
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fstat(int file){
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void * _sbrk(intptr_t increment){
|
||||
return (void*) -1;
|
||||
}
|
||||
|
||||
|
||||
// hal_em9304_spi.h
|
||||
#include "hal_em9304_spi.h"
|
||||
|
||||
static void (*hal_em9304_spi_transfer_done_callback)(void);
|
||||
static void (*hal_em9304_spi_ready_callback)(void);
|
||||
|
||||
#if (0 == AM_BSP_EM9304_IOM)
|
||||
void
|
||||
am_iomaster0_isr(void)
|
||||
{
|
||||
uint32_t ui32IntStatus;
|
||||
|
||||
//
|
||||
// Read and clear the interrupt status.
|
||||
//
|
||||
ui32IntStatus = am_hal_iom_int_status_get(0, false);
|
||||
am_hal_iom_int_clear(0, ui32IntStatus);
|
||||
|
||||
//
|
||||
// Service FIFO interrupts as necessary, and call IOM callbacks as
|
||||
// transfers are completed.
|
||||
//
|
||||
am_hal_iom_int_service(0, ui32IntStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AM_PART_APOLLO2)
|
||||
#if (5 == AM_BSP_EM9304_IOM)
|
||||
void
|
||||
am_iomaster5_isr(void)
|
||||
{
|
||||
uint32_t ui32IntStatus;
|
||||
|
||||
//
|
||||
// Read and clear the interrupt status.
|
||||
//
|
||||
ui32IntStatus = am_hal_iom_int_status_get(5, false);
|
||||
am_hal_iom_int_clear(5, ui32IntStatus);
|
||||
|
||||
//
|
||||
// Service FIFO interrupts as necessary, and call IOM callbacks as
|
||||
// transfers are completed.
|
||||
//
|
||||
am_hal_iom_int_service(5, ui32IntStatus);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void
|
||||
am_gpio_isr(void)
|
||||
{
|
||||
uint64_t ui64Status;
|
||||
|
||||
//
|
||||
// Check and clear the GPIO interrupt status
|
||||
//
|
||||
ui64Status = am_hal_gpio_int_status_get(true);
|
||||
am_hal_gpio_int_clear(ui64Status);
|
||||
|
||||
//
|
||||
// Check to see if this was a wakeup event from the BLE radio.
|
||||
//
|
||||
if ( ui64Status & AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT) )
|
||||
{
|
||||
if (hal_em9304_spi_ready_callback){
|
||||
(*hal_em9304_spi_ready_callback)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hal_em9304_spi_enable_ready_interrupt(void){
|
||||
am_hal_gpio_int_enable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT));
|
||||
}
|
||||
|
||||
void hal_em9304_spi_disable_ready_interrupt(void){
|
||||
am_hal_gpio_int_disable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT));
|
||||
}
|
||||
|
||||
void hal_em9304_spi_set_ready_callback(void (*done)(void)){
|
||||
hal_em9304_spi_ready_callback = done;
|
||||
}
|
||||
|
||||
int hal_em9304_spi_get_ready(void){
|
||||
return am_hal_gpio_input_read() & AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT);
|
||||
}
|
||||
|
||||
void hal_em9304_spi_init(void){
|
||||
hal_em9304_spi_disable_ready_interrupt();
|
||||
}
|
||||
|
||||
void hal_em9304_spi_deinit(void){
|
||||
hal_em9304_spi_disable_ready_interrupt();
|
||||
}
|
||||
|
||||
void hal_em9304_spi_set_transfer_done_callback(void (*done)(void)){
|
||||
hal_em9304_spi_transfer_done_callback = done;
|
||||
}
|
||||
|
||||
void hal_em9304_spi_set_chip_select(int enable){
|
||||
if (enable){
|
||||
am_hal_gpio_out_bit_clear(AM_BSP_GPIO_EM9304_CS);
|
||||
} else {
|
||||
am_hal_gpio_out_bit_set(AM_BSP_GPIO_EM9304_CS);
|
||||
}
|
||||
}
|
||||
|
||||
void hal_em9304_spi_transceive(const uint8_t * tx_data, uint8_t * rx_data, uint16_t len){
|
||||
// TODO: handle tx_data/rx_data not aligned
|
||||
// TODO: support non-blocking full duplex
|
||||
uint32_t ui32ChipSelect = 0;
|
||||
// TODO: Use Full Duplex with Interrupt callback
|
||||
// NOTE: Full Duplex only supported on Apollo2
|
||||
// NOTE: Enabling Full Duplex causes am_hal_iom_spi_write_nq to block (as bytes ready returns number of bytes written)
|
||||
// AM_REGn(IOMSTR, ui32Module, CFG) |= AM_REG_IOMSTR_CFG_FULLDUP(1);
|
||||
am_hal_iom_spi_fullduplex_nq(AM_BSP_EM9304_IOM, ui32ChipSelect, (uint32_t *) tx_data, (uint32_t *) rx_data, len, AM_HAL_IOM_RAW);
|
||||
(*hal_em9304_spi_transfer_done_callback)();
|
||||
return;
|
||||
}
|
||||
|
||||
void hal_em9304_spi_transmit(const uint8_t * tx_data, uint16_t len){
|
||||
// TODO: handle tx_data/rx_data not aligned
|
||||
uint32_t ui32ChipSelect = 0;
|
||||
am_hal_iom_spi_write_nb(AM_BSP_EM9304_IOM, ui32ChipSelect, (uint32_t *) tx_data, len, AM_HAL_IOM_RAW, hal_em9304_spi_transfer_done_callback);
|
||||
}
|
||||
|
||||
void hal_em9304_spi_receive(uint8_t * rx_data, uint16_t len){
|
||||
// TODO: handle tx_data/rx_data not aligned
|
||||
// TODO: support non-blocking full duplex
|
||||
uint32_t ui32ChipSelect = 0;
|
||||
am_hal_iom_spi_read_nb(AM_BSP_EM9304_IOM, ui32ChipSelect, (uint32_t *) rx_data, len, AM_HAL_IOM_RAW, hal_em9304_spi_transfer_done_callback);
|
||||
}
|
||||
|
||||
int hal_em9304_spi_get_fullduplex_support(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Main
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
// EM 9304 SPI Master HCI Implementation
|
||||
const uint8_t hci_reset_2[] = { 0x01, 0x03, 0x0c, 0x00 };
|
||||
|
||||
#include "btstack_run_loop.h"
|
||||
#include "btstack_run_loop_embedded.h"
|
||||
#include "btstack_memory.h"
|
||||
#include "hci_dump.h"
|
||||
|
||||
int btstack_main(int argc, const char * argv[]);
|
||||
int main(void)
|
||||
{
|
||||
//
|
||||
// Set the clock frequency.
|
||||
//
|
||||
am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX);
|
||||
|
||||
//
|
||||
// Set the default cache configuration
|
||||
//
|
||||
am_hal_cachectrl_enable(&am_hal_cachectrl_defaults);
|
||||
|
||||
//
|
||||
// Configure the board for low power operation.
|
||||
//
|
||||
am_bsp_low_power_init();
|
||||
|
||||
//
|
||||
// Initialize the printf interface for UART output.
|
||||
//
|
||||
am_util_stdio_printf_init((am_util_stdio_print_char_t)am_bsp_uart_string_print);
|
||||
|
||||
//
|
||||
// Configure and enable the UART.
|
||||
//
|
||||
uart_init(AM_BSP_UART_PRINT_INST);
|
||||
|
||||
//
|
||||
// Reboot and configure em9304.
|
||||
//
|
||||
em9304_init();
|
||||
|
||||
am_hal_interrupt_enable(AM_HAL_INTERRUPT_GPIO);
|
||||
|
||||
//
|
||||
// Enable IOM SPI interrupts.
|
||||
//
|
||||
am_hal_iom_int_clear(AM_BSP_EM9304_IOM, AM_HAL_IOM_INT_CMDCMP | AM_HAL_IOM_INT_THR);
|
||||
am_hal_iom_int_enable(AM_BSP_EM9304_IOM, AM_HAL_IOM_INT_CMDCMP | AM_HAL_IOM_INT_THR);
|
||||
|
||||
#if (0 == AM_BSP_EM9304_IOM)
|
||||
am_hal_interrupt_enable(AM_HAL_INTERRUPT_IOMASTER0);
|
||||
#elif (5 == AM_BSP_EM9304_IOM)
|
||||
am_hal_interrupt_enable(AM_HAL_INTERRUPT_IOMASTER5);
|
||||
#endif
|
||||
|
||||
// start with BTstack init - especially configure HCI Transport
|
||||
btstack_memory_init();
|
||||
btstack_run_loop_init(btstack_run_loop_embedded_get_instance());
|
||||
|
||||
// init HCI
|
||||
hci_init(hci_transport_em9304_spi_instance(btstack_em9304_spi_embedded_instance()), NULL);
|
||||
hci_dump_open( NULL, HCI_DUMP_STDOUT );
|
||||
|
||||
// hand over control to btstack_main()..
|
||||
|
||||
// turn on!
|
||||
// hci_power_control(HCI_POWER_ON);
|
||||
btstack_main(0, NULL);
|
||||
|
||||
btstack_run_loop_execute();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user