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
uart_init(uint32_t ui32Module)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
uart_disable(uint32_t ui32Module)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
am_devices_em9304_spi_init(uint32_t ui32Module,const am_hal_iom_config_t * psIomConfig)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
configure_em9304_pins(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
em9304_init(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
hal_cpu_disable_irqs(void)210905e80caSMatthias Ringwald void hal_cpu_disable_irqs(void){
211905e80caSMatthias Ringwald am_hal_interrupt_master_disable();
212905e80caSMatthias Ringwald }
213905e80caSMatthias Ringwald
hal_cpu_enable_irqs(void)214905e80caSMatthias Ringwald void hal_cpu_enable_irqs(void){
215905e80caSMatthias Ringwald am_hal_interrupt_master_enable();
216905e80caSMatthias Ringwald }
217905e80caSMatthias Ringwald
hal_cpu_enable_irqs_and_sleep(void)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"
hal_time_ms(void)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);
_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 }
_read(int file,char * ptr,int len)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
_close(int file)270905e80caSMatthias Ringwald int _close(int file){
271905e80caSMatthias Ringwald (void)file;
272905e80caSMatthias Ringwald return -1;
273905e80caSMatthias Ringwald }
274905e80caSMatthias Ringwald
_isatty(int file)275905e80caSMatthias Ringwald int _isatty(int file){
276905e80caSMatthias Ringwald (void)file;
277905e80caSMatthias Ringwald return -1;
278905e80caSMatthias Ringwald }
279905e80caSMatthias Ringwald
_lseek(int file)280905e80caSMatthias Ringwald int _lseek(int file){
281905e80caSMatthias Ringwald (void)file;
282905e80caSMatthias Ringwald return -1;
283905e80caSMatthias Ringwald }
284905e80caSMatthias Ringwald
_fstat(int file)285905e80caSMatthias Ringwald int _fstat(int file){
286905e80caSMatthias Ringwald (void)file;
287905e80caSMatthias Ringwald return -1;
288905e80caSMatthias Ringwald }
289905e80caSMatthias Ringwald
_sbrk(intptr_t increment)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
am_iomaster0_isr(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
am_iomaster5_isr(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
am_gpio_isr(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
hal_em9304_spi_enable_ready_interrupt(void)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
hal_em9304_spi_disable_ready_interrupt(void)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
hal_em9304_spi_set_ready_callback(void (* done)(void))373905e80caSMatthias Ringwald void hal_em9304_spi_set_ready_callback(void (*done)(void)){
374905e80caSMatthias Ringwald hal_em9304_spi_ready_callback = done;
375905e80caSMatthias Ringwald }
376905e80caSMatthias Ringwald
hal_em9304_spi_get_ready(void)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
hal_em9304_spi_init(void)381905e80caSMatthias Ringwald void hal_em9304_spi_init(void){
382905e80caSMatthias Ringwald hal_em9304_spi_disable_ready_interrupt();
383905e80caSMatthias Ringwald }
384905e80caSMatthias Ringwald
hal_em9304_spi_deinit(void)385905e80caSMatthias Ringwald void hal_em9304_spi_deinit(void){
386905e80caSMatthias Ringwald hal_em9304_spi_disable_ready_interrupt();
387905e80caSMatthias Ringwald }
388905e80caSMatthias Ringwald
hal_em9304_spi_set_transfer_done_callback(void (* done)(void))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
hal_em9304_spi_set_chip_select(int enable)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
hal_em9304_spi_transceive(const uint8_t * tx_data,uint8_t * rx_data,uint16_t len)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
hal_em9304_spi_transmit(const uint8_t * tx_data,uint16_t len)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
hal_em9304_spi_receive(uint8_t * rx_data,uint16_t len)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
hal_em9304_spi_get_fullduplex_support(void)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"
446287aaa02SMatthias Ringwald #include "hci_dump_embedded_stdout.h"
447*c8dfe071SMatthias Ringwald #include "hci_transport.h"
448*c8dfe071SMatthias Ringwald #include "hci_transport_em9304_spi.h"
449905e80caSMatthias Ringwald
450b5c1b6b6SMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration;
451b5c1b6b6SMatthias Ringwald int btstack_main(int argc, char ** argv);
452b5c1b6b6SMatthias Ringwald
453b5c1b6b6SMatthias Ringwald // main.c
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)454b5c1b6b6SMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
455b5c1b6b6SMatthias Ringwald UNUSED(size);
456b5c1b6b6SMatthias Ringwald UNUSED(channel);
457b5c1b6b6SMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return;
458b5c1b6b6SMatthias Ringwald switch(hci_event_packet_get_type(packet)){
459b5c1b6b6SMatthias Ringwald case BTSTACK_EVENT_STATE:
460b5c1b6b6SMatthias Ringwald if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
461b5c1b6b6SMatthias Ringwald printf("BTstack up and running.\n");
462b5c1b6b6SMatthias Ringwald break;
463b5c1b6b6SMatthias Ringwald default:
464b5c1b6b6SMatthias Ringwald break;
465b5c1b6b6SMatthias Ringwald }
466b5c1b6b6SMatthias Ringwald }
467b5c1b6b6SMatthias Ringwald
main(void)468905e80caSMatthias Ringwald int main(void)
469905e80caSMatthias Ringwald {
470905e80caSMatthias Ringwald //
471905e80caSMatthias Ringwald // Set the clock frequency.
472905e80caSMatthias Ringwald //
473905e80caSMatthias Ringwald am_hal_clkgen_sysclk_select(AM_HAL_CLKGEN_SYSCLK_MAX);
474905e80caSMatthias Ringwald
475905e80caSMatthias Ringwald //
476905e80caSMatthias Ringwald // Set the default cache configuration
477905e80caSMatthias Ringwald //
478905e80caSMatthias Ringwald am_hal_cachectrl_enable(&am_hal_cachectrl_defaults);
479905e80caSMatthias Ringwald
480905e80caSMatthias Ringwald //
481905e80caSMatthias Ringwald // Configure the board for low power operation.
482905e80caSMatthias Ringwald //
483905e80caSMatthias Ringwald am_bsp_low_power_init();
484905e80caSMatthias Ringwald
485905e80caSMatthias Ringwald //
486905e80caSMatthias Ringwald // Initialize the printf interface for UART output.
487905e80caSMatthias Ringwald //
488905e80caSMatthias Ringwald am_util_stdio_printf_init((am_util_stdio_print_char_t)am_bsp_uart_string_print);
489905e80caSMatthias Ringwald
490905e80caSMatthias Ringwald //
491905e80caSMatthias Ringwald // Configure and enable the UART.
492905e80caSMatthias Ringwald //
493905e80caSMatthias Ringwald uart_init(AM_BSP_UART_PRINT_INST);
494905e80caSMatthias Ringwald
495905e80caSMatthias Ringwald //
496905e80caSMatthias Ringwald // Reboot and configure em9304.
497905e80caSMatthias Ringwald //
498905e80caSMatthias Ringwald em9304_init();
499905e80caSMatthias Ringwald
500905e80caSMatthias Ringwald am_hal_interrupt_enable(AM_HAL_INTERRUPT_GPIO);
501905e80caSMatthias Ringwald
502905e80caSMatthias Ringwald //
503905e80caSMatthias Ringwald // Enable IOM SPI interrupts.
504905e80caSMatthias Ringwald //
505905e80caSMatthias Ringwald am_hal_iom_int_clear(AM_BSP_EM9304_IOM, AM_HAL_IOM_INT_CMDCMP | AM_HAL_IOM_INT_THR);
506905e80caSMatthias Ringwald am_hal_iom_int_enable(AM_BSP_EM9304_IOM, AM_HAL_IOM_INT_CMDCMP | AM_HAL_IOM_INT_THR);
507905e80caSMatthias Ringwald
508905e80caSMatthias Ringwald #if (0 == AM_BSP_EM9304_IOM)
509905e80caSMatthias Ringwald am_hal_interrupt_enable(AM_HAL_INTERRUPT_IOMASTER0);
510905e80caSMatthias Ringwald #elif (5 == AM_BSP_EM9304_IOM)
511905e80caSMatthias Ringwald am_hal_interrupt_enable(AM_HAL_INTERRUPT_IOMASTER5);
512905e80caSMatthias Ringwald #endif
513905e80caSMatthias Ringwald
514c5ae0d23SMatthias Ringwald // Start System Timer (only Apollo 2)
515c5ae0d23SMatthias Ringwald am_hal_stimer_config(AM_HAL_STIMER_LFRC_1KHZ);
516c5ae0d23SMatthias Ringwald am_hal_stimer_counter_clear();
517c5ae0d23SMatthias Ringwald
518905e80caSMatthias Ringwald // start with BTstack init - especially configure HCI Transport
519905e80caSMatthias Ringwald btstack_memory_init();
520905e80caSMatthias Ringwald btstack_run_loop_init(btstack_run_loop_embedded_get_instance());
521905e80caSMatthias Ringwald
522905e80caSMatthias Ringwald // init HCI
523905e80caSMatthias Ringwald hci_init(hci_transport_em9304_spi_instance(btstack_em9304_spi_embedded_instance()), NULL);
524287aaa02SMatthias Ringwald // hci_dump_init(hci_dump_embedded_stdout_get_instance());
525b5c1b6b6SMatthias Ringwald
526b5c1b6b6SMatthias Ringwald // inform about BTstack state
527b5c1b6b6SMatthias Ringwald hci_event_callback_registration.callback = &packet_handler;
528b5c1b6b6SMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration);
529905e80caSMatthias Ringwald
530905e80caSMatthias Ringwald // hand over control to btstack_main()..
531905e80caSMatthias Ringwald
532905e80caSMatthias Ringwald // turn on!
533905e80caSMatthias Ringwald // hci_power_control(HCI_POWER_ON);
534905e80caSMatthias Ringwald btstack_main(0, NULL);
535905e80caSMatthias Ringwald
536905e80caSMatthias Ringwald btstack_run_loop_execute();
537905e80caSMatthias Ringwald }
538