diff options
| author | hathach <[email protected]> | 2018-03-26 22:46:53 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2018-03-26 22:46:53 +0700 |
| commit | 24d4b27980a415a548328dd74b524c6b9456c7b9 (patch) | |
| tree | 31b7fa38c3d357e4992f673c162d3ec129f3a51c /tinyusb | |
| parent | cf8a85fa8bc2ffe7130b7383dee64812bc2ebdce (diff) | |
move nrf5x port files
Diffstat (limited to 'tinyusb')
| -rw-r--r-- | tinyusb/portable/nordic/nrf5x/dcd_nrf52.c | 650 | ||||
| -rw-r--r-- | tinyusb/portable/nordic/nrf5x/dcd_nrf52.h | 50 | ||||
| -rw-r--r-- | tinyusb/portable/nordic/nrf5x/hal_nrf52.c | 100 |
3 files changed, 800 insertions, 0 deletions
diff --git a/tinyusb/portable/nordic/nrf5x/dcd_nrf52.c b/tinyusb/portable/nordic/nrf5x/dcd_nrf52.c new file mode 100644 index 000000000..78e2df87c --- /dev/null +++ b/tinyusb/portable/nordic/nrf5x/dcd_nrf52.c @@ -0,0 +1,650 @@ +/**************************************************************************/ +/*! + @file dcd_nrf52.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, hathach (tinyusb.org) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +// TODO remove +#include "nrf.h" +#include "nrf_power.h" +#include "nrf_usbd.h" +#include "nrf_clock.h" + +#include "nrf_drv_power.h" +#include "nrf_drv_usbd_errata.h" + +#include "tusb_dcd.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ +enum +{ + // Max allowed by USB specs + MAX_PACKET_SIZE = 64, + + // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT + EDPT_END_ALL_MASK = 0x1FFBFC +}; + +/*------------------------------------------------------------------*/ +/* VARIABLE DECLARATION + *------------------------------------------------------------------*/ +typedef struct +{ + uint8_t* buffer; + uint16_t total_len; + uint16_t actual_len; + + uint8_t mps; // max packet size +} nom_xfer_t; + +/*static*/ struct +{ + struct + { + uint8_t* buffer; + uint16_t len; + uint8_t dir; + }control; + + // Non control: 7 endpoints IN & OUT (offset 1) + nom_xfer_t xfer[2][7]; + + volatile bool dma_running; +}_dcd; + +/*------------------------------------------------------------------*/ +/* Controller Start up Sequence + *------------------------------------------------------------------*/ +static bool hfclk_running(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (nrf_sdh_is_enabled()) + { + uint32_t is_running; + (void) sd_clock_hfclk_is_running(&is_running); + return (is_running ? true : false); + } +#endif + + return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +} + +static void hfclk_enable(void) +{ + // already running, nothing to do + if ( hfclk_running() ) return; + +#ifdef SOFTDEVICE_PRESENT + if (nrf_sdh_is_enabled()) + { + (void)sd_clock_hfclk_request(); + return; + } +#endif + + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); +} + +static void hfclk_disable(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (nrf_sdh_is_enabled()) + { + (void)sd_clock_hfclk_release(); + return; + } +#endif // SOFTDEVICE_PRESENT + + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); +} + +static void power_usb_event_handler(nrf_drv_power_usb_evt_t event) +{ + // 51.4 specs USBD start-up sequene + switch ( event ) + { + case NRF_DRV_POWER_USB_EVT_DETECTED: + if ( !NRF_USBD->ENABLE ) + { + /* Prepare for READY event receiving */ + nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + + /* Enable the peripheral */ + nrf_usbd_enable(); + + // Enable HFCLK + hfclk_enable(); + + /* Waiting for peripheral to enable, this should take a few us */ + while ( !(NRF_USBD_EVENTCAUSE_READY_MASK & NRF_USBD->EVENTCAUSE) ) { } + nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + nrf_usbd_event_clear(NRF_USBD_EVENT_USBEVENT); + } + break; + + case NRF_DRV_POWER_USB_EVT_READY: + // Wait for HFCLK + while ( !hfclk_running() ) {} + + if ( nrf_drv_usbd_errata_166() ) + { + *((volatile uint32_t *) (NRF_USBD_BASE + 0x800)) = 0x7E3; + *((volatile uint32_t *) (NRF_USBD_BASE + 0x804)) = 0x40; + + __ISB(); __DSB(); + } + + nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_Half); + + // Enable interrupt. SOF is used as CDC auto flush + NRF_USBD->INTENSET = USBD_INTEN_USBRESET_Msk | USBD_INTEN_USBEVENT_Msk | USBD_INTEN_ACCESSFAULT_Msk | + USBD_INTEN_EP0SETUP_Msk | USBD_INTEN_EP0DATADONE_Msk | USBD_INTEN_ENDEPIN0_Msk | USBD_INTEN_ENDEPOUT0_Msk | + USBD_INTEN_EPDATA_Msk | USBD_INTEN_SOF_Msk; + + // if (enable_sof || nrf_drv_usbd_errata_104()) + // { + // ints_to_enable |= NRF_USBD_INT_SOF_MASK; + // } + + // Enable interrupt, Priorities 0,1,4,5 (nRF52) are reserved for SoftDevice + NVIC_SetPriority(USBD_IRQn, 7); + NVIC_ClearPendingIRQ(USBD_IRQn); + NVIC_EnableIRQ(USBD_IRQn); + + // Enable pull up + nrf_usbd_pullup_enable(); + break; + + case NRF_DRV_POWER_USB_EVT_REMOVED: + if ( NRF_USBD->ENABLE ) + { + // Abort all transfers + + // Disable pull up + nrf_usbd_pullup_disable(); + + // Disable Interrupt + NVIC_DisableIRQ(USBD_IRQn); + + // disable all interrupt + NRF_USBD->INTENCLR = NRF_USBD->INTEN; + + nrf_usbd_disable(); + hfclk_disable(); + } + break; + + default: break; + } +} + +void bus_reset(void) +{ + for(int i=0; i<8; i++) + { + NRF_USBD->TASKS_STARTEPIN[i] = 0; + NRF_USBD->TASKS_STARTEPOUT[i] = 0; + } + + NRF_USBD->TASKS_STARTISOIN = 0; + NRF_USBD->TASKS_STARTISOOUT = 0; + + varclr(&_dcd); +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +bool tusb_dcd_init (uint8_t rhport) +{ + // USB Power detection + const nrf_drv_power_usbevt_config_t config = + { + .handler = power_usb_event_handler + }; + return ( NRF_SUCCESS == nrf_drv_power_usbevt_init(&config) ); +} + +void tusb_dcd_connect (uint8_t rhport) +{ + +} +void tusb_dcd_disconnect (uint8_t rhport) +{ + +} + +void tusb_dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + // Set Address is automatically update by hw controller +} + +void tusb_dcd_set_config (uint8_t rhport, uint8_t config_num) +{ + (void) rhport; + (void) config_num; + // Nothing to do +} + +/*------------------------------------------------------------------*/ +/* Control + *------------------------------------------------------------------*/ +static void edpt_dma_start(uint8_t epnum, uint8_t dir) +{ + // Only one dma could be active + while ( _dcd.dma_running ) { } + + _dcd.dma_running = true; + + if ( dir == TUSB_DIR_OUT ) + { + NRF_USBD->TASKS_STARTEPOUT[epnum] = 1; + } else + { + NRF_USBD->TASKS_STARTEPIN[epnum] = 1; + } + + __ISB(); __DSB(); +} + +static void edpt_dma_end(void) +{ + _dcd.dma_running = false; +} + +static void control_xact_start(void) +{ + // Each transaction is up to 64 bytes + uint8_t const xact_len = min16_of(_dcd.control.len, MAX_PACKET_SIZE); + + if ( _dcd.control.dir == TUSB_DIR_OUT ) + { + // TODO control out + NRF_USBD->EPOUT[0].PTR = (uint32_t) _dcd.control.buffer; + NRF_USBD->EPOUT[0].MAXCNT = xact_len; + + NRF_USBD->TASKS_EP0RCVOUT = 1; + __ISB(); __DSB(); + }else + { + NRF_USBD->EPIN[0].PTR = (uint32_t) _dcd.control.buffer; + NRF_USBD->EPIN[0].MAXCNT = xact_len; + + edpt_dma_start(0, TUSB_DIR_IN); + } + + _dcd.control.buffer += xact_len; + _dcd.control.len -= xact_len; +} + +//static void control_xact_done(void) +//{ +// if ( _dcd_data.control.xfer_len > 0 ) +// { +// if ( _dcd_data.control.dir == TUSB_DIR_OUT ) +// { +// // out control need to wait for END EPOUT event before updating Pointer +// edpt_dma_start(0, TUSB_DIR_OUT); +// }else +// { +// control_xact_start(); +// } +// }else +// { +// tusb_dcd_xfer_complete(0, 0, 0, true); +// } +//} + + +bool tusb_dcd_control_xfer (uint8_t rhport, tusb_dir_t dir, uint8_t * buffer, uint16_t length) +{ + (void) rhport; + + if ( length ) + { + // Data Phase + _dcd.control.len = length; + _dcd.control.buffer = buffer; + _dcd.control.dir = (uint8_t) dir; + + control_xact_start(); + }else + { + // Status Phase + NRF_USBD->TASKS_EP0STATUS = 1; + __ISB(); __DSB(); + } + + return true; +} + +/*------------------------------------------------------------------*/ +/* + *------------------------------------------------------------------*/ +static void normal_xact_start(uint8_t epnum, uint8_t dir) +{ + nom_xfer_t* xfer = &_dcd.xfer[dir][epnum-1]; + + // Each transaction is up to Max Packet Size + uint8_t const xact_len = min16_of(xfer->total_len - xfer->actual_len, xfer->mps); + + if ( dir == TUSB_DIR_OUT ) + { + // HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec + // use the back door interface as sdk for walk around + if ( nrf_drv_usbd_errata_sizeepout_rw() ) + { + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum; + *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0; + (void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + else + { + // Overwrite size will allow hw to accept data + NRF_USBD->SIZE.EPOUT[epnum] = 0; + __ISB(); __DSB(); + } + }else + { + NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; + NRF_USBD->EPIN[epnum].MAXCNT = xact_len; + + xfer->buffer += xact_len; + + edpt_dma_start(epnum, TUSB_DIR_IN); + } +} + +bool tusb_dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = edpt_dir(desc_edpt->bEndpointAddress); + + _dcd.xfer[dir][epnum-1].mps = desc_edpt->wMaxPacketSize.size; + + if ( dir == TUSB_DIR_OUT ) + { + NRF_USBD->INTENSET = BIT_(USBD_INTEN_ENDEPOUT0_Pos + epnum); + NRF_USBD->EPOUTEN |= BIT_(epnum); + }else + { + NRF_USBD->INTENSET = BIT_(USBD_INTEN_ENDEPIN0_Pos + epnum); + NRF_USBD->EPINEN |= BIT_(epnum); + } + __ISB(); __DSB(); + + return true; +} + +bool tusb_dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + + uint8_t const epnum = edpt_number(ep_addr); + uint8_t const dir = edpt_dir(ep_addr); + + _dcd.xfer[dir][epnum-1].buffer = buffer; + _dcd.xfer[dir][epnum-1].total_len = total_bytes; + _dcd.xfer[dir][epnum-1].actual_len = 0; + + normal_xact_start(epnum, dir); + +// if ( dir == TUSB_DIR_OUT ) +// { +// // TODO +// }else +// { +// +// } + + return true; +} + +void tusb_dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + if ( ep_addr == 0) + { + NRF_USBD->TASKS_EP0STALL = 1; + }else + { + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep_addr; + } + + __ISB(); __DSB(); +} + +void tusb_dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + if ( ep_addr ) + { + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr; + } +} + +bool tusb_dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + + // USBD shouldn't check control endpoint state + if ( 0 == ep_addr ) return false; + + uint8_t const epnum = edpt_number(ep_addr); + uint8_t const dir = edpt_dir(ep_addr); + + nom_xfer_t* xfer = &_dcd.xfer[dir][epnum-1]; + + return xfer->actual_len < xfer->total_len; +} + +/*------------------------------------------------------------------*/ +/* + *------------------------------------------------------------------*/ +void USBD_IRQHandler(void) +{ + uint32_t const inten = NRF_USBD->INTEN; + uint32_t int_status = 0; + + volatile uint32_t* regclr = &NRF_USBD->EVENTS_USBRESET; + + for(int i=0; i<32; i++) + { + if ( BIT_TEST_(inten, i) && regclr[i] ) + { + int_status |= BIT_(i); + + // nrf_usbd_event_clear() + regclr[i] = 0; + + __ISB(); __DSB(); + } + } + + /*------------- Interrupt Processing -------------*/ + if ( int_status & USBD_INTEN_USBRESET_Msk ) + { + bus_reset(); + + tusb_dcd_bus_event(0, USBD_BUS_EVENT_RESET); + } + + if ( int_status & USBD_INTEN_SOF_Msk ) + { + tusb_dcd_bus_event(0, USBD_BUS_EVENT_SOF); + } + + if ( int_status & EDPT_END_ALL_MASK ) + { + // DMA complete move data from SRAM -> Endpoint + edpt_dma_end(); + } + + /*------------- Control Transfer -------------*/ + if ( int_status & USBD_INTEN_EP0SETUP_Msk ) + { + uint8_t setup[8] = { + NRF_USBD->BMREQUESTTYPE, NRF_USBD->BREQUEST, NRF_USBD->WVALUEL, NRF_USBD->WVALUEH, + NRF_USBD->WINDEXL, NRF_USBD->WINDEXH, NRF_USBD->WLENGTHL, NRF_USBD->WLENGTHH + }; + + tusb_dcd_setup_received(0, setup); + } + + if ( int_status & USBD_INTEN_EP0DATADONE_Msk ) + { + if ( _dcd.control.dir == TUSB_DIR_OUT ) + { + // OUT data from Host -> Endpoint + // Trigger DMA to move Endpoint -> SRAM + edpt_dma_start(0, TUSB_DIR_OUT); + }else + { + // IN: data transferred from Endpoint -> Host + if ( _dcd.control.len > 0 ) + { + control_xact_start(); + }else + { + // Control IN complete + tusb_dcd_xfer_complete(0, 0, 0, true); + } + } + } + + if ( int_status & USBD_INTEN_ENDEPOUT0_Msk) + { + // OUT data moved from Endpoint -> SRAM + if ( _dcd.control.len > 0 ) + { + control_xact_start(); + }else + { + // Control OUT complete + tusb_dcd_xfer_complete(0, 0, 0, true); + } + } + + /*------------- Bulk/Interrupt Transfer -------------*/ + if ( int_status & USBD_INTEN_EPDATA_Msk) + { + uint32_t data_status = NRF_USBD->EPDATASTATUS; + + nrf_usbd_epdatastatus_clear(data_status); + + // In: data from Endpoint -> Host + for(uint8_t epnum=1; epnum<8; epnum++) + { + if ( BIT_TEST_(data_status, epnum ) ) + { + nom_xfer_t* xfer = &_dcd.xfer[TUSB_DIR_IN][epnum-1]; + + xfer->actual_len += NRF_USBD->EPIN[epnum].MAXCNT; + + if ( xfer->actual_len < xfer->total_len ) + { + // more to xfer + normal_xact_start(epnum, TUSB_DIR_IN); + } else + { + // BULK/INT IN complete + tusb_dcd_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, true); + } + } + } + + // OUT: data from Host -> Endpoint + for(uint8_t epnum=1; epnum<8; epnum++) + { + if ( BIT_TEST_(data_status, 16+epnum ) ) + { + nom_xfer_t* xfer = &_dcd.xfer[TUSB_DIR_OUT][epnum-1]; + + uint8_t const xact_len = NRF_USBD->SIZE.EPOUT[epnum]; + + // Trigger DMA move data from Endpoint -> SRAM + NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer; + NRF_USBD->EPOUT[epnum].MAXCNT = xact_len; + + edpt_dma_start(epnum, TUSB_DIR_OUT); + + xfer->buffer += xact_len; + xfer->actual_len += xact_len; + } + } + } + + // OUT: data from DMA -> SRAM + for(uint8_t epnum=1; epnum<8; epnum++) + { + if ( BIT_TEST_(int_status, USBD_INTEN_ENDEPOUT0_Pos+epnum) ) + { + nom_xfer_t* xfer = &_dcd.xfer[TUSB_DIR_OUT][epnum-1]; + + // Transfer complete if transaction len < Max Packet Size or total len is transferred + if ( (NRF_USBD->EPOUT[epnum].AMOUNT == xfer->mps) && (xfer->actual_len < xfer->total_len) ) + { + // Allow Host -> Endpoint + + // HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec + // use the back door interface as sdk for walk around + if ( nrf_drv_usbd_errata_sizeepout_rw() ) + { + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum; + *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0; + (void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + else + { + // Overwrite size will allow hw to accept data + NRF_USBD->SIZE.EPOUT[epnum] = 0; + __ISB(); __DSB(); + } + }else + { + xfer->total_len = xfer->actual_len; + + // BULK/INT OUT complete + tusb_dcd_xfer_complete(0, epnum, xfer->actual_len, true); + } + } + } + +} diff --git a/tinyusb/portable/nordic/nrf5x/dcd_nrf52.h b/tinyusb/portable/nordic/nrf5x/dcd_nrf52.h new file mode 100644 index 000000000..7d830da6f --- /dev/null +++ b/tinyusb/portable/nordic/nrf5x/dcd_nrf52.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/*! + @file dcd_nrf52.h + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, hathach (tinyusb.org) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ +#ifndef DCD_NRF52_H_ +#define DCD_NRF52_H_ + + + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef __cplusplus + } +#endif + +#endif /* DCD_NRF52_H_ */ diff --git a/tinyusb/portable/nordic/nrf5x/hal_nrf52.c b/tinyusb/portable/nordic/nrf5x/hal_nrf52.c new file mode 100644 index 000000000..5554beb56 --- /dev/null +++ b/tinyusb/portable/nordic/nrf5x/hal_nrf52.c @@ -0,0 +1,100 @@ +/**************************************************************************/ +/*! + @file hal_nrf52.c + @author hathach + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2018, hathach (tinyusb.org) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/**************************************************************************/ + +#include <stdbool.h> +#include "nrf.h" +#include "nrf_gpio.h" +#include "nrf_clock.h" + +#include "tusb_hal.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------*/ +/* VARIABLE DECLARATION + *------------------------------------------------------------------*/ + +/*------------------------------------------------------------------*/ +/* FUNCTION DECLARATION + *------------------------------------------------------------------*/ + +volatile uint32_t system_ticks = 0; + +void SysTick_Handler (void) +{ + system_ticks++; +} + + +bool tusb_hal_init(void) +{ + return true; +} + +void tusb_hal_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USBD_IRQn); +} + +void tusb_hal_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USBD_IRQn); +} + +uint32_t tusb_hal_tick_get(void) +{ + //#define tick2ms(tck) ( ( ((uint64_t)(tck)) * 1000) / configTICK_RATE_HZ ) + //return tick2ms( app_timer_cnt_get() ); + + return system_ticks; +} + +void tusb_hal_dbg_breakpoint(void) +{ + // M0 cannot check if debugger is attached or not +#if defined(__CORTEX_M) && (__CORTEX_M > 0) + // check if debugger is attached + if ( (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == CoreDebug_DHCSR_C_DEBUGEN_Msk) + { + __asm("BKPT #0\n"); + } +#endif +} |
