1905e80caSMatthias Ringwald // 2905e80caSMatthias Ringwald // BTstack port for Apolle 2 EVB with EM9304 shield 3905e80caSMatthias Ringwald // 4905e80caSMatthias Ringwald 5905e80caSMatthias Ringwald #include "am_mcu_apollo.h" 6905e80caSMatthias Ringwald #include "am_bsp.h" 7905e80caSMatthias Ringwald #include "am_util.h" 8905e80caSMatthias Ringwald #include "am_devices_em9304.h" 9905e80caSMatthias Ringwald 10905e80caSMatthias Ringwald //***************************************************************************** 11905e80caSMatthias Ringwald // 12905e80caSMatthias Ringwald // Insert compiler version at compile time. 13905e80caSMatthias Ringwald // 14905e80caSMatthias Ringwald //***************************************************************************** 15905e80caSMatthias Ringwald #define STRINGIZE_VAL(n) STRINGIZE_VAL2(n) 16905e80caSMatthias Ringwald #define STRINGIZE_VAL2(n) #n 17905e80caSMatthias Ringwald 18905e80caSMatthias Ringwald #ifdef __GNUC__ 19905e80caSMatthias Ringwald #define COMPILER_VERSION ("GCC " __VERSION__) 20905e80caSMatthias Ringwald #elif defined(__ARMCC_VERSION) 21905e80caSMatthias Ringwald #define COMPILER_VERSION ("ARMCC " STRINGIZE_VAL(__ARMCC_VERSION)) 22905e80caSMatthias Ringwald #elif defined(__KEIL__) 23905e80caSMatthias Ringwald #define COMPILER_VERSION "KEIL_CARM " STRINGIZE_VAL(__CA__) 24905e80caSMatthias Ringwald #elif defined(__IAR_SYSTEMS_ICC__) 25905e80caSMatthias Ringwald #define COMPILER_VERSION __VERSION__ 26905e80caSMatthias Ringwald #else 27905e80caSMatthias Ringwald #define COMPILER_VERSION "Compiler unknown" 28905e80caSMatthias Ringwald #endif 29905e80caSMatthias Ringwald 30905e80caSMatthias Ringwald //***************************************************************************** 31905e80caSMatthias Ringwald // 32905e80caSMatthias Ringwald // IOM SPI Configuration for EM9304 33905e80caSMatthias Ringwald // 34905e80caSMatthias Ringwald //***************************************************************************** 35905e80caSMatthias Ringwald const am_hal_iom_config_t g_sEm9304IOMConfigSPI = 36905e80caSMatthias Ringwald { 37905e80caSMatthias Ringwald .ui32ClockFrequency = AM_HAL_IOM_8MHZ, 38905e80caSMatthias Ringwald .ui32InterfaceMode = AM_HAL_IOM_SPIMODE, 39905e80caSMatthias Ringwald .ui8WriteThreshold = 20, 40905e80caSMatthias Ringwald .ui8ReadThreshold = 20, 41905e80caSMatthias Ringwald .bSPHA = 0, 42905e80caSMatthias Ringwald .bSPOL = 0, 43905e80caSMatthias Ringwald }; 44905e80caSMatthias Ringwald 45905e80caSMatthias Ringwald //***************************************************************************** 46905e80caSMatthias Ringwald // 47905e80caSMatthias Ringwald // UART configuration settings. 48905e80caSMatthias Ringwald // 49905e80caSMatthias Ringwald //***************************************************************************** 50905e80caSMatthias Ringwald am_hal_uart_config_t g_sUartConfig = 51905e80caSMatthias Ringwald { 52905e80caSMatthias Ringwald .ui32BaudRate = 115200, 53905e80caSMatthias Ringwald .ui32DataBits = AM_HAL_UART_DATA_BITS_8, 54905e80caSMatthias Ringwald .bTwoStopBits = false, 55905e80caSMatthias Ringwald .ui32Parity = AM_HAL_UART_PARITY_NONE, 56905e80caSMatthias Ringwald .ui32FlowCtrl = AM_HAL_UART_FLOW_CTRL_NONE, 57905e80caSMatthias Ringwald }; 58905e80caSMatthias Ringwald 59905e80caSMatthias Ringwald //***************************************************************************** 60905e80caSMatthias Ringwald // 61905e80caSMatthias Ringwald // Initialize the UART 62905e80caSMatthias Ringwald // 63905e80caSMatthias Ringwald //***************************************************************************** 64905e80caSMatthias Ringwald void 65905e80caSMatthias Ringwald uart_init(uint32_t ui32Module) 66905e80caSMatthias Ringwald { 67905e80caSMatthias Ringwald // 68905e80caSMatthias Ringwald // Make sure the UART RX and TX pins are enabled. 69905e80caSMatthias Ringwald // 70905e80caSMatthias Ringwald am_bsp_pin_enable(COM_UART_TX); 71905e80caSMatthias Ringwald am_bsp_pin_enable(COM_UART_RX); 72905e80caSMatthias Ringwald 73905e80caSMatthias Ringwald // 74905e80caSMatthias Ringwald // Power on the selected UART 75905e80caSMatthias Ringwald // 76905e80caSMatthias Ringwald am_hal_uart_pwrctrl_enable(ui32Module); 77905e80caSMatthias Ringwald 78905e80caSMatthias Ringwald // 79905e80caSMatthias Ringwald // Start the UART interface, apply the desired configuration settings, and 80905e80caSMatthias Ringwald // enable the FIFOs. 81905e80caSMatthias Ringwald // 82905e80caSMatthias Ringwald am_hal_uart_clock_enable(ui32Module); 83905e80caSMatthias Ringwald 84905e80caSMatthias Ringwald // 85905e80caSMatthias Ringwald // Disable the UART before configuring it. 86905e80caSMatthias Ringwald // 87905e80caSMatthias Ringwald am_hal_uart_disable(ui32Module); 88905e80caSMatthias Ringwald 89905e80caSMatthias Ringwald // 90905e80caSMatthias Ringwald // Configure the UART. 91905e80caSMatthias Ringwald // 92905e80caSMatthias Ringwald am_hal_uart_config(ui32Module, &g_sUartConfig); 93905e80caSMatthias Ringwald 94905e80caSMatthias Ringwald // 95905e80caSMatthias Ringwald // Enable the UART FIFO. 96905e80caSMatthias Ringwald // 97905e80caSMatthias Ringwald am_hal_uart_fifo_config(ui32Module, AM_HAL_UART_TX_FIFO_1_2 | AM_HAL_UART_RX_FIFO_1_2); 98905e80caSMatthias Ringwald 99905e80caSMatthias Ringwald // 100905e80caSMatthias Ringwald // Enable the UART. 101905e80caSMatthias Ringwald // 102905e80caSMatthias Ringwald am_hal_uart_enable(ui32Module); 103905e80caSMatthias Ringwald } 104905e80caSMatthias Ringwald 105905e80caSMatthias Ringwald //***************************************************************************** 106905e80caSMatthias Ringwald // 107905e80caSMatthias Ringwald // Disable the UART 108905e80caSMatthias Ringwald // 109905e80caSMatthias Ringwald //***************************************************************************** 110905e80caSMatthias Ringwald void 111905e80caSMatthias Ringwald uart_disable(uint32_t ui32Module) 112905e80caSMatthias Ringwald { 113905e80caSMatthias Ringwald // 114905e80caSMatthias Ringwald // Clear all interrupts before sleeping as having a pending UART interrupt 115905e80caSMatthias Ringwald // burns power. 116905e80caSMatthias Ringwald // 117905e80caSMatthias Ringwald am_hal_uart_int_clear(ui32Module, 0xFFFFFFFF); 118905e80caSMatthias Ringwald 119905e80caSMatthias Ringwald // 120905e80caSMatthias Ringwald // Disable the UART. 121905e80caSMatthias Ringwald // 122905e80caSMatthias Ringwald am_hal_uart_disable(ui32Module); 123905e80caSMatthias Ringwald 124905e80caSMatthias Ringwald // 125905e80caSMatthias Ringwald // Disable the UART pins. 126905e80caSMatthias Ringwald // 127905e80caSMatthias Ringwald am_bsp_pin_disable(COM_UART_TX); 128905e80caSMatthias Ringwald am_bsp_pin_disable(COM_UART_RX); 129905e80caSMatthias Ringwald 130905e80caSMatthias Ringwald // 131905e80caSMatthias Ringwald // Disable the UART clock. 132905e80caSMatthias Ringwald // 133905e80caSMatthias Ringwald am_hal_uart_clock_disable(ui32Module); 134905e80caSMatthias Ringwald } 135905e80caSMatthias Ringwald 136905e80caSMatthias Ringwald //***************************************************************************** 137905e80caSMatthias Ringwald // 138905e80caSMatthias Ringwald // Initialize the EM9304 BLE Controller 139905e80caSMatthias Ringwald // 140905e80caSMatthias Ringwald //***************************************************************************** 141905e80caSMatthias Ringwald void 142905e80caSMatthias Ringwald am_devices_em9304_spi_init(uint32_t ui32Module, const am_hal_iom_config_t *psIomConfig) 143905e80caSMatthias Ringwald { 144905e80caSMatthias Ringwald if ( AM_REGn(IOMSTR, ui32Module, CFG) & AM_REG_IOMSTR_CFG_IFCEN_M ) 145905e80caSMatthias Ringwald { 146905e80caSMatthias Ringwald return; 147905e80caSMatthias Ringwald } 148905e80caSMatthias Ringwald 149905e80caSMatthias Ringwald #if defined(AM_PART_APOLLO2) 150905e80caSMatthias Ringwald am_hal_iom_pwrctrl_enable(ui32Module); 151905e80caSMatthias Ringwald #endif 152905e80caSMatthias Ringwald // 153905e80caSMatthias Ringwald // Setup the pins for SPI mode. 154905e80caSMatthias Ringwald // 155905e80caSMatthias Ringwald am_bsp_iom_spi_pins_enable(ui32Module); 156905e80caSMatthias Ringwald 157905e80caSMatthias Ringwald // 158905e80caSMatthias Ringwald // Set the required configuration settings for the IOM. 159905e80caSMatthias Ringwald // 160905e80caSMatthias Ringwald am_hal_iom_config(ui32Module, psIomConfig); 161905e80caSMatthias Ringwald 162905e80caSMatthias Ringwald // Enable spi 163905e80caSMatthias Ringwald am_hal_iom_enable(ui32Module); 164905e80caSMatthias Ringwald } 165905e80caSMatthias Ringwald 166905e80caSMatthias Ringwald void 167905e80caSMatthias Ringwald configure_em9304_pins(void) 168905e80caSMatthias Ringwald { 169905e80caSMatthias Ringwald am_bsp_pin_enable(EM9304_CS); 170905e80caSMatthias Ringwald am_bsp_pin_enable(EM9304_INT); 171905e80caSMatthias Ringwald 172905e80caSMatthias Ringwald am_hal_gpio_out_bit_set(AM_BSP_GPIO_EM9304_CS); 173905e80caSMatthias Ringwald 174905e80caSMatthias Ringwald am_hal_gpio_int_polarity_bit_set(AM_BSP_GPIO_EM9304_INT, AM_HAL_GPIO_RISING); 175905e80caSMatthias Ringwald am_hal_gpio_int_clear(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT)); 176905e80caSMatthias Ringwald am_hal_gpio_int_enable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT)); 177905e80caSMatthias Ringwald } 178905e80caSMatthias Ringwald 179905e80caSMatthias Ringwald void 180905e80caSMatthias Ringwald em9304_init(void) 181905e80caSMatthias Ringwald { 182905e80caSMatthias Ringwald // 183905e80caSMatthias Ringwald // Assert RESET to the Telink device. 184905e80caSMatthias Ringwald // 185905e80caSMatthias Ringwald am_hal_gpio_pin_config(AM_BSP_GPIO_EM9304_RESET, AM_HAL_GPIO_OUTPUT); 186905e80caSMatthias Ringwald am_hal_gpio_out_bit_clear(AM_BSP_GPIO_EM9304_RESET); 187905e80caSMatthias Ringwald 188905e80caSMatthias Ringwald // 189905e80caSMatthias Ringwald // Setup SPI interface for EM9304 190905e80caSMatthias Ringwald // 191905e80caSMatthias Ringwald configure_em9304_pins(); 192905e80caSMatthias Ringwald am_devices_em9304_spi_init(AM_BSP_EM9304_IOM, &g_sEm9304IOMConfigSPI); 193905e80caSMatthias Ringwald 194905e80caSMatthias Ringwald // 195905e80caSMatthias Ringwald // Delay for 20ms to make sure the em device gets ready for commands. 196905e80caSMatthias Ringwald // 197905e80caSMatthias Ringwald am_util_delay_ms(5); 198905e80caSMatthias Ringwald 199905e80caSMatthias Ringwald // 200905e80caSMatthias Ringwald // Enable the IOM and GPIO interrupt handlers. 201905e80caSMatthias Ringwald // 202905e80caSMatthias Ringwald am_hal_gpio_out_bit_set(AM_BSP_GPIO_EM9304_RESET); 203905e80caSMatthias Ringwald 204905e80caSMatthias Ringwald am_util_delay_ms(20); 205905e80caSMatthias Ringwald } 206905e80caSMatthias Ringwald 207905e80caSMatthias Ringwald // hal_cpu.h implementation 208905e80caSMatthias Ringwald #include "hal_cpu.h" 209905e80caSMatthias Ringwald 210905e80caSMatthias Ringwald void hal_cpu_disable_irqs(void){ 211905e80caSMatthias Ringwald am_hal_interrupt_master_disable(); 212905e80caSMatthias Ringwald } 213905e80caSMatthias Ringwald 214905e80caSMatthias Ringwald void hal_cpu_enable_irqs(void){ 215905e80caSMatthias Ringwald am_hal_interrupt_master_enable(); 216905e80caSMatthias Ringwald } 217905e80caSMatthias Ringwald 218905e80caSMatthias Ringwald void hal_cpu_enable_irqs_and_sleep(void){ 219905e80caSMatthias Ringwald am_hal_interrupt_master_enable(); 220905e80caSMatthias Ringwald __asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag 221905e80caSMatthias Ringwald } 222905e80caSMatthias Ringwald 223905e80caSMatthias Ringwald 224905e80caSMatthias Ringwald // hal_time_ms.h 225905e80caSMatthias Ringwald #include "hal_time_ms.h" 226905e80caSMatthias Ringwald uint32_t hal_time_ms(void){ 227c5ae0d23SMatthias Ringwald return am_hal_stimer_counter_get(); 228905e80caSMatthias Ringwald } 229905e80caSMatthias Ringwald 230905e80caSMatthias Ringwald 231905e80caSMatthias Ringwald /** 232905e80caSMatthias Ringwald * Use USART_CONSOLE as a console. 233905e80caSMatthias Ringwald * This is a syscall for newlib 234905e80caSMatthias Ringwald * @param file 235905e80caSMatthias Ringwald * @param ptr 236905e80caSMatthias Ringwald * @param len 237905e80caSMatthias Ringwald * @return 238905e80caSMatthias Ringwald */ 239905e80caSMatthias Ringwald #include <stdio.h> 240905e80caSMatthias Ringwald #include <unistd.h> 241905e80caSMatthias Ringwald #include <errno.h> 242905e80caSMatthias Ringwald int _write(int file, char *ptr, int len); 243905e80caSMatthias Ringwald int _write(int file, char *ptr, int len){ 244905e80caSMatthias Ringwald #if 1 245905e80caSMatthias Ringwald uint8_t cr = '\r'; 246905e80caSMatthias Ringwald int i; 247905e80caSMatthias Ringwald 248905e80caSMatthias Ringwald if (file == STDOUT_FILENO || file == STDERR_FILENO) { 249905e80caSMatthias Ringwald for (i = 0; i < len; i++) { 250905e80caSMatthias Ringwald if (ptr[i] == '\n') { 251905e80caSMatthias Ringwald am_hal_uart_char_transmit_polled( AM_BSP_UART_PRINT_INST, cr ); 252905e80caSMatthias Ringwald } 253905e80caSMatthias Ringwald am_hal_uart_char_transmit_polled( AM_BSP_UART_PRINT_INST, ptr[i]); 254905e80caSMatthias Ringwald } 255905e80caSMatthias Ringwald return i; 256905e80caSMatthias Ringwald } 257905e80caSMatthias Ringwald errno = EIO; 258905e80caSMatthias Ringwald return -1; 259905e80caSMatthias Ringwald #else 260905e80caSMatthias Ringwald return len; 261905e80caSMatthias Ringwald #endif 262905e80caSMatthias Ringwald } 263905e80caSMatthias Ringwald int _read(int file, char * ptr, int len){ 264905e80caSMatthias Ringwald (void)file; 265905e80caSMatthias Ringwald (void)ptr; 266905e80caSMatthias Ringwald (void)len; 267905e80caSMatthias Ringwald return -1; 268905e80caSMatthias Ringwald } 269905e80caSMatthias Ringwald 270905e80caSMatthias Ringwald int _close(int file){ 271905e80caSMatthias Ringwald (void)file; 272905e80caSMatthias Ringwald return -1; 273905e80caSMatthias Ringwald } 274905e80caSMatthias Ringwald 275905e80caSMatthias Ringwald int _isatty(int file){ 276905e80caSMatthias Ringwald (void)file; 277905e80caSMatthias Ringwald return -1; 278905e80caSMatthias Ringwald } 279905e80caSMatthias Ringwald 280905e80caSMatthias Ringwald int _lseek(int file){ 281905e80caSMatthias Ringwald (void)file; 282905e80caSMatthias Ringwald return -1; 283905e80caSMatthias Ringwald } 284905e80caSMatthias Ringwald 285905e80caSMatthias Ringwald int _fstat(int file){ 286905e80caSMatthias Ringwald (void)file; 287905e80caSMatthias Ringwald return -1; 288905e80caSMatthias Ringwald } 289905e80caSMatthias Ringwald 290905e80caSMatthias Ringwald void * _sbrk(intptr_t increment){ 291905e80caSMatthias Ringwald return (void*) -1; 292905e80caSMatthias Ringwald } 293905e80caSMatthias Ringwald 294905e80caSMatthias Ringwald 295905e80caSMatthias Ringwald // hal_em9304_spi.h 296905e80caSMatthias Ringwald #include "hal_em9304_spi.h" 297905e80caSMatthias Ringwald 298905e80caSMatthias Ringwald static void (*hal_em9304_spi_transfer_done_callback)(void); 299905e80caSMatthias Ringwald static void (*hal_em9304_spi_ready_callback)(void); 300905e80caSMatthias Ringwald 301905e80caSMatthias Ringwald #if (0 == AM_BSP_EM9304_IOM) 302905e80caSMatthias Ringwald void 303905e80caSMatthias Ringwald am_iomaster0_isr(void) 304905e80caSMatthias Ringwald { 305905e80caSMatthias Ringwald uint32_t ui32IntStatus; 306905e80caSMatthias Ringwald 307905e80caSMatthias Ringwald // 308905e80caSMatthias Ringwald // Read and clear the interrupt status. 309905e80caSMatthias Ringwald // 310905e80caSMatthias Ringwald ui32IntStatus = am_hal_iom_int_status_get(0, false); 311905e80caSMatthias Ringwald am_hal_iom_int_clear(0, ui32IntStatus); 312905e80caSMatthias Ringwald 313905e80caSMatthias Ringwald // 314905e80caSMatthias Ringwald // Service FIFO interrupts as necessary, and call IOM callbacks as 315905e80caSMatthias Ringwald // transfers are completed. 316905e80caSMatthias Ringwald // 317905e80caSMatthias Ringwald am_hal_iom_int_service(0, ui32IntStatus); 318905e80caSMatthias Ringwald } 319905e80caSMatthias Ringwald #endif 320905e80caSMatthias Ringwald 321905e80caSMatthias Ringwald #if defined(AM_PART_APOLLO2) 322905e80caSMatthias Ringwald #if (5 == AM_BSP_EM9304_IOM) 323905e80caSMatthias Ringwald void 324905e80caSMatthias Ringwald am_iomaster5_isr(void) 325905e80caSMatthias Ringwald { 326905e80caSMatthias Ringwald uint32_t ui32IntStatus; 327905e80caSMatthias Ringwald 328905e80caSMatthias Ringwald // 329905e80caSMatthias Ringwald // Read and clear the interrupt status. 330905e80caSMatthias Ringwald // 331905e80caSMatthias Ringwald ui32IntStatus = am_hal_iom_int_status_get(5, false); 332905e80caSMatthias Ringwald am_hal_iom_int_clear(5, ui32IntStatus); 333905e80caSMatthias Ringwald 334905e80caSMatthias Ringwald // 335905e80caSMatthias Ringwald // Service FIFO interrupts as necessary, and call IOM callbacks as 336905e80caSMatthias Ringwald // transfers are completed. 337905e80caSMatthias Ringwald // 338905e80caSMatthias Ringwald am_hal_iom_int_service(5, ui32IntStatus); 339905e80caSMatthias Ringwald } 340905e80caSMatthias Ringwald #endif 341905e80caSMatthias Ringwald #endif 342905e80caSMatthias Ringwald 343905e80caSMatthias Ringwald void 344905e80caSMatthias Ringwald am_gpio_isr(void) 345905e80caSMatthias Ringwald { 346905e80caSMatthias Ringwald uint64_t ui64Status; 347905e80caSMatthias Ringwald 348905e80caSMatthias Ringwald // 349905e80caSMatthias Ringwald // Check and clear the GPIO interrupt status 350905e80caSMatthias Ringwald // 351905e80caSMatthias Ringwald ui64Status = am_hal_gpio_int_status_get(true); 352905e80caSMatthias Ringwald am_hal_gpio_int_clear(ui64Status); 353905e80caSMatthias Ringwald 354905e80caSMatthias Ringwald // 355905e80caSMatthias Ringwald // Check to see if this was a wakeup event from the BLE radio. 356905e80caSMatthias Ringwald // 357905e80caSMatthias Ringwald if ( ui64Status & AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT) ) 358905e80caSMatthias Ringwald { 359905e80caSMatthias Ringwald if (hal_em9304_spi_ready_callback){ 360905e80caSMatthias Ringwald (*hal_em9304_spi_ready_callback)(); 361905e80caSMatthias Ringwald } 362905e80caSMatthias Ringwald } 363905e80caSMatthias Ringwald } 364905e80caSMatthias Ringwald 365905e80caSMatthias Ringwald void hal_em9304_spi_enable_ready_interrupt(void){ 366905e80caSMatthias Ringwald am_hal_gpio_int_enable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT)); 367905e80caSMatthias Ringwald } 368905e80caSMatthias Ringwald 369905e80caSMatthias Ringwald void hal_em9304_spi_disable_ready_interrupt(void){ 370905e80caSMatthias Ringwald am_hal_gpio_int_disable(AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT)); 371905e80caSMatthias Ringwald } 372905e80caSMatthias Ringwald 373905e80caSMatthias Ringwald void hal_em9304_spi_set_ready_callback(void (*done)(void)){ 374905e80caSMatthias Ringwald hal_em9304_spi_ready_callback = done; 375905e80caSMatthias Ringwald } 376905e80caSMatthias Ringwald 377905e80caSMatthias Ringwald int hal_em9304_spi_get_ready(void){ 378905e80caSMatthias Ringwald return am_hal_gpio_input_read() & AM_HAL_GPIO_BIT(AM_BSP_GPIO_EM9304_INT); 379905e80caSMatthias Ringwald } 380905e80caSMatthias Ringwald 381905e80caSMatthias Ringwald void hal_em9304_spi_init(void){ 382905e80caSMatthias Ringwald hal_em9304_spi_disable_ready_interrupt(); 383905e80caSMatthias Ringwald } 384905e80caSMatthias Ringwald 385905e80caSMatthias Ringwald void hal_em9304_spi_deinit(void){ 386905e80caSMatthias Ringwald hal_em9304_spi_disable_ready_interrupt(); 387905e80caSMatthias Ringwald } 388905e80caSMatthias Ringwald 389905e80caSMatthias Ringwald void hal_em9304_spi_set_transfer_done_callback(void (*done)(void)){ 390905e80caSMatthias Ringwald hal_em9304_spi_transfer_done_callback = done; 391905e80caSMatthias Ringwald } 392905e80caSMatthias Ringwald 393905e80caSMatthias Ringwald void hal_em9304_spi_set_chip_select(int enable){ 394905e80caSMatthias Ringwald if (enable){ 395905e80caSMatthias Ringwald am_hal_gpio_out_bit_clear(AM_BSP_GPIO_EM9304_CS); 396905e80caSMatthias Ringwald } else { 397905e80caSMatthias Ringwald am_hal_gpio_out_bit_set(AM_BSP_GPIO_EM9304_CS); 398905e80caSMatthias Ringwald } 399905e80caSMatthias Ringwald } 400905e80caSMatthias Ringwald 401905e80caSMatthias Ringwald void hal_em9304_spi_transceive(const uint8_t * tx_data, uint8_t * rx_data, uint16_t len){ 402905e80caSMatthias Ringwald // TODO: handle tx_data/rx_data not aligned 403905e80caSMatthias Ringwald // TODO: support non-blocking full duplex 404905e80caSMatthias Ringwald uint32_t ui32ChipSelect = 0; 405905e80caSMatthias Ringwald // TODO: Use Full Duplex with Interrupt callback 406905e80caSMatthias Ringwald // NOTE: Full Duplex only supported on Apollo2 407905e80caSMatthias Ringwald // NOTE: Enabling Full Duplex causes am_hal_iom_spi_write_nq to block (as bytes ready returns number of bytes written) 408905e80caSMatthias Ringwald // AM_REGn(IOMSTR, ui32Module, CFG) |= AM_REG_IOMSTR_CFG_FULLDUP(1); 409905e80caSMatthias Ringwald am_hal_iom_spi_fullduplex_nq(AM_BSP_EM9304_IOM, ui32ChipSelect, (uint32_t *) tx_data, (uint32_t *) rx_data, len, AM_HAL_IOM_RAW); 410905e80caSMatthias Ringwald (*hal_em9304_spi_transfer_done_callback)(); 411905e80caSMatthias Ringwald return; 412905e80caSMatthias Ringwald } 413905e80caSMatthias Ringwald 414905e80caSMatthias Ringwald void hal_em9304_spi_transmit(const uint8_t * tx_data, uint16_t len){ 415905e80caSMatthias Ringwald // TODO: handle tx_data/rx_data not aligned 416905e80caSMatthias Ringwald uint32_t ui32ChipSelect = 0; 417905e80caSMatthias Ringwald 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); 418905e80caSMatthias Ringwald } 419905e80caSMatthias Ringwald 420905e80caSMatthias Ringwald void hal_em9304_spi_receive(uint8_t * rx_data, uint16_t len){ 421905e80caSMatthias Ringwald // TODO: handle tx_data/rx_data not aligned 422905e80caSMatthias Ringwald // TODO: support non-blocking full duplex 423905e80caSMatthias Ringwald uint32_t ui32ChipSelect = 0; 424905e80caSMatthias Ringwald 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); 425905e80caSMatthias Ringwald } 426905e80caSMatthias Ringwald 427905e80caSMatthias Ringwald int hal_em9304_spi_get_fullduplex_support(void){ 428905e80caSMatthias Ringwald return 0; 429905e80caSMatthias Ringwald } 430905e80caSMatthias Ringwald 431905e80caSMatthias Ringwald //***************************************************************************** 432905e80caSMatthias Ringwald // 433905e80caSMatthias Ringwald // Main 434905e80caSMatthias Ringwald // 435905e80caSMatthias Ringwald //***************************************************************************** 436905e80caSMatthias Ringwald 437905e80caSMatthias Ringwald 438905e80caSMatthias Ringwald // EM 9304 SPI Master HCI Implementation 439905e80caSMatthias Ringwald const uint8_t hci_reset_2[] = { 0x01, 0x03, 0x0c, 0x00 }; 440905e80caSMatthias Ringwald 441b5c1b6b6SMatthias Ringwald #include "btstack_event.h" 442b5c1b6b6SMatthias Ringwald #include "btstack_memory.h" 443905e80caSMatthias Ringwald #include "btstack_run_loop.h" 444905e80caSMatthias Ringwald #include "btstack_run_loop_embedded.h" 445905e80caSMatthias Ringwald #include "hci_dump.h" 446*287aaa02SMatthias Ringwald #include "hci_dump_embedded_stdout.h" 447905e80caSMatthias Ringwald 448b5c1b6b6SMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 449b5c1b6b6SMatthias Ringwald int btstack_main(int argc, char ** argv); 450b5c1b6b6SMatthias Ringwald 451b5c1b6b6SMatthias Ringwald // main.c 452b5c1b6b6SMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 453b5c1b6b6SMatthias Ringwald UNUSED(size); 454b5c1b6b6SMatthias Ringwald UNUSED(channel); 455b5c1b6b6SMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return; 456b5c1b6b6SMatthias Ringwald switch(hci_event_packet_get_type(packet)){ 457b5c1b6b6SMatthias Ringwald case BTSTACK_EVENT_STATE: 458b5c1b6b6SMatthias Ringwald if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; 459b5c1b6b6SMatthias Ringwald printf("BTstack up and running.\n"); 460b5c1b6b6SMatthias Ringwald break; 461b5c1b6b6SMatthias Ringwald default: 462b5c1b6b6SMatthias Ringwald break; 463b5c1b6b6SMatthias Ringwald } 464b5c1b6b6SMatthias Ringwald } 465b5c1b6b6SMatthias Ringwald 466905e80caSMatthias Ringwald int main(void) 467905e80caSMatthias Ringwald { 468905e80caSMatthias Ringwald // 469905e80caSMatthias Ringwald // Set the clock frequency. 470905e80caSMatthias Ringwald // 471905e80caSMatthias Ringwald am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX); 472905e80caSMatthias Ringwald 473905e80caSMatthias Ringwald // 474905e80caSMatthias Ringwald // Set the default cache configuration 475905e80caSMatthias Ringwald // 476905e80caSMatthias Ringwald am_hal_cachectrl_enable(&am_hal_cachectrl_defaults); 477905e80caSMatthias Ringwald 478905e80caSMatthias Ringwald // 479905e80caSMatthias Ringwald // Configure the board for low power operation. 480905e80caSMatthias Ringwald // 481905e80caSMatthias Ringwald am_bsp_low_power_init(); 482905e80caSMatthias Ringwald 483905e80caSMatthias Ringwald // 484905e80caSMatthias Ringwald // Initialize the printf interface for UART output. 485905e80caSMatthias Ringwald // 486905e80caSMatthias Ringwald am_util_stdio_printf_init((am_util_stdio_print_char_t)am_bsp_uart_string_print); 487905e80caSMatthias Ringwald 488905e80caSMatthias Ringwald // 489905e80caSMatthias Ringwald // Configure and enable the UART. 490905e80caSMatthias Ringwald // 491905e80caSMatthias Ringwald uart_init(AM_BSP_UART_PRINT_INST); 492905e80caSMatthias Ringwald 493905e80caSMatthias Ringwald // 494905e80caSMatthias Ringwald // Reboot and configure em9304. 495905e80caSMatthias Ringwald // 496905e80caSMatthias Ringwald em9304_init(); 497905e80caSMatthias Ringwald 498905e80caSMatthias Ringwald am_hal_interrupt_enable(AM_HAL_INTERRUPT_GPIO); 499905e80caSMatthias Ringwald 500905e80caSMatthias Ringwald // 501905e80caSMatthias Ringwald // Enable IOM SPI interrupts. 502905e80caSMatthias Ringwald // 503905e80caSMatthias Ringwald am_hal_iom_int_clear(AM_BSP_EM9304_IOM, AM_HAL_IOM_INT_CMDCMP | AM_HAL_IOM_INT_THR); 504905e80caSMatthias Ringwald am_hal_iom_int_enable(AM_BSP_EM9304_IOM, AM_HAL_IOM_INT_CMDCMP | AM_HAL_IOM_INT_THR); 505905e80caSMatthias Ringwald 506905e80caSMatthias Ringwald #if (0 == AM_BSP_EM9304_IOM) 507905e80caSMatthias Ringwald am_hal_interrupt_enable(AM_HAL_INTERRUPT_IOMASTER0); 508905e80caSMatthias Ringwald #elif (5 == AM_BSP_EM9304_IOM) 509905e80caSMatthias Ringwald am_hal_interrupt_enable(AM_HAL_INTERRUPT_IOMASTER5); 510905e80caSMatthias Ringwald #endif 511905e80caSMatthias Ringwald 512c5ae0d23SMatthias Ringwald // Start System Timer (only Apollo 2) 513c5ae0d23SMatthias Ringwald am_hal_stimer_config(AM_HAL_STIMER_LFRC_1KHZ); 514c5ae0d23SMatthias Ringwald am_hal_stimer_counter_clear(); 515c5ae0d23SMatthias Ringwald 516905e80caSMatthias Ringwald // start with BTstack init - especially configure HCI Transport 517905e80caSMatthias Ringwald btstack_memory_init(); 518905e80caSMatthias Ringwald btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); 519905e80caSMatthias Ringwald 520905e80caSMatthias Ringwald // init HCI 521905e80caSMatthias Ringwald hci_init(hci_transport_em9304_spi_instance(btstack_em9304_spi_embedded_instance()), NULL); 522*287aaa02SMatthias Ringwald // hci_dump_init(hci_dump_embedded_stdout_get_instance()); 523b5c1b6b6SMatthias Ringwald 524b5c1b6b6SMatthias Ringwald // inform about BTstack state 525b5c1b6b6SMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 526b5c1b6b6SMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 527905e80caSMatthias Ringwald 528905e80caSMatthias Ringwald // hand over control to btstack_main().. 529905e80caSMatthias Ringwald 530905e80caSMatthias Ringwald // turn on! 531905e80caSMatthias Ringwald // hci_power_control(HCI_POWER_ON); 532905e80caSMatthias Ringwald btstack_main(0, NULL); 533905e80caSMatthias Ringwald 534905e80caSMatthias Ringwald btstack_run_loop_execute(); 535905e80caSMatthias Ringwald } 536