11b2596b5SMatthias Ringwald #include "asf.h" 21b2596b5SMatthias Ringwald #include "stdio_serial.h" 31b2596b5SMatthias Ringwald #include "conf_board.h" 41b2596b5SMatthias Ringwald #include "conf_clock.h" 51b2596b5SMatthias Ringwald 658a1b1bbSMatthias Ringwald // BTstack 7*13b8e9b1SMatthias Ringwald #include "btstack_chipset_atwilc3000.h" 8*13b8e9b1SMatthias Ringwald #include "btstack_debug.h" 9*13b8e9b1SMatthias Ringwald #include "btstack_memory.h" 1058a1b1bbSMatthias Ringwald #include "btstack_run_loop.h" 1158a1b1bbSMatthias Ringwald #include "btstack_run_loop_embedded.h" 1258a1b1bbSMatthias Ringwald #include "classic/btstack_link_key_db.h" 1358a1b1bbSMatthias Ringwald #include "hal_uart_dma.h" 1458a1b1bbSMatthias Ringwald #include "hal_cpu.h" 1558a1b1bbSMatthias Ringwald #include "hal_tick.h" 16*13b8e9b1SMatthias Ringwald #include "hci.h" 17*13b8e9b1SMatthias Ringwald #include "hci_dump.h" 18*13b8e9b1SMatthias Ringwald #include "wilc3000_bt_firmware.h" 1958a1b1bbSMatthias Ringwald 20*13b8e9b1SMatthias Ringwald // #define USE_XDMAC_FOR_USART 2158a1b1bbSMatthias Ringwald #define XDMA_CH_UART_TX 0 2258a1b1bbSMatthias Ringwald #define XDMA_CH_UART_RX 1 231b2596b5SMatthias Ringwald 2458a1b1bbSMatthias Ringwald /** All interrupt mask. */ 2558a1b1bbSMatthias Ringwald #define ALL_INTERRUPT_MASK 0xffffffff 261b2596b5SMatthias Ringwald 271b2596b5SMatthias Ringwald #ifdef __cplusplus 281b2596b5SMatthias Ringwald extern "C" { 291b2596b5SMatthias Ringwald #endif 30*13b8e9b1SMatthias Ringwald 31*13b8e9b1SMatthias Ringwald extern int btstack_main(int argc, const char * argv[]); 32*13b8e9b1SMatthias Ringwald 33*13b8e9b1SMatthias Ringwald static void dummy_handler(void){} 34*13b8e9b1SMatthias Ringwald static void (*tick_handler)(void) = &dummy_handler; 35*13b8e9b1SMatthias Ringwald 36*13b8e9b1SMatthias Ringwald static btstack_uart_config_t uart_config; 37*13b8e9b1SMatthias Ringwald 38*13b8e9b1SMatthias Ringwald static hci_transport_config_uart_t transport_config = { 39*13b8e9b1SMatthias Ringwald HCI_TRANSPORT_CONFIG_UART, 40*13b8e9b1SMatthias Ringwald 115200, 41*13b8e9b1SMatthias Ringwald 921600, // use 0 to skip baud rate change from 115200 to X for debugging purposes 42*13b8e9b1SMatthias Ringwald 1, // flow control 43*13b8e9b1SMatthias Ringwald NULL, 44*13b8e9b1SMatthias Ringwald }; 451b2596b5SMatthias Ringwald 461b2596b5SMatthias Ringwald /** 471b2596b5SMatthias Ringwald * \brief Handler for System Tick interrupt. 481b2596b5SMatthias Ringwald */ 491b2596b5SMatthias Ringwald void SysTick_Handler(void) 501b2596b5SMatthias Ringwald { 5158a1b1bbSMatthias Ringwald tick_handler(); 521b2596b5SMatthias Ringwald } 531b2596b5SMatthias Ringwald 541b2596b5SMatthias Ringwald /** 551b2596b5SMatthias Ringwald * Configure UART console. 561b2596b5SMatthias Ringwald */ 571b2596b5SMatthias Ringwald // [main_console_configure] 581b2596b5SMatthias Ringwald static void configure_console(void) 591b2596b5SMatthias Ringwald { 601b2596b5SMatthias Ringwald const usart_serial_options_t uart_serial_options = { 611b2596b5SMatthias Ringwald .baudrate = CONF_UART_BAUDRATE, 621b2596b5SMatthias Ringwald #ifdef CONF_UART_CHAR_LENGTH 631b2596b5SMatthias Ringwald .charlength = CONF_UART_CHAR_LENGTH, 641b2596b5SMatthias Ringwald #endif 651b2596b5SMatthias Ringwald .paritytype = CONF_UART_PARITY, 661b2596b5SMatthias Ringwald #ifdef CONF_UART_STOP_BITS 671b2596b5SMatthias Ringwald .stopbits = CONF_UART_STOP_BITS, 681b2596b5SMatthias Ringwald #endif 691b2596b5SMatthias Ringwald }; 701b2596b5SMatthias Ringwald 711b2596b5SMatthias Ringwald /* Configure console UART. */ 721b2596b5SMatthias Ringwald sysclk_enable_peripheral_clock(CONSOLE_UART_ID); 731b2596b5SMatthias Ringwald stdio_serial_init(CONF_UART, &uart_serial_options); 741b2596b5SMatthias Ringwald } 751b2596b5SMatthias Ringwald 761b2596b5SMatthias Ringwald // [main_console_configure] 771b2596b5SMatthias Ringwald 781b2596b5SMatthias Ringwald /** 7958a1b1bbSMatthias Ringwald * \brief Wait for the given number of milliseconds (ticks 801b2596b5SMatthias Ringwald * generated by the SAM's microcontrollers's system tick). 811b2596b5SMatthias Ringwald * 821b2596b5SMatthias Ringwald * \param ul_dly_ticks Delay to wait for, in milliseconds. 831b2596b5SMatthias Ringwald */ 841b2596b5SMatthias Ringwald // [main_ms_delay] 8558a1b1bbSMatthias Ringwald static void mdelay(uint32_t delay_in_ms) 861b2596b5SMatthias Ringwald { 8758a1b1bbSMatthias Ringwald // delay_ms(delay_in_ms); 8858a1b1bbSMatthias Ringwald uint32_t time_to_wait = btstack_run_loop_get_time_ms() + delay_in_ms; 8958a1b1bbSMatthias Ringwald while (btstack_run_loop_get_time_ms() < time_to_wait); 901b2596b5SMatthias Ringwald } 911b2596b5SMatthias Ringwald // [main_ms_delay] 921b2596b5SMatthias Ringwald 9358a1b1bbSMatthias Ringwald //////////////////////////////////////////////////////////////////////////////// 9458a1b1bbSMatthias Ringwald // hal_cpu.h implementation 9558a1b1bbSMatthias Ringwald //////////////////////////////////////////////////////////////////////////////// 9658a1b1bbSMatthias Ringwald // hal_led.h implementation 9758a1b1bbSMatthias Ringwald #include "hal_led.h" 9858a1b1bbSMatthias Ringwald void hal_led_off(void); 9958a1b1bbSMatthias Ringwald void hal_led_on(void); 10058a1b1bbSMatthias Ringwald 10158a1b1bbSMatthias Ringwald void hal_led_off(void){ 10258a1b1bbSMatthias Ringwald // gpio_set_pin_low(GPIOA, GPIO_LED2); 10358a1b1bbSMatthias Ringwald } 10458a1b1bbSMatthias Ringwald void hal_led_on(void){ 10558a1b1bbSMatthias Ringwald // gpio_set_pin_high(GPIOA, GPIO_LED2); 10658a1b1bbSMatthias Ringwald } 10758a1b1bbSMatthias Ringwald void hal_led_toggle(void){ 10858a1b1bbSMatthias Ringwald // gpio_toggle_pin(GPIOA, GPIO_LED2); 10958a1b1bbSMatthias Ringwald } 11058a1b1bbSMatthias Ringwald 11158a1b1bbSMatthias Ringwald // hal_cpu.h implementation 11258a1b1bbSMatthias Ringwald #include "hal_cpu.h" 11358a1b1bbSMatthias Ringwald 11458a1b1bbSMatthias Ringwald void hal_cpu_disable_irqs(void){ 11558a1b1bbSMatthias Ringwald //__disable_irq(); 11658a1b1bbSMatthias Ringwald } 11758a1b1bbSMatthias Ringwald 11858a1b1bbSMatthias Ringwald void hal_cpu_enable_irqs(void){ 11958a1b1bbSMatthias Ringwald // __enable_irq(); 12058a1b1bbSMatthias Ringwald } 12158a1b1bbSMatthias Ringwald 12258a1b1bbSMatthias Ringwald void hal_cpu_enable_irqs_and_sleep(void){ 12358a1b1bbSMatthias Ringwald hal_led_off(); 12458a1b1bbSMatthias Ringwald // __enable_irq(); 12558a1b1bbSMatthias Ringwald // __asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag 12658a1b1bbSMatthias Ringwald 12758a1b1bbSMatthias Ringwald // note: hal_uart_needed_during_sleep can be used to disable peripheral clock if it's not needed for a timer 12858a1b1bbSMatthias Ringwald hal_led_on(); 12958a1b1bbSMatthias Ringwald } 13058a1b1bbSMatthias Ringwald 13158a1b1bbSMatthias Ringwald 13258a1b1bbSMatthias Ringwald #ifndef USE_XDMAC_FOR_USART 13358a1b1bbSMatthias Ringwald // RX state 13458a1b1bbSMatthias Ringwald static volatile uint16_t bytes_to_read = 0; 13558a1b1bbSMatthias Ringwald static volatile uint8_t * rx_buffer_ptr = 0; 13658a1b1bbSMatthias Ringwald 13758a1b1bbSMatthias Ringwald // TX state 13858a1b1bbSMatthias Ringwald static volatile uint16_t bytes_to_write = 0; 13958a1b1bbSMatthias Ringwald static volatile uint8_t * tx_buffer_ptr = 0; 14058a1b1bbSMatthias Ringwald #endif 14158a1b1bbSMatthias Ringwald 14258a1b1bbSMatthias Ringwald // handlers 14358a1b1bbSMatthias Ringwald static void (*rx_done_handler)(void) = dummy_handler; 14458a1b1bbSMatthias Ringwald static void (*tx_done_handler)(void) = dummy_handler; 14558a1b1bbSMatthias Ringwald static void (*cts_irq_handler)(void) = dummy_handler; 14658a1b1bbSMatthias Ringwald 14758a1b1bbSMatthias Ringwald // @note While the Atmel SAM S7x data sheet states 14858a1b1bbSMatthias Ringwald // "The hardware handshaking feature enables an out-of-band flow control by automatic management 14958a1b1bbSMatthias Ringwald // of the pins RTS and CTS.", 15058a1b1bbSMatthias Ringwald // I didn't see RTS going up automatically up, ever. So, at least for RTS, the automatic management 15158a1b1bbSMatthias Ringwald // is just a glorified GPIO pin control feature, which provides no benefit, but irritates a lot 15258a1b1bbSMatthias Ringwald 15358a1b1bbSMatthias Ringwald static void hal_uart_rts_high(void){ 15458a1b1bbSMatthias Ringwald BOARD_USART->US_CR = US_CR_RTSEN; 15558a1b1bbSMatthias Ringwald } 15658a1b1bbSMatthias Ringwald static void hal_uart_rts_low(void){ 15758a1b1bbSMatthias Ringwald BOARD_USART->US_CR = US_CR_RTSDIS; 15858a1b1bbSMatthias Ringwald } 15958a1b1bbSMatthias Ringwald 16058a1b1bbSMatthias Ringwald /** 16158a1b1bbSMatthias Ringwald */ 16258a1b1bbSMatthias Ringwald void hal_uart_dma_init(void) 16358a1b1bbSMatthias Ringwald { 164*13b8e9b1SMatthias Ringwald // power on 165*13b8e9b1SMatthias Ringwald ioport_set_pin_dir(BLUETOOTH_CHP_EN, IOPORT_DIR_OUTPUT); 166*13b8e9b1SMatthias Ringwald ioport_set_pin_level(BLUETOOTH_CHP_EN, IOPORT_PIN_LEVEL_HIGH); 167*13b8e9b1SMatthias Ringwald 168*13b8e9b1SMatthias Ringwald // reset 169*13b8e9b1SMatthias Ringwald ioport_set_pin_dir(BLUETOOTH_RESET, IOPORT_DIR_OUTPUT); 170*13b8e9b1SMatthias Ringwald ioport_set_pin_level(BLUETOOTH_RESET, IOPORT_PIN_LEVEL_LOW); 171*13b8e9b1SMatthias Ringwald mdelay(250); 172*13b8e9b1SMatthias Ringwald ioport_set_pin_level(BLUETOOTH_RESET, IOPORT_PIN_LEVEL_HIGH); 173*13b8e9b1SMatthias Ringwald mdelay(250); 174*13b8e9b1SMatthias Ringwald 175*13b8e9b1SMatthias Ringwald /* Enable the peripheral clock in the PMC. */ 176*13b8e9b1SMatthias Ringwald sysclk_enable_peripheral_clock(BOARD_ID_USART); 17758a1b1bbSMatthias Ringwald 17858a1b1bbSMatthias Ringwald // configure Bluetooth USART 17958a1b1bbSMatthias Ringwald const sam_usart_opt_t bluetooth_settings = { 18058a1b1bbSMatthias Ringwald 115200, 18158a1b1bbSMatthias Ringwald US_MR_CHRL_8_BIT, 18258a1b1bbSMatthias Ringwald US_MR_PAR_NO, 18358a1b1bbSMatthias Ringwald US_MR_NBSTOP_1_BIT, 18458a1b1bbSMatthias Ringwald US_MR_CHMODE_NORMAL, 18558a1b1bbSMatthias Ringwald /* This field is only used in IrDA mode. */ 18658a1b1bbSMatthias Ringwald 0 18758a1b1bbSMatthias Ringwald }; 18858a1b1bbSMatthias Ringwald 18958a1b1bbSMatthias Ringwald /* Configure USART mode. */ 190*13b8e9b1SMatthias Ringwald #if 0 19158a1b1bbSMatthias Ringwald usart_init_hw_handshaking(BOARD_USART, &bluetooth_settings, sysclk_get_peripheral_hz()); 192*13b8e9b1SMatthias Ringwald hal_uart_rts_low(); 193*13b8e9b1SMatthias Ringwald #else 194*13b8e9b1SMatthias Ringwald usart_init_rs232(BOARD_USART, &bluetooth_settings, sysclk_get_peripheral_hz()); 195*13b8e9b1SMatthias Ringwald #endif 19658a1b1bbSMatthias Ringwald 19758a1b1bbSMatthias Ringwald /* Disable all the interrupts. */ 19858a1b1bbSMatthias Ringwald usart_disable_interrupt(BOARD_USART, ALL_INTERRUPT_MASK); 19958a1b1bbSMatthias Ringwald 20058a1b1bbSMatthias Ringwald /* Enable TX & RX function. */ 20158a1b1bbSMatthias Ringwald usart_enable_tx(BOARD_USART); 20258a1b1bbSMatthias Ringwald usart_enable_rx(BOARD_USART); 20358a1b1bbSMatthias Ringwald 20458a1b1bbSMatthias Ringwald /* Configure and enable interrupt of USART. */ 20558a1b1bbSMatthias Ringwald NVIC_EnableIRQ(USART_IRQn); 20658a1b1bbSMatthias Ringwald 20758a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 20858a1b1bbSMatthias Ringwald 20958a1b1bbSMatthias Ringwald // setup XDMAC 21058a1b1bbSMatthias Ringwald 21158a1b1bbSMatthias Ringwald /* Initialize and enable DMA controller */ 21258a1b1bbSMatthias Ringwald pmc_enable_periph_clk(ID_XDMAC); 21358a1b1bbSMatthias Ringwald 21458a1b1bbSMatthias Ringwald /* Enable XDMA interrupt */ 21558a1b1bbSMatthias Ringwald NVIC_ClearPendingIRQ(XDMAC_IRQn); 21658a1b1bbSMatthias Ringwald NVIC_SetPriority( XDMAC_IRQn ,1); 21758a1b1bbSMatthias Ringwald NVIC_EnableIRQ(XDMAC_IRQn); 21858a1b1bbSMatthias Ringwald 21958a1b1bbSMatthias Ringwald // Setup XDMA Channel for USART TX 22058a1b1bbSMatthias Ringwald xdmac_channel_set_destination_addr(XDMAC, XDMA_CH_UART_TX, (uint32_t)&BOARD_USART->US_THR); 22158a1b1bbSMatthias Ringwald xdmac_channel_set_config(XDMAC, XDMA_CH_UART_TX, 22258a1b1bbSMatthias Ringwald XDMAC_CC_TYPE_PER_TRAN | 22358a1b1bbSMatthias Ringwald XDMAC_CC_DSYNC_MEM2PER | 22458a1b1bbSMatthias Ringwald XDMAC_CC_MEMSET_NORMAL_MODE | 22558a1b1bbSMatthias Ringwald XDMAC_CC_MBSIZE_SINGLE | 22658a1b1bbSMatthias Ringwald XDMAC_CC_DWIDTH_BYTE | 22758a1b1bbSMatthias Ringwald XDMAC_CC_SIF_AHB_IF0 | 22858a1b1bbSMatthias Ringwald XDMAC_CC_DIF_AHB_IF1 | 22958a1b1bbSMatthias Ringwald XDMAC_CC_SAM_INCREMENTED_AM | 23058a1b1bbSMatthias Ringwald XDMAC_CC_DAM_FIXED_AM | 23158a1b1bbSMatthias Ringwald XDMAC_CC_CSIZE_CHK_1 | 23258a1b1bbSMatthias Ringwald XDMAC_CC_PERID(XDAMC_CHANNEL_HWID_USART0_TX) 23358a1b1bbSMatthias Ringwald ); 23458a1b1bbSMatthias Ringwald xdmac_channel_set_descriptor_control(XDMAC, XDMA_CH_UART_TX, 0); 23558a1b1bbSMatthias Ringwald xdmac_channel_set_source_microblock_stride(XDMAC, XDMA_CH_UART_TX, 0); 23658a1b1bbSMatthias Ringwald xdmac_channel_set_destination_microblock_stride(XDMAC, XDMA_CH_UART_TX, 0); 23758a1b1bbSMatthias Ringwald xdmac_channel_set_datastride_mempattern(XDMAC, XDMA_CH_UART_TX, 0); 23858a1b1bbSMatthias Ringwald xdmac_channel_set_block_control(XDMAC, XDMA_CH_UART_TX, 0); 23958a1b1bbSMatthias Ringwald xdmac_enable_interrupt(XDMAC, XDMA_CH_UART_TX); 24058a1b1bbSMatthias Ringwald xdmac_channel_enable_interrupt(XDMAC, XDMA_CH_UART_TX, XDMAC_CIE_BIE); 24158a1b1bbSMatthias Ringwald 24258a1b1bbSMatthias Ringwald // Setup XDMA Channel for USART RX 24358a1b1bbSMatthias Ringwald xdmac_channel_set_source_addr(XDMAC, XDMA_CH_UART_RX, (uint32_t)&BOARD_USART->US_RHR); 24458a1b1bbSMatthias Ringwald xdmac_channel_set_config(XDMAC, XDMA_CH_UART_RX, 24558a1b1bbSMatthias Ringwald XDMAC_CC_TYPE_PER_TRAN | 24658a1b1bbSMatthias Ringwald XDMAC_CC_DSYNC_PER2MEM | 24758a1b1bbSMatthias Ringwald XDMAC_CC_MEMSET_NORMAL_MODE | 24858a1b1bbSMatthias Ringwald XDMAC_CC_MBSIZE_SINGLE | 24958a1b1bbSMatthias Ringwald XDMAC_CC_DWIDTH_BYTE | 25058a1b1bbSMatthias Ringwald XDMAC_CC_SIF_AHB_IF1 | 25158a1b1bbSMatthias Ringwald XDMAC_CC_DIF_AHB_IF0 | 25258a1b1bbSMatthias Ringwald XDMAC_CC_SAM_FIXED_AM | 25358a1b1bbSMatthias Ringwald XDMAC_CC_DAM_INCREMENTED_AM | 25458a1b1bbSMatthias Ringwald XDMAC_CC_CSIZE_CHK_1 | 25558a1b1bbSMatthias Ringwald XDMAC_CC_PERID(XDAMC_CHANNEL_HWID_USART0_RX) 25658a1b1bbSMatthias Ringwald ); 25758a1b1bbSMatthias Ringwald xdmac_channel_set_descriptor_control(XDMAC, XDMA_CH_UART_RX, 0); 25858a1b1bbSMatthias Ringwald xdmac_channel_set_source_microblock_stride(XDMAC, XDMA_CH_UART_RX, 0); 25958a1b1bbSMatthias Ringwald xdmac_channel_set_destination_microblock_stride(XDMAC, XDMA_CH_UART_RX, 0); 26058a1b1bbSMatthias Ringwald xdmac_channel_set_datastride_mempattern(XDMAC, XDMA_CH_UART_RX, 0); 26158a1b1bbSMatthias Ringwald xdmac_channel_set_block_control(XDMAC, XDMA_CH_UART_RX, 0); 26258a1b1bbSMatthias Ringwald xdmac_enable_interrupt(XDMAC, XDMA_CH_UART_RX); 26358a1b1bbSMatthias Ringwald xdmac_channel_enable_interrupt(XDMAC, XDMA_CH_UART_RX, XDMAC_CIE_BIE); 26458a1b1bbSMatthias Ringwald #endif 26558a1b1bbSMatthias Ringwald } 26658a1b1bbSMatthias Ringwald 26758a1b1bbSMatthias Ringwald void hal_uart_dma_set_sleep(uint8_t sleep){ 26858a1b1bbSMatthias Ringwald } 26958a1b1bbSMatthias Ringwald 27058a1b1bbSMatthias Ringwald void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){ 27158a1b1bbSMatthias Ringwald rx_done_handler = the_block_handler; 27258a1b1bbSMatthias Ringwald } 27358a1b1bbSMatthias Ringwald 27458a1b1bbSMatthias Ringwald void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){ 27558a1b1bbSMatthias Ringwald tx_done_handler = the_block_handler; 27658a1b1bbSMatthias Ringwald } 27758a1b1bbSMatthias Ringwald 27858a1b1bbSMatthias Ringwald void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){ 27958a1b1bbSMatthias Ringwald cts_irq_handler = the_irq_handler; 28058a1b1bbSMatthias Ringwald } 28158a1b1bbSMatthias Ringwald 28258a1b1bbSMatthias Ringwald int hal_uart_dma_set_baud(uint32_t baud){ 28358a1b1bbSMatthias Ringwald /* Disable TX & RX function. */ 28458a1b1bbSMatthias Ringwald usart_disable_tx(BOARD_USART); 28558a1b1bbSMatthias Ringwald usart_disable_rx(BOARD_USART); 28658a1b1bbSMatthias Ringwald uint32_t res = usart_set_async_baudrate(BOARD_USART, baud, sysclk_get_peripheral_hz()); 28758a1b1bbSMatthias Ringwald if (res){ 28858a1b1bbSMatthias Ringwald log_error("hal_uart_dma_set_baud library call failed"); 28958a1b1bbSMatthias Ringwald } 29058a1b1bbSMatthias Ringwald 29158a1b1bbSMatthias Ringwald /* Enable TX & RX function. */ 29258a1b1bbSMatthias Ringwald usart_enable_tx(BOARD_USART); 29358a1b1bbSMatthias Ringwald usart_enable_rx(BOARD_USART); 29458a1b1bbSMatthias Ringwald 295*13b8e9b1SMatthias Ringwald log_info("set baud rate %u", (int) baud); 296*13b8e9b1SMatthias Ringwald return 0; 297*13b8e9b1SMatthias Ringwald } 29858a1b1bbSMatthias Ringwald 299*13b8e9b1SMatthias Ringwald int hal_uart_dma_set_flowcontrol(uint32_t flowcontrol){ 300*13b8e9b1SMatthias Ringwald UNUSED(flowcontrol); 30158a1b1bbSMatthias Ringwald return 0; 30258a1b1bbSMatthias Ringwald } 30358a1b1bbSMatthias Ringwald 30458a1b1bbSMatthias Ringwald void hal_uart_dma_send_block(const uint8_t *data, uint16_t size){ 305*13b8e9b1SMatthias Ringwald // log_info("send %u", size); 306*13b8e9b1SMatthias Ringwald // log_info_hexdump(data, size); 30758a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 30858a1b1bbSMatthias Ringwald xdmac_channel_get_interrupt_status( XDMAC, XDMA_CH_UART_TX); 30958a1b1bbSMatthias Ringwald xdmac_channel_set_source_addr(XDMAC, XDMA_CH_UART_TX, (uint32_t)data); 31058a1b1bbSMatthias Ringwald xdmac_channel_set_microblock_control(XDMAC, XDMA_CH_UART_TX, size); 31158a1b1bbSMatthias Ringwald xdmac_channel_enable(XDMAC, XDMA_CH_UART_TX); 31258a1b1bbSMatthias Ringwald #else 31358a1b1bbSMatthias Ringwald tx_buffer_ptr = (uint8_t *) data; 31458a1b1bbSMatthias Ringwald bytes_to_write = size; 31558a1b1bbSMatthias Ringwald usart_enable_interrupt(BOARD_USART, US_IER_TXRDY); 31658a1b1bbSMatthias Ringwald #endif 31758a1b1bbSMatthias Ringwald } 31858a1b1bbSMatthias Ringwald 31958a1b1bbSMatthias Ringwald void hal_uart_dma_receive_block(uint8_t *data, uint16_t size){ 32058a1b1bbSMatthias Ringwald 32158a1b1bbSMatthias Ringwald hal_uart_rts_low(); 32258a1b1bbSMatthias Ringwald 32358a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 32458a1b1bbSMatthias Ringwald xdmac_channel_get_interrupt_status( XDMAC, XDMA_CH_UART_RX); 32558a1b1bbSMatthias Ringwald xdmac_channel_set_destination_addr(XDMAC, XDMA_CH_UART_RX, (uint32_t)data); 32658a1b1bbSMatthias Ringwald xdmac_channel_set_microblock_control(XDMAC, XDMA_CH_UART_RX, size); 32758a1b1bbSMatthias Ringwald xdmac_channel_enable(XDMAC, XDMA_CH_UART_RX); 32858a1b1bbSMatthias Ringwald #else 32958a1b1bbSMatthias Ringwald rx_buffer_ptr = data; 33058a1b1bbSMatthias Ringwald bytes_to_read = size; 33158a1b1bbSMatthias Ringwald usart_enable_interrupt(BOARD_USART, US_IER_RXRDY); 33258a1b1bbSMatthias Ringwald #endif 33358a1b1bbSMatthias Ringwald } 33458a1b1bbSMatthias Ringwald 33558a1b1bbSMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 33658a1b1bbSMatthias Ringwald void XDMAC_Handler(void) 33758a1b1bbSMatthias Ringwald { 33858a1b1bbSMatthias Ringwald uint32_t dma_status; 33958a1b1bbSMatthias Ringwald dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_UART_TX); 34058a1b1bbSMatthias Ringwald if (dma_status & XDMAC_CIS_BIS) { 34158a1b1bbSMatthias Ringwald tx_done_handler(); 34258a1b1bbSMatthias Ringwald } 34358a1b1bbSMatthias Ringwald dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_UART_RX); 34458a1b1bbSMatthias Ringwald if (dma_status & XDMAC_CIS_BIS) { 34558a1b1bbSMatthias Ringwald hal_uart_rts_high(); 34658a1b1bbSMatthias Ringwald rx_done_handler(); 34758a1b1bbSMatthias Ringwald } 34858a1b1bbSMatthias Ringwald } 34958a1b1bbSMatthias Ringwald #else 35058a1b1bbSMatthias Ringwald void USART_Handler(void) 35158a1b1bbSMatthias Ringwald { 35258a1b1bbSMatthias Ringwald uint32_t ul_status; 35358a1b1bbSMatthias Ringwald 35458a1b1bbSMatthias Ringwald /* Read USART status. */ 35558a1b1bbSMatthias Ringwald ul_status = usart_get_status(BOARD_USART); 35658a1b1bbSMatthias Ringwald 35758a1b1bbSMatthias Ringwald // handle ready to send 35858a1b1bbSMatthias Ringwald if(ul_status & US_IER_TXRDY) { 35958a1b1bbSMatthias Ringwald if (bytes_to_write){ 36058a1b1bbSMatthias Ringwald // send next byte 36158a1b1bbSMatthias Ringwald usart_write(BOARD_USART, *tx_buffer_ptr); 36258a1b1bbSMatthias Ringwald tx_buffer_ptr++; 36358a1b1bbSMatthias Ringwald bytes_to_write--; 36458a1b1bbSMatthias Ringwald } else { 36558a1b1bbSMatthias Ringwald // done. disable tx ready interrupt to avoid starvation here 36658a1b1bbSMatthias Ringwald usart_disable_interrupt(BOARD_USART, US_IER_TXRDY); 36758a1b1bbSMatthias Ringwald tx_done_handler(); 36858a1b1bbSMatthias Ringwald } 36958a1b1bbSMatthias Ringwald } 37058a1b1bbSMatthias Ringwald 37158a1b1bbSMatthias Ringwald // handle byte available for read 37258a1b1bbSMatthias Ringwald if (ul_status & US_IER_RXRDY) { 37358a1b1bbSMatthias Ringwald uint32_t ch; 37458a1b1bbSMatthias Ringwald usart_read(BOARD_USART, (uint32_t *)&ch); 37558a1b1bbSMatthias Ringwald *rx_buffer_ptr++ = ch; 37658a1b1bbSMatthias Ringwald bytes_to_read--; 37758a1b1bbSMatthias Ringwald if (bytes_to_read == 0){ 37858a1b1bbSMatthias Ringwald // done. disable rx ready interrupt, raise RTS 37958a1b1bbSMatthias Ringwald hal_uart_rts_high(); 38058a1b1bbSMatthias Ringwald usart_disable_interrupt(BOARD_USART, US_IER_RXRDY); 38158a1b1bbSMatthias Ringwald rx_done_handler(); 38258a1b1bbSMatthias Ringwald } 38358a1b1bbSMatthias Ringwald } 38458a1b1bbSMatthias Ringwald } 38558a1b1bbSMatthias Ringwald #endif 38658a1b1bbSMatthias Ringwald 38758a1b1bbSMatthias Ringwald void hal_tick_init() 38858a1b1bbSMatthias Ringwald { 38958a1b1bbSMatthias Ringwald /* Configure systick for 1 ms */ 39058a1b1bbSMatthias Ringwald puts("Configure system tick to get 1ms tick period.\r"); 39158a1b1bbSMatthias Ringwald if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { 39258a1b1bbSMatthias Ringwald puts("-F- Systick configuration error\r"); 39358a1b1bbSMatthias Ringwald while (1); 39458a1b1bbSMatthias Ringwald } 39558a1b1bbSMatthias Ringwald } 39658a1b1bbSMatthias Ringwald 39758a1b1bbSMatthias Ringwald void hal_tick_set_handler(void (*handler)(void)){ 39858a1b1bbSMatthias Ringwald if (handler == NULL){ 39958a1b1bbSMatthias Ringwald tick_handler = &dummy_handler; 40058a1b1bbSMatthias Ringwald return; 40158a1b1bbSMatthias Ringwald } 40258a1b1bbSMatthias Ringwald tick_handler = handler; 40358a1b1bbSMatthias Ringwald } 40458a1b1bbSMatthias Ringwald 40558a1b1bbSMatthias Ringwald int hal_tick_get_tick_period_in_ms(void){ 40658a1b1bbSMatthias Ringwald return 1; 40758a1b1bbSMatthias Ringwald } 40858a1b1bbSMatthias Ringwald 409*13b8e9b1SMatthias Ringwald static const btstack_uart_block_t * uart_driver; 410*13b8e9b1SMatthias Ringwald 411*13b8e9b1SMatthias Ringwald static void phase2(int status){ 412*13b8e9b1SMatthias Ringwald 413*13b8e9b1SMatthias Ringwald if (status){ 414*13b8e9b1SMatthias Ringwald printf("Download firmware failed\n"); 415*13b8e9b1SMatthias Ringwald return; 416*13b8e9b1SMatthias Ringwald } 417*13b8e9b1SMatthias Ringwald 418*13b8e9b1SMatthias Ringwald printf("Phase 2: Main app\n"); 419*13b8e9b1SMatthias Ringwald 420*13b8e9b1SMatthias Ringwald // init HCI 421*13b8e9b1SMatthias Ringwald const hci_transport_t * transport = hci_transport_h4_instance(uart_driver); 422*13b8e9b1SMatthias Ringwald // const btstack_link_key_db_t * link_key_db = btstack_link_key_db_fs_instance(); 423*13b8e9b1SMatthias Ringwald hci_init(transport, (void*) &transport_config); 424*13b8e9b1SMatthias Ringwald hci_set_chipset(btstack_chipset_atwilc3000_instance()); 425*13b8e9b1SMatthias Ringwald // hci_set_link_key_db(link_key_db); 426*13b8e9b1SMatthias Ringwald 427*13b8e9b1SMatthias Ringwald // setup app 428*13b8e9b1SMatthias Ringwald btstack_main(0, NULL); 429*13b8e9b1SMatthias Ringwald } 43058a1b1bbSMatthias Ringwald 4311b2596b5SMatthias Ringwald /** 4321b2596b5SMatthias Ringwald * \brief getting-started Application entry point. 4331b2596b5SMatthias Ringwald * 4341b2596b5SMatthias Ringwald * \return Unused (ANSI-C compatibility). 4351b2596b5SMatthias Ringwald */ 4361b2596b5SMatthias Ringwald // [main] 4371b2596b5SMatthias Ringwald int main(void) 4381b2596b5SMatthias Ringwald { 4391b2596b5SMatthias Ringwald /* Initialize the SAM system */ 4401b2596b5SMatthias Ringwald sysclk_init(); 4411b2596b5SMatthias Ringwald board_init(); 4421b2596b5SMatthias Ringwald 4431b2596b5SMatthias Ringwald /* Initialize the console uart */ 4441b2596b5SMatthias Ringwald configure_console(); 4451b2596b5SMatthias Ringwald 446*13b8e9b1SMatthias Ringwald /* Output boot info */ 447*13b8e9b1SMatthias Ringwald printf("BTstack on SAMV71 Xplained Ultra with ATWILC3000\n"); 44858a1b1bbSMatthias Ringwald printf("CPU %lu hz, peripheral clock %lu hz\n", sysclk_get_cpu_hz(), sysclk_get_peripheral_hz()); 449*13b8e9b1SMatthias Ringwald #ifdef USE_XDMAC_FOR_USART 450*13b8e9b1SMatthias Ringwald printf("Using XDMA for Bluetooth UART\n"); 451*13b8e9b1SMatthias Ringwald #else 452*13b8e9b1SMatthias Ringwald printf("Using IRQ driver for Bluetooth UART\n"); 453*13b8e9b1SMatthias Ringwald #endif 454*13b8e9b1SMatthias Ringwald printf("--\n"); 45558a1b1bbSMatthias Ringwald 45658a1b1bbSMatthias Ringwald // start with BTstack init - especially configure HCI Transport 45758a1b1bbSMatthias Ringwald btstack_memory_init(); 45858a1b1bbSMatthias Ringwald btstack_run_loop_init(btstack_run_loop_embedded_get_instance()); 45958a1b1bbSMatthias Ringwald 46058a1b1bbSMatthias Ringwald // enable full log output while porting 461*13b8e9b1SMatthias Ringwald hci_dump_open(NULL, HCI_DUMP_STDOUT); 46258a1b1bbSMatthias Ringwald 463*13b8e9b1SMatthias Ringwald // setup UART HAL + Run Loop integration 464*13b8e9b1SMatthias Ringwald uart_driver = btstack_uart_block_embedded_instance(); 46558a1b1bbSMatthias Ringwald 466*13b8e9b1SMatthias Ringwald // extract UART config from transport config, but disable flow control 467*13b8e9b1SMatthias Ringwald uart_config.baudrate = transport_config.baudrate_init; 468*13b8e9b1SMatthias Ringwald uart_config.flowcontrol = 0; 469*13b8e9b1SMatthias Ringwald uart_config.device_name = transport_config.device_name; 470*13b8e9b1SMatthias Ringwald uart_driver->init(&uart_config); 47158a1b1bbSMatthias Ringwald 472*13b8e9b1SMatthias Ringwald // phase #1 download firmware 473*13b8e9b1SMatthias Ringwald printf("Phase 1: Download firmware\n"); 474*13b8e9b1SMatthias Ringwald 475*13b8e9b1SMatthias Ringwald // phase #2 start main app 476*13b8e9b1SMatthias Ringwald btstack_chipset_atwilc3000_download_firmware(uart_driver, transport_config.baudrate_main, transport_config.flowcontrol, atwilc3000_fw_data, atwilc3000_fw_size, &phase2); 47758a1b1bbSMatthias Ringwald 47858a1b1bbSMatthias Ringwald // go 47958a1b1bbSMatthias Ringwald btstack_run_loop_execute(); 48058a1b1bbSMatthias Ringwald 48158a1b1bbSMatthias Ringwald // compiler happy 4821b2596b5SMatthias Ringwald while(1); 4831b2596b5SMatthias Ringwald } 4841b2596b5SMatthias Ringwald #ifdef __cplusplus 4851b2596b5SMatthias Ringwald } 4861b2596b5SMatthias Ringwald #endif 487