1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/gpio.h>
9 
10 #if defined(CONFIG_SOC_SERIES_NRF52X)
11 #define CPU_CLOCK		64000000U
12 #else
13 #define CPU_CLOCK		CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
14 #endif
15 
16 #if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
17 #define FAST_BITBANG_HW_SUPPORT 1
18 #else
19 #define FAST_BITBANG_HW_SUPPORT 0
20 #endif
21 
pin_delay_asm(uint32_t delay)22 static ALWAYS_INLINE void pin_delay_asm(uint32_t delay)
23 {
24 #if defined(CONFIG_CPU_CORTEX_M)
25 	__asm volatile ("movs r3, %[p]\n"
26 			".start_%=:\n"
27 			"subs r3, #1\n"
28 			"bne .start_%=\n"
29 			:
30 			: [p] "r" (delay)
31 			: "r3", "cc"
32 			);
33 #else
34 #warning "Pin delay is not defined"
35 #endif
36 }
37 
swdp_ll_pin_input(void * const base,uint8_t pin)38 static ALWAYS_INLINE void swdp_ll_pin_input(void *const base, uint8_t pin)
39 {
40 #if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
41 	NRF_GPIO_Type * reg = base;
42 
43 	reg->PIN_CNF[pin] = 0b0000;
44 #endif
45 }
46 
swdp_ll_pin_output(void * const base,uint8_t pin)47 static ALWAYS_INLINE void swdp_ll_pin_output(void *const base, uint8_t pin)
48 {
49 #if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
50 	NRF_GPIO_Type * reg = base;
51 
52 	reg->PIN_CNF[pin] = 0b0001;
53 #endif
54 }
55 
56 
swdp_ll_pin_set(void * const base,uint8_t pin)57 static ALWAYS_INLINE void swdp_ll_pin_set(void *const base, uint8_t pin)
58 {
59 #if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
60 	NRF_GPIO_Type * reg = base;
61 
62 	reg->OUTSET = BIT(pin);
63 #endif
64 }
65 
swdp_ll_pin_clr(void * const base,uint8_t pin)66 static ALWAYS_INLINE void swdp_ll_pin_clr(void *const base, uint8_t pin)
67 {
68 #if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
69 	NRF_GPIO_Type * reg = base;
70 
71 	reg->OUTCLR = BIT(pin);
72 #endif
73 }
74 
swdp_ll_pin_get(void * const base,uint8_t pin)75 static ALWAYS_INLINE uint32_t swdp_ll_pin_get(void *const base, uint8_t pin)
76 {
77 #if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X)
78 	NRF_GPIO_Type * reg = base;
79 
80 	return ((reg->IN >> pin) & 1);
81 #else
82 	return 0UL;
83 #endif
84 }
85