xref: /btstack/port/samv71-xplained-atwilc3000/main.c (revision 58a1b1bbd780fce065cc682a3cd9375e3ada0688)
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