1 /*
2  * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef _MEC_ECIA_API_H
7 #define _MEC_ECIA_API_H
8 
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include "mec_defs.h"
14 
15 /* Interfaces to any C modules */
16 #ifdef __cplusplus
17 extern "C"
18 {
19 #endif
20 
21 /* Encoded information of a MEC5 peripheral interrupt source.
22  * g = GIRQ number in data sheet: 8 <= g <= 26
23  * gb = bit position in 32-bit GIRQ source register.
24  * na = NVIC external input the aggregated GIRQ output is connected to.
25  * nd = NVIC external input this individual source is connected to. If
26  *      the source does not have a direct NVIC connection use 0xff.
27  * Examples:
28  * GPIO 0101 is bit 1 of Aggregated GIRQ9 connected to NVIC external
29  * input 1. GIRQ9 has no direct NVIC connections.
30  * MEC5_ECIA_INFO(9, 1, 1, 255)
31  *
32  * Basic timer 5 is bit 5 of GIRQ23 connected to NVIC external input 14
33  * and has direct NVIC input 141
34  * MEC5_ECIA_INFO(23, 5, 14, 141)
35  */
36 #define MEC5_ECIA_INFO(g, gb, na, nd) \
37         ((((uint32_t)(g) - 8u) & 0x1fu) | (((uint32_t)(gb) & 0x1fu) << 8) \
38          | (((uint32_t)(na) & 0xffu) << 16) | (((uint32_t)(nd) & 0xffu) << 24))
39 
40 /* Extract the zero-based GIRQ number */
41 #define MEC5_ECIA_INFO_GIRQZ(info) ((uint32_t)(info) & 0x1fu)
42 /* Get GIRQ number */
43 #define MEC_ECIA_INFO_GIRQ(info) (MEC5_ECIA_INFO_GIRQZ(info) + MEC5_ECIA_FIRST_GIRQ_NOS)
44 /* extract GIRQ bit position */
45 #define MEC5_ECIA_INFO_GIRQ_POS(info) (((uint32_t)(info) >> 8) & 0x1fu)
46 /* extract the Aggregated GIRQ NVIC external input number */
47 #define MEC5_ECIA_INFO_NVIC_AGGR(info) (((uint32_t)(info) >> 16) & 0xffu)
48 /* extract the Direct GIRQ NVIC external input number */
49 #define MEC5_ECIA_INFO_NVIC_DIRECT(info) (((uint32_t)(info) >> 24) & 0xffu)
50 
51 /*
52  * Globally disables maskable interrupts in CPU.
53  * Configure MEC5 ECIA.
54  * Disables and clears all external NVIC enables.
55  * Sets all external NVIC priorities to dflt_priority.
56  * Leaves interrupts globally masked off.
57  */
58 #define MEC_ECIA_INIT_FLAG_ALL_DIRECT_GIRQ 1
59 #define MEC_ECIA_INIT_FLAG_ALL_DIRECT_NVIC 2
60 #define MEC_ECIA_INIT_FLAG_ALL_AGGR_GIRQ 4
61 
62 void mec_hal_ecia_init(uint32_t direct_bitmap, uint8_t dflt_priority, uint32_t flags);
63 
64 /*
65  * The following routines do not globally mask interrupts and
66  * restore interrupts in the CPU.
67  * It is the applications responsiblity to use these routines safely.
68  * If a device's GIRQ was configured for Aggregated mode then changes
69  * to priority, etc. will affect all peripheral sources connected to
70  * the aggregated GIRQ.
71  */
72 void mec_hal_girq_ctrl(uint32_t devi, int enable);
73 
74 uint32_t mec_hal_girq_src(uint32_t devi);
75 uint32_t mec_hal_girq_result(uint32_t devi);
76 
77 void mec_hal_girq_clr_src(uint32_t devi);
78 
79 int mec_hal_girq_bm_en(uint32_t girq_num, uint32_t bitmap, uint8_t enable);
80 
81 int mec_hal_girq_bm_clr_src(uint32_t girq, uint32_t clr_src_bitmap);
82 
83 uint32_t mec_hal_girq_source_get(uint32_t girq_num);
84 uint32_t mec_hal_girq_result_get(uint32_t girq);
85 
86 uint32_t mec_hal_girq_result_test(uint32_t girq, uint32_t bitpos);
87 
88 int mec_hal_ecia_girq_aggr_enable(uint32_t girq_num, uint8_t enable);
89 
90 /* Check if a peripheral interrupt source is direct capable.
91  * This is not a simple question.
92  * This routine only works if Method 1 initialization
93  * is implement in mec_ecia_init() and the application
94  * developer calls mec_ecia_init() or duplicates its
95  * functionality.
96  */
97 int mec_hal_ecia_is_direct(uint32_t devi);
98 
99 /* NVIC external interrupt API
100  * !!!! WARNING: Touching NVIC registers requires CPU in privileged mode !!!!
101  */
102 void mec_hal_ecia_nvic_enable(uint32_t devi);
103 void mec_hal_ecia_nvic_disable(uint32_t devi);
104 /* Clear NVIC interrupt pending for a specific device source */
105 void mec_hal_ecia_nvic_clr_pend(uint32_t devi);
106 /* Get NVIC interrupt pending status for a specific device source. */
107 uint32_t mec_hal_ecia_nvic_get_pending(uint32_t devi);
108 /* Return peripheral source NVIC priority 0=highest,...,7=lowest */
109 uint8_t mec_hal_ecia_nvic_get_pri(uint32_t devi);
110 /* Set peripheral's NVIC priority 0=highest,...,7=lowest */
111 void mec_hal_ecia_nvic_set_pri(uint32_t devi, uint8_t priority);
112 
113 #ifdef __cplusplus
114 }
115 #endif
116 
117 #endif /* #ifndef _MEC_ECIA_H */
118