11b2596b5SMatthias Ringwald /** 21b2596b5SMatthias Ringwald * \file 31b2596b5SMatthias Ringwald * 41b2596b5SMatthias Ringwald * \brief Getting Started Application. 51b2596b5SMatthias Ringwald * 6*58a1b1bbSMatthias Ringwald * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. 71b2596b5SMatthias Ringwald * 81b2596b5SMatthias Ringwald * \asf_license_start 91b2596b5SMatthias Ringwald * 101b2596b5SMatthias Ringwald * \page License 111b2596b5SMatthias Ringwald * 121b2596b5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 131b2596b5SMatthias Ringwald * modification, are permitted provided that the following conditions are met: 141b2596b5SMatthias Ringwald * 151b2596b5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright notice, 161b2596b5SMatthias Ringwald * this list of conditions and the following disclaimer. 171b2596b5SMatthias Ringwald * 181b2596b5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright notice, 191b2596b5SMatthias Ringwald * this list of conditions and the following disclaimer in the documentation 201b2596b5SMatthias Ringwald * and/or other materials provided with the distribution. 211b2596b5SMatthias Ringwald * 221b2596b5SMatthias Ringwald * 3. The name of Atmel may not be used to endorse or promote products derived 231b2596b5SMatthias Ringwald * from this software without specific prior written permission. 241b2596b5SMatthias Ringwald * 251b2596b5SMatthias Ringwald * 4. This software may only be redistributed and used in connection with an 261b2596b5SMatthias Ringwald * Atmel microcontroller product. 271b2596b5SMatthias Ringwald * 281b2596b5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 291b2596b5SMatthias Ringwald * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 301b2596b5SMatthias Ringwald * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 311b2596b5SMatthias Ringwald * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 321b2596b5SMatthias Ringwald * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 331b2596b5SMatthias Ringwald * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 341b2596b5SMatthias Ringwald * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 351b2596b5SMatthias Ringwald * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 361b2596b5SMatthias Ringwald * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 371b2596b5SMatthias Ringwald * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 381b2596b5SMatthias Ringwald * POSSIBILITY OF SUCH DAMAGE. 391b2596b5SMatthias Ringwald * 401b2596b5SMatthias Ringwald * \asf_license_stop 411b2596b5SMatthias Ringwald * 421b2596b5SMatthias Ringwald */ 431b2596b5SMatthias Ringwald 441b2596b5SMatthias Ringwald /** 451b2596b5SMatthias Ringwald * \mainpage Getting Started Application 461b2596b5SMatthias Ringwald * 471b2596b5SMatthias Ringwald * \section Purpose 481b2596b5SMatthias Ringwald * 49*58a1b1bbSMatthias Ringwald * BTstack port for SAM MCUs 501b2596b5SMatthias Ringwald * 511b2596b5SMatthias Ringwald * \section Requirements 521b2596b5SMatthias Ringwald * 531b2596b5SMatthias Ringwald * This package can be used with SAM evaluation kits. 541b2596b5SMatthias Ringwald * 551b2596b5SMatthias Ringwald * \section Description 561b2596b5SMatthias Ringwald * 571b2596b5SMatthias Ringwald * 581b2596b5SMatthias Ringwald * \section Usage 591b2596b5SMatthias Ringwald * 601b2596b5SMatthias Ringwald * -# Build the program and download it inside the evaluation board. 611b2596b5SMatthias Ringwald * -# On the computer, open and configure a terminal application 621b2596b5SMatthias Ringwald * (e.g. HyperTerminal on Microsoft Windows) with these settings: 631b2596b5SMatthias Ringwald * - 115200 bauds 641b2596b5SMatthias Ringwald * - 8 bits of data 651b2596b5SMatthias Ringwald * - No parity 661b2596b5SMatthias Ringwald * - 1 stop bit 671b2596b5SMatthias Ringwald * - No flow control 681b2596b5SMatthias Ringwald * -# Start the application. 691b2596b5SMatthias Ringwald * 701b2596b5SMatthias Ringwald */ 711b2596b5SMatthias Ringwald 721b2596b5SMatthias Ringwald #include "asf.h" 731b2596b5SMatthias Ringwald #include "stdio_serial.h" 741b2596b5SMatthias Ringwald #include "conf_board.h" 751b2596b5SMatthias Ringwald #include "conf_clock.h" 761b2596b5SMatthias Ringwald 77*58a1b1bbSMatthias Ringwald // BTstack 78*58a1b1bbSMatthias Ringwald #include "btstack_run_loop.h" 79*58a1b1bbSMatthias Ringwald #include "btstack_run_loop_embedded.h" 80*58a1b1bbSMatthias Ringwald #include "btstack_debug.h" 81*58a1b1bbSMatthias Ringwald #include "hci.h" 82*58a1b1bbSMatthias Ringwald #include "hci_dump.h" 83*58a1b1bbSMatthias Ringwald #include "btstack_chipset_atwilc3000.h" 84*58a1b1bbSMatthias Ringwald #include "btstack_memory.h" 85*58a1b1bbSMatthias Ringwald #include "classic/btstack_link_key_db.h" 861b2596b5SMatthias Ringwald 87*58a1b1bbSMatthias Ringwald #include "hal_uart_dma.h" 88*58a1b1bbSMatthias Ringwald #include "hal_cpu.h" 89*58a1b1bbSMatthias Ringwald #include "hal_tick.h" 90*58a1b1bbSMatthias Ringwald 91*58a1b1bbSMatthias Ringwald extern int btstack_main(int argc, const char * argv[]); 92*58a1b1bbSMatthias Ringwald 93*58a1b1bbSMatthias Ringwald #define USE_XDMAC_FOR_USART 94*58a1b1bbSMatthias Ringwald #define XDMA_CH_UART_TX 0 95*58a1b1bbSMatthias Ringwald #define XDMA_CH_UART_RX 1 961b2596b5SMatthias Ringwald 971b2596b5SMatthias Ringwald #define STRING_EOL "\r" 981b2596b5SMatthias Ringwald #define STRING_HEADER "-- Getting Started Example --\r\n" \ 991b2596b5SMatthias Ringwald "-- "BOARD_NAME" --\r\n" \ 1001b2596b5SMatthias Ringwald "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL 1011b2596b5SMatthias Ringwald 102*58a1b1bbSMatthias Ringwald /** All interrupt mask. */ 103*58a1b1bbSMatthias Ringwald #define ALL_INTERRUPT_MASK 0xffffffff 1041b2596b5SMatthias Ringwald 105*58a1b1bbSMatthias Ringwald static void dummy_handler(void){} 106*58a1b1bbSMatthias Ringwald static void (*tick_handler)(void) = &dummy_handler; 1071b2596b5SMatthias Ringwald 108*58a1b1bbSMatthias Ringwald /** when porting to different setup, please 109*58a1b1bbSMatthias Ringwald * disable baudrate change (use 0 instead of 4000000) 110*58a1b1bbSMatthias Ringwald * and don't enable eHCILL mode (comment line below) 111*58a1b1bbSMatthias Ringwald */ 1121b2596b5SMatthias Ringwald 113*58a1b1bbSMatthias Ringwald // after HCI Reset, use 115200. Then increase baud rate to X. 114*58a1b1bbSMatthias Ringwald static hci_transport_config_uart_t hci_transport_config = { 115*58a1b1bbSMatthias Ringwald HCI_TRANSPORT_CONFIG_UART, 116*58a1b1bbSMatthias Ringwald 115200, 117*58a1b1bbSMatthias Ringwald 4000000, // use 0 to skip baud rate change from 115200 to X for debugging purposes 118*58a1b1bbSMatthias Ringwald 1, // flow control 119*58a1b1bbSMatthias Ringwald NULL, 120*58a1b1bbSMatthias Ringwald }; 1211b2596b5SMatthias Ringwald /// @cond 0 1221b2596b5SMatthias Ringwald /**INDENT-OFF**/ 1231b2596b5SMatthias Ringwald #ifdef __cplusplus 1241b2596b5SMatthias Ringwald extern "C" { 1251b2596b5SMatthias Ringwald #endif 1261b2596b5SMatthias Ringwald /**INDENT-ON**/ 1271b2596b5SMatthias Ringwald /// @endcond 1281b2596b5SMatthias Ringwald 1291b2596b5SMatthias Ringwald /** 1301b2596b5SMatthias Ringwald * \brief Handler for System Tick interrupt. 1311b2596b5SMatthias Ringwald */ 1321b2596b5SMatthias Ringwald void SysTick_Handler(void) 1331b2596b5SMatthias Ringwald { 134*58a1b1bbSMatthias Ringwald tick_handler(); 1351b2596b5SMatthias Ringwald } 1361b2596b5SMatthias Ringwald 1371b2596b5SMatthias Ringwald /** 1381b2596b5SMatthias Ringwald * Configure UART console. 1391b2596b5SMatthias Ringwald */ 1401b2596b5SMatthias Ringwald // [main_console_configure] 1411b2596b5SMatthias Ringwald static void configure_console(void) 1421b2596b5SMatthias Ringwald { 1431b2596b5SMatthias Ringwald const usart_serial_options_t uart_serial_options = { 1441b2596b5SMatthias Ringwald .baudrate = CONF_UART_BAUDRATE, 1451b2596b5SMatthias Ringwald #ifdef CONF_UART_CHAR_LENGTH 1461b2596b5SMatthias Ringwald .charlength = CONF_UART_CHAR_LENGTH, 1471b2596b5SMatthias Ringwald #endif 1481b2596b5SMatthias Ringwald .paritytype = CONF_UART_PARITY, 1491b2596b5SMatthias Ringwald #ifdef CONF_UART_STOP_BITS 1501b2596b5SMatthias Ringwald .stopbits = CONF_UART_STOP_BITS, 1511b2596b5SMatthias Ringwald #endif 1521b2596b5SMatthias Ringwald }; 1531b2596b5SMatthias Ringwald 1541b2596b5SMatthias Ringwald /* Configure console UART. */ 1551b2596b5SMatthias Ringwald sysclk_enable_peripheral_clock(CONSOLE_UART_ID); 1561b2596b5SMatthias Ringwald stdio_serial_init(CONF_UART, &uart_serial_options); 1571b2596b5SMatthias Ringwald } 1581b2596b5SMatthias Ringwald 1591b2596b5SMatthias Ringwald // [main_console_configure] 1601b2596b5SMatthias Ringwald 1611b2596b5SMatthias Ringwald /** 162*58a1b1bbSMatthias Ringwald * \brief Wait for the given number of milliseconds (ticks 1631b2596b5SMatthias Ringwald * generated by the SAM's microcontrollers's system tick). 1641b2596b5SMatthias Ringwald * 1651b2596b5SMatthias Ringwald * \param ul_dly_ticks Delay to wait for, in milliseconds. 1661b2596b5SMatthias Ringwald */ 1671b2596b5SMatthias Ringwald // [main_ms_delay] 168*58a1b1bbSMatthias Ringwald static void mdelay(uint32_t delay_in_ms) 1691b2596b5SMatthias Ringwald { 170*58a1b1bbSMatthias Ringwald // delay_ms(delay_in_ms); 171*58a1b1bbSMatthias Ringwald uint32_t time_to_wait = btstack_run_loop_get_time_ms() + delay_in_ms; 172*58a1b1bbSMatthias Ringwald while (btstack_run_loop_get_time_ms() < time_to_wait); 1731b2596b5SMatthias Ringwald } 1741b2596b5SMatthias Ringwald // [main_ms_delay] 1751b2596b5SMatthias Ringwald 176*58a1b1bbSMatthias Ringwald //////////////////////////////////////////////////////////////////////////////// 177*58a1b1bbSMatthias Ringwald // hal_cpu.h implementation 178*58a1b1bbSMatthias Ringwald //////////////////////////////////////////////////////////////////////////////// 179*58a1b1bbSMatthias Ringwald // hal_led.h implementation 180*58a1b1bbSMatthias Ringwald #include "hal_led.h" 181*58a1b1bbSMatthias Ringwald void hal_led_off(void); 182*58a1b1bbSMatthias Ringwald void hal_led_on(void); 183*58a1b1bbSMatthias Ringwald 184*58a1b1bbSMatthias Ringwald void hal_led_off(void){ 185*58a1b1bbSMatthias Ringwald // gpio_set_pin_low(GPIOA, GPIO_LED2); 186*58a1b1bbSMatthias Ringwald } 187*58a1b1bbSMatthias Ringwald void hal_led_on(void){ 188*58a1b1bbSMatthias Ringwald // gpio_set_pin_high(GPIOA, GPIO_LED2); 189*58a1b1bbSMatthias Ringwald } 190*58a1b1bbSMatthias Ringwald void hal_led_toggle(void){ 191*58a1b1bbSMatthias Ringwald // gpio_toggle_pin(GPIOA, GPIO_LED2); 192*58a1b1bbSMatthias Ringwald } 193*58a1b1bbSMatthias Ringwald 194*58a1b1bbSMatthias Ringwald // hal_cpu.h implementation 195*58a1b1bbSMatthias Ringwald #include "hal_cpu.h" 196*58a1b1bbSMatthias Ringwald 197*58a1b1bbSMatthias Ringwald void hal_cpu_disable_irqs(void){ 198*58a1b1bbSMatthias Ringwald //__disable_irq(); 199*58a1b1bbSMatthias Ringwald } 200*58a1b1bbSMatthias Ringwald 201*58a1b1bbSMatthias Ringwald void hal_cpu_enable_irqs(void){ 202*58a1b1bbSMatthias Ringwald // __enable_irq(); 203*58a1b1bbSMatthias Ringwald } 204*58a1b1bbSMatthias Ringwald 205*58a1b1bbSMatthias Ringwald void hal_cpu_enable_irqs_and_sleep(void){ 206*58a1b1bbSMatthias Ringwald hal_led_off(); 207*58a1b1bbSMatthias Ringwald // __enable_irq(); 208*58a1b1bbSMatthias Ringwald // __asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag 209*58a1b1bbSMatthias Ringwald 210*58a1b1bbSMatthias Ringwald // note: hal_uart_needed_during_sleep can be used to disable peripheral clock if it's not needed for a timer 211*58a1b1bbSMatthias Ringwald hal_led_on(); 212*58a1b1bbSMatthias Ringwald } 213*58a1b1bbSMatthias Ringwald 214*58a1b1bbSMatthias Ringwald 215*58a1b1bbSMatthias Ringwald #ifndef USE_XDMAC_FOR_USART 216*58a1b1bbSMatthias Ringwald // RX state 217*58a1b1bbSMatthias Ringwald static volatile uint16_t bytes_to_read = 0; 218*58a1b1bbSMatthias Ringwald static volatile uint8_t * rx_buffer_ptr = 0; 219*58a1b1bbSMatthias Ringwald 220*58a1b1bbSMatthias Ringwald // TX state 221*58a1b1bbSMatthias Ringwald static volatile uint16_t bytes_to_write = 0; 222*58a1b1bbSMatthias Ringwald static volatile uint8_t * tx_buffer_ptr = 0; 223*58a1b1bbSMatthias Ringwald #endif 224*58a1b1bbSMatthias Ringwald 225*58a1b1bbSMatthias Ringwald // handlers 226*58a1b1bbSMatthias Ringwald static void (*rx_done_handler)(void) = dummy_handler; 227*58a1b1bbSMatthias Ringwald static void (*tx_done_handler)(void) = dummy_handler; 228*58a1b1bbSMatthias Ringwald static void (*cts_irq_handler)(void) = dummy_handler; 229*58a1b1bbSMatthias Ringwald 230*58a1b1bbSMatthias Ringwald // @note While the Atmel SAM S7x data sheet states 231*58a1b1bbSMatthias Ringwald // "The hardware handshaking feature enables an out-of-band flow control by automatic management 232*58a1b1bbSMatthias Ringwald // of the pins RTS and CTS.", 233*58a1b1bbSMatthias Ringwald // I didn't see RTS going up automatically up, ever. So, at least for RTS, the automatic management 234*58a1b1bbSMatthias Ringwald // is just a glorified GPIO pin control feature, which provides no benefit, but irritates a lot 235*58a1b1bbSMatthias Ringwald 236*58a1b1bbSMatthias Ringwald static void hal_uart_rts_high(void){ 237*58a1b1bbSMatthias Ringwald BOARD_USART->US_CR = US_CR_RTSEN; 238*58a1b1bbSMatthias Ringwald } 239*58a1b1bbSMatthias Ringwald static void hal_uart_rts_low(void){ 240*58a1b1bbSMatthias Ringwald BOARD_USART->US_CR = US_CR_RTSDIS; 241*58a1b1bbSMatthias Ringwald } 242*58a1b1bbSMatthias Ringwald 243*58a1b1bbSMatthias Ringwald /** 244*58a1b1bbSMatthias Ringwald */ 245*58a1b1bbSMatthias Ringwald void hal_uart_dma_init(void) 246*58a1b1bbSMatthias Ringwald { 247*58a1b1bbSMatthias Ringwald // configure n_shutdown pin, and reset Bluetooth 248*58a1b1bbSMatthias Ringwald ioport_set_pin_dir(N_SHUTDOWN, IOPORT_DIR_OUTPUT); 249*58a1b1bbSMatthias Ringwald ioport_set_pin_level(N_SHUTDOWN, IOPORT_PIN_LEVEL_LOW); 250*58a1b1bbSMatthias Ringwald mdelay(100); 251*58a1b1bbSMatthias Ringwald ioport_set_pin_level(N_SHUTDOWN, IOPORT_PIN_LEVEL_HIGH); 252*58a1b1bbSMatthias Ringwald mdelay(500); 253*58a1b1bbSMatthias Ringwald 254*58a1b1bbSMatthias Ringwald // configure Bluetooth USART 255*58a1b1bbSMatthias Ringwald const sam_usart_opt_t bluetooth_settings = { 256*58a1b1bbSMatthias Ringwald 115200, 257*58a1b1bbSMatthias Ringwald US_MR_CHRL_8_BIT, 258*58a1b1bbSMatthias Ringwald US_MR_PAR_NO, 259*58a1b1bbSMatthias Ringwald US_MR_NBSTOP_1_BIT, 260*58a1b1bbSMatthias Ringwald US_MR_CHMODE_NORMAL, 261*58a1b1bbSMatthias Ringwald /* This field is only used in IrDA mode. */ 262*58a1b1bbSMatthias Ringwald 0 263*58a1b1bbSMatthias Ringwald }; 264*58a1b1bbSMatthias Ringwald 265*58a1b1bbSMatthias Ringwald /* Enable the peripheral clock in the PMC. */ 266*58a1b1bbSMatthias Ringwald sysclk_enable_peripheral_clock(BOARD_ID_USART); 267*58a1b1bbSMatthias Ringwald 268*58a1b1bbSMatthias Ringwald /* Configure USART mode. */ 269*58a1b1bbSMatthias Ringwald usart_init_hw_handshaking(BOARD_USART, &bluetooth_settings, sysclk_get_peripheral_hz()); 270*58a1b1bbSMatthias Ringwald 271*58a1b1bbSMatthias Ringwald /* Disable all the interrupts. */ 272*58a1b1bbSMatthias Ringwald usart_disable_interrupt(BOARD_USART, ALL_INTERRUPT_MASK); 273*58a1b1bbSMatthias Ringwald 274*58a1b1bbSMatthias Ringwald // RX not ready yet 275*58a1b1bbSMatthias Ringwald // usart_drive_RTS_pin_high(BOARD_USART); 276*58a1b1bbSMatthias Ringwald 277*58a1b1bbSMatthias Ringwald /* Enable TX & RX function. */ 278*58a1b1bbSMatthias Ringwald usart_enable_tx(BOARD_USART); 279*58a1b1bbSMatthias Ringwald usart_enable_rx(BOARD_USART); 280*58a1b1bbSMatthias Ringwald 281*58a1b1bbSMatthias Ringwald /* Configure and enable interrupt of USART. */ 282*58a1b1bbSMatthias Ringwald NVIC_EnableIRQ(USART_IRQn); 283*58a1b1bbSMatthias Ringwald 284*58a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 285*58a1b1bbSMatthias Ringwald 286*58a1b1bbSMatthias Ringwald // setup XDMAC 287*58a1b1bbSMatthias Ringwald 288*58a1b1bbSMatthias Ringwald /* Initialize and enable DMA controller */ 289*58a1b1bbSMatthias Ringwald pmc_enable_periph_clk(ID_XDMAC); 290*58a1b1bbSMatthias Ringwald 291*58a1b1bbSMatthias Ringwald /* Enable XDMA interrupt */ 292*58a1b1bbSMatthias Ringwald NVIC_ClearPendingIRQ(XDMAC_IRQn); 293*58a1b1bbSMatthias Ringwald NVIC_SetPriority( XDMAC_IRQn ,1); 294*58a1b1bbSMatthias Ringwald NVIC_EnableIRQ(XDMAC_IRQn); 295*58a1b1bbSMatthias Ringwald 296*58a1b1bbSMatthias Ringwald // Setup XDMA Channel for USART TX 297*58a1b1bbSMatthias Ringwald xdmac_channel_set_destination_addr(XDMAC, XDMA_CH_UART_TX, (uint32_t)&BOARD_USART->US_THR); 298*58a1b1bbSMatthias Ringwald xdmac_channel_set_config(XDMAC, XDMA_CH_UART_TX, 299*58a1b1bbSMatthias Ringwald XDMAC_CC_TYPE_PER_TRAN | 300*58a1b1bbSMatthias Ringwald XDMAC_CC_DSYNC_MEM2PER | 301*58a1b1bbSMatthias Ringwald XDMAC_CC_MEMSET_NORMAL_MODE | 302*58a1b1bbSMatthias Ringwald XDMAC_CC_MBSIZE_SINGLE | 303*58a1b1bbSMatthias Ringwald XDMAC_CC_DWIDTH_BYTE | 304*58a1b1bbSMatthias Ringwald XDMAC_CC_SIF_AHB_IF0 | 305*58a1b1bbSMatthias Ringwald XDMAC_CC_DIF_AHB_IF1 | 306*58a1b1bbSMatthias Ringwald XDMAC_CC_SAM_INCREMENTED_AM | 307*58a1b1bbSMatthias Ringwald XDMAC_CC_DAM_FIXED_AM | 308*58a1b1bbSMatthias Ringwald XDMAC_CC_CSIZE_CHK_1 | 309*58a1b1bbSMatthias Ringwald XDMAC_CC_PERID(XDAMC_CHANNEL_HWID_USART0_TX) 310*58a1b1bbSMatthias Ringwald ); 311*58a1b1bbSMatthias Ringwald xdmac_channel_set_descriptor_control(XDMAC, XDMA_CH_UART_TX, 0); 312*58a1b1bbSMatthias Ringwald xdmac_channel_set_source_microblock_stride(XDMAC, XDMA_CH_UART_TX, 0); 313*58a1b1bbSMatthias Ringwald xdmac_channel_set_destination_microblock_stride(XDMAC, XDMA_CH_UART_TX, 0); 314*58a1b1bbSMatthias Ringwald xdmac_channel_set_datastride_mempattern(XDMAC, XDMA_CH_UART_TX, 0); 315*58a1b1bbSMatthias Ringwald xdmac_channel_set_block_control(XDMAC, XDMA_CH_UART_TX, 0); 316*58a1b1bbSMatthias Ringwald xdmac_enable_interrupt(XDMAC, XDMA_CH_UART_TX); 317*58a1b1bbSMatthias Ringwald xdmac_channel_enable_interrupt(XDMAC, XDMA_CH_UART_TX, XDMAC_CIE_BIE); 318*58a1b1bbSMatthias Ringwald 319*58a1b1bbSMatthias Ringwald // Setup XDMA Channel for USART RX 320*58a1b1bbSMatthias Ringwald xdmac_channel_set_source_addr(XDMAC, XDMA_CH_UART_RX, (uint32_t)&BOARD_USART->US_RHR); 321*58a1b1bbSMatthias Ringwald xdmac_channel_set_config(XDMAC, XDMA_CH_UART_RX, 322*58a1b1bbSMatthias Ringwald XDMAC_CC_TYPE_PER_TRAN | 323*58a1b1bbSMatthias Ringwald XDMAC_CC_DSYNC_PER2MEM | 324*58a1b1bbSMatthias Ringwald XDMAC_CC_MEMSET_NORMAL_MODE | 325*58a1b1bbSMatthias Ringwald XDMAC_CC_MBSIZE_SINGLE | 326*58a1b1bbSMatthias Ringwald XDMAC_CC_DWIDTH_BYTE | 327*58a1b1bbSMatthias Ringwald XDMAC_CC_SIF_AHB_IF1 | 328*58a1b1bbSMatthias Ringwald XDMAC_CC_DIF_AHB_IF0 | 329*58a1b1bbSMatthias Ringwald XDMAC_CC_SAM_FIXED_AM | 330*58a1b1bbSMatthias Ringwald XDMAC_CC_DAM_INCREMENTED_AM | 331*58a1b1bbSMatthias Ringwald XDMAC_CC_CSIZE_CHK_1 | 332*58a1b1bbSMatthias Ringwald XDMAC_CC_PERID(XDAMC_CHANNEL_HWID_USART0_RX) 333*58a1b1bbSMatthias Ringwald ); 334*58a1b1bbSMatthias Ringwald xdmac_channel_set_descriptor_control(XDMAC, XDMA_CH_UART_RX, 0); 335*58a1b1bbSMatthias Ringwald xdmac_channel_set_source_microblock_stride(XDMAC, XDMA_CH_UART_RX, 0); 336*58a1b1bbSMatthias Ringwald xdmac_channel_set_destination_microblock_stride(XDMAC, XDMA_CH_UART_RX, 0); 337*58a1b1bbSMatthias Ringwald xdmac_channel_set_datastride_mempattern(XDMAC, XDMA_CH_UART_RX, 0); 338*58a1b1bbSMatthias Ringwald xdmac_channel_set_block_control(XDMAC, XDMA_CH_UART_RX, 0); 339*58a1b1bbSMatthias Ringwald xdmac_enable_interrupt(XDMAC, XDMA_CH_UART_RX); 340*58a1b1bbSMatthias Ringwald xdmac_channel_enable_interrupt(XDMAC, XDMA_CH_UART_RX, XDMAC_CIE_BIE); 341*58a1b1bbSMatthias Ringwald #endif 342*58a1b1bbSMatthias Ringwald } 343*58a1b1bbSMatthias Ringwald 344*58a1b1bbSMatthias Ringwald void hal_uart_dma_set_sleep(uint8_t sleep){ 345*58a1b1bbSMatthias Ringwald } 346*58a1b1bbSMatthias Ringwald 347*58a1b1bbSMatthias Ringwald void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){ 348*58a1b1bbSMatthias Ringwald rx_done_handler = the_block_handler; 349*58a1b1bbSMatthias Ringwald } 350*58a1b1bbSMatthias Ringwald 351*58a1b1bbSMatthias Ringwald void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){ 352*58a1b1bbSMatthias Ringwald tx_done_handler = the_block_handler; 353*58a1b1bbSMatthias Ringwald } 354*58a1b1bbSMatthias Ringwald 355*58a1b1bbSMatthias Ringwald void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){ 356*58a1b1bbSMatthias Ringwald cts_irq_handler = the_irq_handler; 357*58a1b1bbSMatthias Ringwald } 358*58a1b1bbSMatthias Ringwald 359*58a1b1bbSMatthias Ringwald int hal_uart_dma_set_baud(uint32_t baud){ 360*58a1b1bbSMatthias Ringwald /* Disable TX & RX function. */ 361*58a1b1bbSMatthias Ringwald usart_disable_tx(BOARD_USART); 362*58a1b1bbSMatthias Ringwald usart_disable_rx(BOARD_USART); 363*58a1b1bbSMatthias Ringwald uint32_t res = usart_set_async_baudrate(BOARD_USART, baud, sysclk_get_peripheral_hz()); 364*58a1b1bbSMatthias Ringwald if (res){ 365*58a1b1bbSMatthias Ringwald log_error("hal_uart_dma_set_baud library call failed"); 366*58a1b1bbSMatthias Ringwald } 367*58a1b1bbSMatthias Ringwald 368*58a1b1bbSMatthias Ringwald /* Enable TX & RX function. */ 369*58a1b1bbSMatthias Ringwald usart_enable_tx(BOARD_USART); 370*58a1b1bbSMatthias Ringwald usart_enable_rx(BOARD_USART); 371*58a1b1bbSMatthias Ringwald 372*58a1b1bbSMatthias Ringwald log_info("Bump baud rate"); 373*58a1b1bbSMatthias Ringwald 374*58a1b1bbSMatthias Ringwald return 0; 375*58a1b1bbSMatthias Ringwald } 376*58a1b1bbSMatthias Ringwald 377*58a1b1bbSMatthias Ringwald void hal_uart_dma_send_block(const uint8_t *data, uint16_t size){ 378*58a1b1bbSMatthias Ringwald 379*58a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 380*58a1b1bbSMatthias Ringwald xdmac_channel_get_interrupt_status( XDMAC, XDMA_CH_UART_TX); 381*58a1b1bbSMatthias Ringwald xdmac_channel_set_source_addr(XDMAC, XDMA_CH_UART_TX, (uint32_t)data); 382*58a1b1bbSMatthias Ringwald xdmac_channel_set_microblock_control(XDMAC, XDMA_CH_UART_TX, size); 383*58a1b1bbSMatthias Ringwald xdmac_channel_enable(XDMAC, XDMA_CH_UART_TX); 384*58a1b1bbSMatthias Ringwald #else 385*58a1b1bbSMatthias Ringwald tx_buffer_ptr = (uint8_t *) data; 386*58a1b1bbSMatthias Ringwald bytes_to_write = size; 387*58a1b1bbSMatthias Ringwald usart_enable_interrupt(BOARD_USART, US_IER_TXRDY); 388*58a1b1bbSMatthias Ringwald #endif 389*58a1b1bbSMatthias Ringwald } 390*58a1b1bbSMatthias Ringwald 391*58a1b1bbSMatthias Ringwald void hal_uart_dma_receive_block(uint8_t *data, uint16_t size){ 392*58a1b1bbSMatthias Ringwald 393*58a1b1bbSMatthias Ringwald hal_uart_rts_low(); 394*58a1b1bbSMatthias Ringwald 395*58a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 396*58a1b1bbSMatthias Ringwald xdmac_channel_get_interrupt_status( XDMAC, XDMA_CH_UART_RX); 397*58a1b1bbSMatthias Ringwald xdmac_channel_set_destination_addr(XDMAC, XDMA_CH_UART_RX, (uint32_t)data); 398*58a1b1bbSMatthias Ringwald xdmac_channel_set_microblock_control(XDMAC, XDMA_CH_UART_RX, size); 399*58a1b1bbSMatthias Ringwald xdmac_channel_enable(XDMAC, XDMA_CH_UART_RX); 400*58a1b1bbSMatthias Ringwald #else 401*58a1b1bbSMatthias Ringwald rx_buffer_ptr = data; 402*58a1b1bbSMatthias Ringwald bytes_to_read = size; 403*58a1b1bbSMatthias Ringwald usart_enable_interrupt(BOARD_USART, US_IER_RXRDY); 404*58a1b1bbSMatthias Ringwald #endif 405*58a1b1bbSMatthias Ringwald } 406*58a1b1bbSMatthias Ringwald 407*58a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 408*58a1b1bbSMatthias Ringwald void XDMAC_Handler(void) 409*58a1b1bbSMatthias Ringwald { 410*58a1b1bbSMatthias Ringwald uint32_t dma_status; 411*58a1b1bbSMatthias Ringwald dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_UART_TX); 412*58a1b1bbSMatthias Ringwald if (dma_status & XDMAC_CIS_BIS) { 413*58a1b1bbSMatthias Ringwald tx_done_handler(); 414*58a1b1bbSMatthias Ringwald } 415*58a1b1bbSMatthias Ringwald dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_UART_RX); 416*58a1b1bbSMatthias Ringwald if (dma_status & XDMAC_CIS_BIS) { 417*58a1b1bbSMatthias Ringwald hal_uart_rts_high(); 418*58a1b1bbSMatthias Ringwald rx_done_handler(); 419*58a1b1bbSMatthias Ringwald } 420*58a1b1bbSMatthias Ringwald } 421*58a1b1bbSMatthias Ringwald #else 422*58a1b1bbSMatthias Ringwald void USART_Handler(void) 423*58a1b1bbSMatthias Ringwald { 424*58a1b1bbSMatthias Ringwald uint32_t ul_status; 425*58a1b1bbSMatthias Ringwald uint8_t uc_char; 426*58a1b1bbSMatthias Ringwald 427*58a1b1bbSMatthias Ringwald /* Read USART status. */ 428*58a1b1bbSMatthias Ringwald ul_status = usart_get_status(BOARD_USART); 429*58a1b1bbSMatthias Ringwald 430*58a1b1bbSMatthias Ringwald // handle ready to send 431*58a1b1bbSMatthias Ringwald if(ul_status & US_IER_TXRDY) { 432*58a1b1bbSMatthias Ringwald if (bytes_to_write){ 433*58a1b1bbSMatthias Ringwald // send next byte 434*58a1b1bbSMatthias Ringwald usart_write(BOARD_USART, *tx_buffer_ptr); 435*58a1b1bbSMatthias Ringwald tx_buffer_ptr++; 436*58a1b1bbSMatthias Ringwald bytes_to_write--; 437*58a1b1bbSMatthias Ringwald } else { 438*58a1b1bbSMatthias Ringwald // done. disable tx ready interrupt to avoid starvation here 439*58a1b1bbSMatthias Ringwald usart_disable_interrupt(BOARD_USART, US_IER_TXRDY); 440*58a1b1bbSMatthias Ringwald tx_done_handler(); 441*58a1b1bbSMatthias Ringwald } 442*58a1b1bbSMatthias Ringwald } 443*58a1b1bbSMatthias Ringwald 444*58a1b1bbSMatthias Ringwald // handle byte available for read 445*58a1b1bbSMatthias Ringwald if (ul_status & US_IER_RXRDY) { 446*58a1b1bbSMatthias Ringwald uint32_t ch; 447*58a1b1bbSMatthias Ringwald usart_read(BOARD_USART, (uint32_t *)&ch); 448*58a1b1bbSMatthias Ringwald *rx_buffer_ptr++ = ch; 449*58a1b1bbSMatthias Ringwald bytes_to_read--; 450*58a1b1bbSMatthias Ringwald if (bytes_to_read == 0){ 451*58a1b1bbSMatthias Ringwald // done. disable rx ready interrupt, raise RTS 452*58a1b1bbSMatthias Ringwald hal_uart_rts_high(); 453*58a1b1bbSMatthias Ringwald usart_disable_interrupt(BOARD_USART, US_IER_RXRDY); 454*58a1b1bbSMatthias Ringwald rx_done_handler(); 455*58a1b1bbSMatthias Ringwald } 456*58a1b1bbSMatthias Ringwald } 457*58a1b1bbSMatthias Ringwald } 458*58a1b1bbSMatthias Ringwald #endif 459*58a1b1bbSMatthias Ringwald 460*58a1b1bbSMatthias Ringwald void hal_tick_init() 461*58a1b1bbSMatthias Ringwald { 462*58a1b1bbSMatthias Ringwald /* Configure systick for 1 ms */ 463*58a1b1bbSMatthias Ringwald puts("Configure system tick to get 1ms tick period.\r"); 464*58a1b1bbSMatthias Ringwald if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { 465*58a1b1bbSMatthias Ringwald puts("-F- Systick configuration error\r"); 466*58a1b1bbSMatthias Ringwald while (1); 467*58a1b1bbSMatthias Ringwald } 468*58a1b1bbSMatthias Ringwald } 469*58a1b1bbSMatthias Ringwald 470*58a1b1bbSMatthias Ringwald void hal_tick_set_handler(void (*handler)(void)){ 471*58a1b1bbSMatthias Ringwald if (handler == NULL){ 472*58a1b1bbSMatthias Ringwald tick_handler = &dummy_handler; 473*58a1b1bbSMatthias Ringwald return; 474*58a1b1bbSMatthias Ringwald } 475*58a1b1bbSMatthias Ringwald tick_handler = handler; 476*58a1b1bbSMatthias Ringwald } 477*58a1b1bbSMatthias Ringwald 478*58a1b1bbSMatthias Ringwald int hal_tick_get_tick_period_in_ms(void){ 479*58a1b1bbSMatthias Ringwald return 1; 480*58a1b1bbSMatthias Ringwald } 481*58a1b1bbSMatthias Ringwald 482*58a1b1bbSMatthias Ringwald 4831b2596b5SMatthias Ringwald /** 4841b2596b5SMatthias Ringwald * \brief getting-started Application entry point. 4851b2596b5SMatthias Ringwald * 4861b2596b5SMatthias Ringwald * \return Unused (ANSI-C compatibility). 4871b2596b5SMatthias Ringwald */ 4881b2596b5SMatthias Ringwald // [main] 4891b2596b5SMatthias Ringwald int main(void) 4901b2596b5SMatthias Ringwald { 4911b2596b5SMatthias Ringwald //! [main_step_sys_init] 4921b2596b5SMatthias Ringwald /* Initialize the SAM system */ 4931b2596b5SMatthias Ringwald sysclk_init(); 4941b2596b5SMatthias Ringwald board_init(); 4951b2596b5SMatthias Ringwald //! [main_step_sys_init] 4961b2596b5SMatthias Ringwald 4971b2596b5SMatthias Ringwald //! [main_step_console_init] 4981b2596b5SMatthias Ringwald /* Initialize the console uart */ 4991b2596b5SMatthias Ringwald configure_console(); 5001b2596b5SMatthias Ringwald //! [main_step_console_init] 5011b2596b5SMatthias Ringwald 5021b2596b5SMatthias Ringwald /* Output example information */ 5031b2596b5SMatthias Ringwald puts(STRING_HEADER); 5041b2596b5SMatthias Ringwald 505*58a1b1bbSMatthias Ringwald printf("CPU %lu hz, peripheral clock %lu hz\n", sysclk_get_cpu_hz(), sysclk_get_peripheral_hz()); 506*58a1b1bbSMatthias Ringwald 507*58a1b1bbSMatthias Ringwald // start with BTstack init - especially configure HCI Transport 508*58a1b1bbSMatthias Ringwald btstack_memory_init(); 509*58a1b1bbSMatthias Ringwald btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); 510*58a1b1bbSMatthias Ringwald 511*58a1b1bbSMatthias Ringwald // enable full log output while porting 512*58a1b1bbSMatthias Ringwald // hci_dump_open(NULL, HCI_DUMP_STDOUT); 513*58a1b1bbSMatthias Ringwald 514*58a1b1bbSMatthias Ringwald // init HCI 515*58a1b1bbSMatthias Ringwald // hci_init(hci_transport_h4_instance(), (void*) &hci_transport_config); 516*58a1b1bbSMatthias Ringwald // hci_set_chipset(btstack_chipset_cc256x_instance()); 517*58a1b1bbSMatthias Ringwald // hci_set_link_key_db(btstack_link_key_db_memory_instance()); 518*58a1b1bbSMatthias Ringwald 519*58a1b1bbSMatthias Ringwald // enable eHCILL 520*58a1b1bbSMatthias Ringwald // bt_control_cc256x_enable_ehcill(1); 521*58a1b1bbSMatthias Ringwald 522*58a1b1bbSMatthias Ringwald // hand over to btstack embedded code 523*58a1b1bbSMatthias Ringwald btstack_main(0, NULL); 524*58a1b1bbSMatthias Ringwald 525*58a1b1bbSMatthias Ringwald // go 526*58a1b1bbSMatthias Ringwald btstack_run_loop_execute(); 527*58a1b1bbSMatthias Ringwald 528*58a1b1bbSMatthias Ringwald // compiler happy 5291b2596b5SMatthias Ringwald while(1); 5301b2596b5SMatthias Ringwald } 5311b2596b5SMatthias Ringwald // [main] 5321b2596b5SMatthias Ringwald /// @cond 0 5331b2596b5SMatthias Ringwald /**INDENT-OFF**/ 5341b2596b5SMatthias Ringwald #ifdef __cplusplus 5351b2596b5SMatthias Ringwald } 5361b2596b5SMatthias Ringwald #endif 5371b2596b5SMatthias Ringwald /**INDENT-ON**/ 5381b2596b5SMatthias Ringwald /// @endcond 539