xref: /btstack/port/archive/pic32-harmony/src/btstack_port.c (revision 98451c7b102094e15e0a72ca2f7098d91aed2017)
1bfc39f3eSMatthias Ringwald //
2bfc39f3eSMatthias Ringwald // BTstack Port for the Microchip PIC32 Harmony Platfrom
3bfc39f3eSMatthias Ringwald //
4bfc39f3eSMatthias Ringwald 
5bfc39f3eSMatthias Ringwald #include "btstack_port.h"
6bfc39f3eSMatthias Ringwald 
7bfc39f3eSMatthias Ringwald #include "system_config.h"
8bfc39f3eSMatthias Ringwald 
9bfc39f3eSMatthias Ringwald #include "btstack_chipset_csr.h"
10bfc39f3eSMatthias Ringwald #include "btstack_debug.h"
11bfc39f3eSMatthias Ringwald #include "btstack_event.h"
12bfc39f3eSMatthias Ringwald #include "btstack_run_loop.h"
13bfc39f3eSMatthias Ringwald #include "btstack_run_loop_embedded.h"
14bfc39f3eSMatthias Ringwald #include "btstack_uart_slip_wrapper.h"
15bfc39f3eSMatthias Ringwald #include "hci.h"
16bfc39f3eSMatthias Ringwald #include "hci_dump.h"
17bfc39f3eSMatthias Ringwald #include "hci_transport.h"
18bfc39f3eSMatthias Ringwald 
19bfc39f3eSMatthias Ringwald #include <stdint.h>
20bfc39f3eSMatthias Ringwald #include <stdbool.h>
21bfc39f3eSMatthias Ringwald #include <stddef.h>
22bfc39f3eSMatthias Ringwald #include <stdlib.h>
23bfc39f3eSMatthias Ringwald 
24bfc39f3eSMatthias Ringwald #include "driver/tmr/drv_tmr.h"
25bfc39f3eSMatthias Ringwald #include "peripheral/usart/plib_usart.h"
26bfc39f3eSMatthias Ringwald #include "system/ports/sys_ports.h"
27bfc39f3eSMatthias Ringwald 
28bfc39f3eSMatthias Ringwald //
29bfc39f3eSMatthias Ringwald int btstack_main(int argc, const char * argv[]);
30bfc39f3eSMatthias Ringwald 
31bfc39f3eSMatthias Ringwald 
32bfc39f3eSMatthias Ringwald /// HAL Tick ///
33bfc39f3eSMatthias Ringwald #include "hal_tick.h"
34bfc39f3eSMatthias Ringwald 
35bfc39f3eSMatthias Ringwald #define APP_TMR_ALARM_PERIOD                48825
36bfc39f3eSMatthias Ringwald #define APP_LED_PORT                        PORT_CHANNEL_A
37bfc39f3eSMatthias Ringwald #define APP_LED_PIN                         PORTS_BIT_POS_4
38bfc39f3eSMatthias Ringwald 
39bfc39f3eSMatthias Ringwald static void dummy_handler(void);
40bfc39f3eSMatthias Ringwald static void (*tick_handler)(void);
41bfc39f3eSMatthias Ringwald static int hal_uart_needed_during_sleep = 1;
42bfc39f3eSMatthias Ringwald 
dummy_handler(void)43bfc39f3eSMatthias Ringwald static void dummy_handler(void){};
44bfc39f3eSMatthias Ringwald static DRV_HANDLE handleTmr;
45bfc39f3eSMatthias Ringwald static bool ledIsOn;
46bfc39f3eSMatthias Ringwald 
sys_tick_handler(uintptr_t context,uint32_t alarmCount)47bfc39f3eSMatthias Ringwald static void sys_tick_handler (  uintptr_t context, uint32_t alarmCount ){
48bfc39f3eSMatthias Ringwald     if (!ledIsOn) {
49bfc39f3eSMatthias Ringwald         ledIsOn = true;
50bfc39f3eSMatthias Ringwald         SYS_PORTS_PinSet(PORTS_ID_0, APP_LED_PORT, APP_LED_PIN);
51bfc39f3eSMatthias Ringwald     }
52bfc39f3eSMatthias Ringwald     else
53bfc39f3eSMatthias Ringwald     {
54bfc39f3eSMatthias Ringwald         ledIsOn = false;
55bfc39f3eSMatthias Ringwald         SYS_PORTS_PinClear(PORTS_ID_0, APP_LED_PORT, APP_LED_PIN);
56bfc39f3eSMatthias Ringwald     }
57bfc39f3eSMatthias Ringwald 
58bfc39f3eSMatthias Ringwald     (*tick_handler)();
59bfc39f3eSMatthias Ringwald }
60bfc39f3eSMatthias Ringwald 
hal_tick_init(void)61bfc39f3eSMatthias Ringwald void hal_tick_init(void){
62bfc39f3eSMatthias Ringwald     ledIsOn = false;
63bfc39f3eSMatthias Ringwald     handleTmr = DRV_TMR_Open(APP_TMR_DRV_INDEX, DRV_IO_INTENT_EXCLUSIVE);
64bfc39f3eSMatthias Ringwald     if( DRV_HANDLE_INVALID == handleTmr ){
65bfc39f3eSMatthias Ringwald         log_error("Timer init failed");
66bfc39f3eSMatthias Ringwald         return;
67bfc39f3eSMatthias Ringwald     }
68bfc39f3eSMatthias Ringwald     DRV_TMR_Alarm16BitRegister(handleTmr, APP_TMR_ALARM_PERIOD, true, (uintptr_t)NULL, sys_tick_handler);
69bfc39f3eSMatthias Ringwald     DRV_TMR_Start(handleTmr);
70bfc39f3eSMatthias Ringwald     SYS_PORTS_PinDirectionSelect(PORTS_ID_0, SYS_PORTS_DIRECTION_OUTPUT, APP_LED_PORT, APP_LED_PIN);
71bfc39f3eSMatthias Ringwald }
72bfc39f3eSMatthias Ringwald 
hal_tick_get_tick_period_in_ms(void)73bfc39f3eSMatthias Ringwald int  hal_tick_get_tick_period_in_ms(void){
74bfc39f3eSMatthias Ringwald     return 250;
75bfc39f3eSMatthias Ringwald }
76bfc39f3eSMatthias Ringwald 
hal_tick_set_handler(void (* handler)(void))77bfc39f3eSMatthias Ringwald void hal_tick_set_handler(void (*handler)(void)){
78bfc39f3eSMatthias Ringwald     if (handler == NULL){
79bfc39f3eSMatthias Ringwald         tick_handler = &dummy_handler;
80bfc39f3eSMatthias Ringwald         return;
81bfc39f3eSMatthias Ringwald     }
82bfc39f3eSMatthias Ringwald     tick_handler = handler;
83bfc39f3eSMatthias Ringwald }
84bfc39f3eSMatthias Ringwald 
msleep(uint32_t delay)85bfc39f3eSMatthias Ringwald static void msleep(uint32_t delay) {
86bfc39f3eSMatthias Ringwald     uint32_t wake = btstack_run_loop_embedded_get_ticks() + delay / hal_tick_get_tick_period_in_ms();
87bfc39f3eSMatthias Ringwald     while (wake > btstack_run_loop_embedded_get_ticks()){
88bfc39f3eSMatthias Ringwald         SYS_Tasks();
89bfc39f3eSMatthias Ringwald     };
90bfc39f3eSMatthias Ringwald }
91bfc39f3eSMatthias Ringwald 
92bfc39f3eSMatthias Ringwald /// HAL CPU ///
93bfc39f3eSMatthias Ringwald #include "hal_cpu.h"
94bfc39f3eSMatthias Ringwald 
hal_cpu_disable_irqs(void)95bfc39f3eSMatthias Ringwald void hal_cpu_disable_irqs(void){
96bfc39f3eSMatthias Ringwald     // TODO implement
97bfc39f3eSMatthias Ringwald }
98bfc39f3eSMatthias Ringwald 
hal_cpu_enable_irqs(void)99bfc39f3eSMatthias Ringwald void hal_cpu_enable_irqs(void){
100bfc39f3eSMatthias Ringwald     // TODO implement
101bfc39f3eSMatthias Ringwald }
102bfc39f3eSMatthias Ringwald 
hal_cpu_enable_irqs_and_sleep(void)103bfc39f3eSMatthias Ringwald void hal_cpu_enable_irqs_and_sleep(void){
104bfc39f3eSMatthias Ringwald     // TODO implement
105bfc39f3eSMatthias Ringwald }
106bfc39f3eSMatthias Ringwald 
107bfc39f3eSMatthias Ringwald 
108bfc39f3eSMatthias Ringwald /// HAL UART DMA ///
109bfc39f3eSMatthias Ringwald #include "hal_uart_dma.h"
110bfc39f3eSMatthias Ringwald 
111bfc39f3eSMatthias Ringwald // handlers
112bfc39f3eSMatthias Ringwald static void (*rx_done_handler)(void) = dummy_handler;
113bfc39f3eSMatthias Ringwald static void (*tx_done_handler)(void) = dummy_handler;
114bfc39f3eSMatthias Ringwald static void (*cts_irq_handler)(void) = dummy_handler;
115bfc39f3eSMatthias Ringwald 
116bfc39f3eSMatthias Ringwald // rx state
117bfc39f3eSMatthias Ringwald static uint16_t  bytes_to_read = 0;
118bfc39f3eSMatthias Ringwald static uint8_t * rx_buffer_ptr = 0;
119bfc39f3eSMatthias Ringwald 
120bfc39f3eSMatthias Ringwald // tx state
121bfc39f3eSMatthias Ringwald static uint16_t  bytes_to_write = 0;
122bfc39f3eSMatthias Ringwald static uint8_t * tx_buffer_ptr = 0;
123bfc39f3eSMatthias Ringwald 
124bfc39f3eSMatthias Ringwald 
125bfc39f3eSMatthias Ringwald // reset Bluetooth using n_shutdown
bluetooth_power_cycle(void)126bfc39f3eSMatthias Ringwald static void bluetooth_power_cycle(void){
127bfc39f3eSMatthias Ringwald     printf("Bluetooth power cycle: Reset ON\n");
128bfc39f3eSMatthias Ringwald     SYS_PORTS_PinClear(PORTS_ID_0, BT_RESET_PORT, BT_RESET_BIT);
129bfc39f3eSMatthias Ringwald     msleep(250);
130bfc39f3eSMatthias Ringwald     printf("Bluetooth power cycle: Reset OFF\n");
131bfc39f3eSMatthias Ringwald     SYS_PORTS_PinSet(PORTS_ID_0, BT_RESET_PORT, BT_RESET_BIT);
132bfc39f3eSMatthias Ringwald }
133bfc39f3eSMatthias Ringwald 
hal_uart_dma_init(void)134bfc39f3eSMatthias Ringwald void hal_uart_dma_init(void){
135bfc39f3eSMatthias Ringwald 
136bfc39f3eSMatthias Ringwald     bytes_to_write = 0;
137bfc39f3eSMatthias Ringwald     bytes_to_read = 0;
138bfc39f3eSMatthias Ringwald 
139bfc39f3eSMatthias Ringwald     /* PPS Input Remapping */
140bfc39f3eSMatthias Ringwald     PLIB_PORTS_RemapInput(PORTS_ID_0, INPUT_FUNC_U2RX, INPUT_PIN_RPF4 );
141bfc39f3eSMatthias Ringwald     PLIB_PORTS_RemapInput(PORTS_ID_0, INPUT_FUNC_U2CTS, INPUT_PIN_RPB2 );
142bfc39f3eSMatthias Ringwald 
143bfc39f3eSMatthias Ringwald     /* PPS Output Remapping */
144bfc39f3eSMatthias Ringwald     PLIB_PORTS_RemapOutput(PORTS_ID_0, OUTPUT_FUNC_U2RTS, OUTPUT_PIN_RPG9 );
145bfc39f3eSMatthias Ringwald     PLIB_PORTS_RemapOutput(PORTS_ID_0, OUTPUT_FUNC_U2TX, OUTPUT_PIN_RPF5 );
146bfc39f3eSMatthias Ringwald 
147bfc39f3eSMatthias Ringwald     /* Initialize USART */
148bfc39f3eSMatthias Ringwald     PLIB_USART_BaudRateSet(BT_USART_ID, SYS_CLK_PeripheralFrequencyGet(CLK_BUS_PERIPHERAL_1), BT_USART_BAUD);
149bfc39f3eSMatthias Ringwald     PLIB_USART_HandshakeModeSelect(BT_USART_ID, USART_HANDSHAKE_MODE_FLOW_CONTROL);
150bfc39f3eSMatthias Ringwald     PLIB_USART_OperationModeSelect(BT_USART_ID, USART_ENABLE_TX_RX_CTS_RTS_USED);
151bfc39f3eSMatthias Ringwald     PLIB_USART_LineControlModeSelect(BT_USART_ID, USART_8N1);
152bfc39f3eSMatthias Ringwald 
153bfc39f3eSMatthias Ringwald     // BCSP on CSR requires even parity
154bfc39f3eSMatthias Ringwald     // PLIB_USART_LineControlModeSelect(BT_USART_ID, USART_8E1);
155bfc39f3eSMatthias Ringwald 
156bfc39f3eSMatthias Ringwald     PLIB_USART_TransmitterEnable(BT_USART_ID);
157bfc39f3eSMatthias Ringwald     // PLIB_USART_TransmitterInterruptModeSelect(bluetooth_uart_id, USART_TRANSMIT_FIFO_IDLE);
158bfc39f3eSMatthias Ringwald 
159bfc39f3eSMatthias Ringwald     // allow overrun mode: not needed for H4. CSR with BCSP/H5 does not enable RTS/CTS
160bfc39f3eSMatthias Ringwald     PLIB_USART_RunInOverflowEnable(BT_USART_ID);
161bfc39f3eSMatthias Ringwald 
162bfc39f3eSMatthias Ringwald     PLIB_USART_ReceiverEnable(BT_USART_ID);
163bfc39f3eSMatthias Ringwald     // PLIB_USART_ReceiverInterruptModeSelect(bluetooth_uart_id, USART_RECEIVE_FIFO_ONE_CHAR);
164bfc39f3eSMatthias Ringwald 
165bfc39f3eSMatthias Ringwald     PLIB_USART_Enable(BT_USART_ID);
166bfc39f3eSMatthias Ringwald 
167bfc39f3eSMatthias Ringwald     // enable _RESET
168bfc39f3eSMatthias Ringwald     SYS_PORTS_PinDirectionSelect(PORTS_ID_0, SYS_PORTS_DIRECTION_OUTPUT, BT_RESET_PORT, BT_RESET_BIT);
169bfc39f3eSMatthias Ringwald 
170bfc39f3eSMatthias Ringwald     bluetooth_power_cycle();
171bfc39f3eSMatthias Ringwald 
172bfc39f3eSMatthias Ringwald     // After reset, CTS is high and we need to wait until CTS is low again
173bfc39f3eSMatthias Ringwald 
174bfc39f3eSMatthias Ringwald     // HACK: CTS doesn't seem to work right now
175bfc39f3eSMatthias Ringwald     msleep(250);
176bfc39f3eSMatthias Ringwald }
177bfc39f3eSMatthias Ringwald 
hal_uart_dma_set_block_received(void (* the_block_handler)(void))178bfc39f3eSMatthias Ringwald void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
179bfc39f3eSMatthias Ringwald     rx_done_handler = the_block_handler;
180bfc39f3eSMatthias Ringwald }
181bfc39f3eSMatthias Ringwald 
hal_uart_dma_set_block_sent(void (* the_block_handler)(void))182bfc39f3eSMatthias Ringwald void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
183bfc39f3eSMatthias Ringwald     tx_done_handler = the_block_handler;
184bfc39f3eSMatthias Ringwald }
185bfc39f3eSMatthias Ringwald 
hal_uart_dma_set_csr_irq_handler(void (* the_irq_handler)(void))186bfc39f3eSMatthias Ringwald void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
187bfc39f3eSMatthias Ringwald     // not needed for regular H4 module (but needed for TI's eHCILL)
188bfc39f3eSMatthias Ringwald }
hal_uart_dma_set_sleep(uint8_t sleep)189bfc39f3eSMatthias Ringwald void hal_uart_dma_set_sleep(uint8_t sleep){
190bfc39f3eSMatthias Ringwald     // not needed for regualr h4 module (but needed for eHCILL or h5)
191bfc39f3eSMatthias Ringwald     UNUSED(sleep);
192bfc39f3eSMatthias Ringwald }
193bfc39f3eSMatthias Ringwald 
hal_uart_dma_set_baud(uint32_t baud)194bfc39f3eSMatthias Ringwald int  hal_uart_dma_set_baud(uint32_t baud){
195bfc39f3eSMatthias Ringwald //    PLIB_USART_Disable(BT_USART_ID);
196bfc39f3eSMatthias Ringwald //    PLIB_USART_BaudRateSet(BT_USART_ID, SYS_CLK_PeripheralFrequencyGet(CLK_BUS_PERIPHERAL_1), baud);
197bfc39f3eSMatthias Ringwald //    PLIB_USART_Enable(BT_USART_ID);
198bfc39f3eSMatthias Ringwald     return 0;
199bfc39f3eSMatthias Ringwald }
200bfc39f3eSMatthias Ringwald 
hal_uart_dma_send_block(const uint8_t * data,uint16_t size)201bfc39f3eSMatthias Ringwald void hal_uart_dma_send_block(const uint8_t *data, uint16_t size){
202bfc39f3eSMatthias Ringwald     tx_buffer_ptr = (uint8_t *) data;
203bfc39f3eSMatthias Ringwald     bytes_to_write = size;}
204bfc39f3eSMatthias Ringwald 
205bfc39f3eSMatthias Ringwald 
hal_uart_dma_receive_block(uint8_t * data,uint16_t size)206bfc39f3eSMatthias Ringwald void hal_uart_dma_receive_block(uint8_t *data, uint16_t size){
207bfc39f3eSMatthias Ringwald     // printf("hal_uart_dma_receive_block req size %u\n", size);
208bfc39f3eSMatthias Ringwald     rx_buffer_ptr = data;
209bfc39f3eSMatthias Ringwald     bytes_to_read = size;
210bfc39f3eSMatthias Ringwald }
211bfc39f3eSMatthias Ringwald 
212bfc39f3eSMatthias Ringwald ///
213bfc39f3eSMatthias Ringwald static hci_transport_config_uart_t config = {
214bfc39f3eSMatthias Ringwald     HCI_TRANSPORT_CONFIG_UART,
215bfc39f3eSMatthias Ringwald     115200,
216bfc39f3eSMatthias Ringwald     0,  // main baudrate
217bfc39f3eSMatthias Ringwald     1,  // flow control
218bfc39f3eSMatthias Ringwald     NULL,
219bfc39f3eSMatthias Ringwald };
220bfc39f3eSMatthias Ringwald 
221bfc39f3eSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration;
222bfc39f3eSMatthias Ringwald 
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)223bfc39f3eSMatthias Ringwald static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
224bfc39f3eSMatthias Ringwald     if (packet_type != HCI_EVENT_PACKET) return;
225bfc39f3eSMatthias Ringwald     if (hci_event_packet_get_type(packet) != BTSTACK_EVENT_STATE) return;
226bfc39f3eSMatthias Ringwald     if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return;
227bfc39f3eSMatthias Ringwald     printf("BTstack up and running.\n");
228bfc39f3eSMatthias Ringwald }
229bfc39f3eSMatthias Ringwald 
BTSTACK_Initialize(void)230bfc39f3eSMatthias Ringwald void BTSTACK_Initialize ( void )
231bfc39f3eSMatthias Ringwald {
232bfc39f3eSMatthias Ringwald     printf("\n\nBTstack_Initialize()\n");
233bfc39f3eSMatthias Ringwald 
234bfc39f3eSMatthias Ringwald     btstack_memory_init();
235bfc39f3eSMatthias Ringwald     btstack_run_loop_init(btstack_run_loop_embedded_get_instance());
236bfc39f3eSMatthias Ringwald 
237*98451c7bSMatthias Ringwald     // hci_dump_open(NULL, HCI_DUMP_STDOUT);
238bfc39f3eSMatthias Ringwald 
239bfc39f3eSMatthias Ringwald     // setup uart driver
240bfc39f3eSMatthias Ringwald     const btstack_uart_block_t * uart_block_driver = btstack_uart_block_embedded_instance();
241bfc39f3eSMatthias Ringwald     const btstack_uart_t * uart_slip_driver = btstack_uart_slip_wrapper_instance(uart_block_driver);
242bfc39f3eSMatthias Ringwald 
243bfc39f3eSMatthias Ringwald     const hci_transport_t * transport = hci_transport_h5_instance(uart_slip_driver);
244bfc39f3eSMatthias Ringwald     hci_init(transport, &config);
245bfc39f3eSMatthias Ringwald     hci_set_chipset(btstack_chipset_csr_instance());
246bfc39f3eSMatthias Ringwald 
247bfc39f3eSMatthias Ringwald     // inform about BTstack state
248bfc39f3eSMatthias Ringwald     hci_event_callback_registration.callback = &packet_handler;
249bfc39f3eSMatthias Ringwald     hci_add_event_handler(&hci_event_callback_registration);
250bfc39f3eSMatthias Ringwald 
251bfc39f3eSMatthias Ringwald     btstack_main(0, NULL);
252bfc39f3eSMatthias Ringwald }
253bfc39f3eSMatthias Ringwald 
254bfc39f3eSMatthias Ringwald 
BTSTACK_Tasks(void)255bfc39f3eSMatthias Ringwald void BTSTACK_Tasks(void){
256bfc39f3eSMatthias Ringwald 
257bfc39f3eSMatthias Ringwald     while (bytes_to_read && PLIB_USART_ReceiverDataIsAvailable(BT_USART_ID)) {
258bfc39f3eSMatthias Ringwald         *rx_buffer_ptr++ = PLIB_USART_ReceiverByteReceive(BT_USART_ID);
259bfc39f3eSMatthias Ringwald         bytes_to_read--;
260bfc39f3eSMatthias Ringwald         if (bytes_to_read == 0){
261bfc39f3eSMatthias Ringwald             (*rx_done_handler)();
262bfc39f3eSMatthias Ringwald         }
263bfc39f3eSMatthias Ringwald     }
264bfc39f3eSMatthias Ringwald 
265bfc39f3eSMatthias Ringwald     if(PLIB_USART_ReceiverOverrunHasOccurred(BT_USART_ID))
266bfc39f3eSMatthias Ringwald     {
267bfc39f3eSMatthias Ringwald         // printf("RX Overrun!\n");
268bfc39f3eSMatthias Ringwald         PLIB_USART_ReceiverOverrunErrorClear(BT_USART_ID);
269bfc39f3eSMatthias Ringwald     }
270bfc39f3eSMatthias Ringwald 
271bfc39f3eSMatthias Ringwald     while (bytes_to_write && !PLIB_USART_TransmitterBufferIsFull(BT_USART_ID)){
272bfc39f3eSMatthias Ringwald         PLIB_USART_TransmitterByteSend(BT_USART_ID, *tx_buffer_ptr++);
273bfc39f3eSMatthias Ringwald         bytes_to_write--;
274bfc39f3eSMatthias Ringwald         if (bytes_to_write == 0){
275bfc39f3eSMatthias Ringwald             (*tx_done_handler)();
276bfc39f3eSMatthias Ringwald         }
277bfc39f3eSMatthias Ringwald     }
278bfc39f3eSMatthias Ringwald 
279bfc39f3eSMatthias Ringwald     // BTstack Run Loop
280bfc39f3eSMatthias Ringwald     btstack_run_loop_embedded_execute_once();
281bfc39f3eSMatthias Ringwald }
282bfc39f3eSMatthias Ringwald 
283