SAM4SD32 (SAM4S-EK2)
Loading...
Searching...
No Matches
ioport_pio.h
Go to the documentation of this file.
1
33/*
34 * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
35 */
36#ifndef IOPORT_SAM_H
37#define IOPORT_SAM_H
38
39#include <sysclk.h>
40
41#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 32 + (pin))
42#define IOPORT_BASE_ADDRESS (uintptr_t)PIOA
43#define IOPORT_PIO_OFFSET ((uintptr_t)PIOB - (uintptr_t)PIOA)
44
45#define IOPORT_PIOA 0
46#define IOPORT_PIOB 1
47#define IOPORT_PIOC 2
48#define IOPORT_PIOD 3
49#define IOPORT_PIOE 4
50#define IOPORT_PIOF 5
51
60
63#define IOPORT_MODE_MUX_MASK (0x7 << 0)
64#define IOPORT_MODE_MUX_BIT0 ( 1 << 0)
65
66#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
67#define IOPORT_MODE_MUX_BIT1 ( 1 << 1)
68#endif
69
70#define IOPORT_MODE_MUX_A ( 0 << 0)
71#define IOPORT_MODE_MUX_B ( 1 << 0)
72
73#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
74#define IOPORT_MODE_MUX_C ( 2 << 0)
75#define IOPORT_MODE_MUX_D ( 3 << 0)
76#endif
77
78#define IOPORT_MODE_PULLUP ( 1 << 3)
79
80#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
81#define IOPORT_MODE_PULLDOWN ( 1 << 4)
82#endif
83
84#define IOPORT_MODE_OPEN_DRAIN ( 1 << 5)
85
86#define IOPORT_MODE_GLITCH_FILTER ( 1 << 6)
87#define IOPORT_MODE_DEBOUNCE ( 1 << 7)
89
91
92typedef uint32_t ioport_mode_t;
93typedef uint32_t ioport_pin_t;
94typedef uint32_t ioport_port_t;
95typedef uint32_t ioport_port_mask_t;
96
98{
99 return pin >> 5;
100}
101
102__always_inline static Pio *arch_ioport_port_to_base(ioport_port_t port)
103{
104#if (SAM4C || SAM4CM || SAM4CP)
105 if (port == IOPORT_PIOC) {
106 return (Pio *)(uintptr_t)PIOC;
107# ifdef ID_PIOD
108 } else if (port == IOPORT_PIOD) {
109 return (Pio *)(uintptr_t)PIOD;
110# endif
111 } else {
112 return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS +
113 (IOPORT_PIO_OFFSET * port));
114 }
115#else
116 return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS +
117 (IOPORT_PIO_OFFSET * port));
118#endif
119}
120
121__always_inline static Pio *arch_ioport_pin_to_base(ioport_pin_t pin)
122{
124}
125
127{
128 return 1U << (pin & 0x1F);
129}
130
131__always_inline static void arch_ioport_init(void)
132{
133#ifdef ID_PIOA
134 sysclk_enable_peripheral_clock(ID_PIOA);
135#endif
136#ifdef ID_PIOB
137 sysclk_enable_peripheral_clock(ID_PIOB);
138#endif
139#ifdef ID_PIOC
140 sysclk_enable_peripheral_clock(ID_PIOC);
141#endif
142#ifdef ID_PIOD
143 sysclk_enable_peripheral_clock(ID_PIOD);
144#endif
145#ifdef ID_PIOE
146 sysclk_enable_peripheral_clock(ID_PIOE);
147#endif
148#ifdef ID_PIOF
149 sysclk_enable_peripheral_clock(ID_PIOF);
150#endif
151}
152
153__always_inline static void arch_ioport_enable_port(ioport_port_t port,
155{
156 arch_ioport_port_to_base(port)->PIO_PER = mask;
157}
158
159__always_inline static void arch_ioport_disable_port(ioport_port_t port,
161{
162 arch_ioport_port_to_base(port)->PIO_PDR = mask;
163}
164
170
176
177__always_inline static void arch_ioport_set_port_mode(ioport_port_t port,
179{
180 Pio *base = arch_ioport_port_to_base(port);
181
182 if (mode & IOPORT_MODE_PULLUP) {
183 base->PIO_PUER = mask;
184 } else {
185 base->PIO_PUDR = mask;
186 }
187
188#if defined(IOPORT_MODE_PULLDOWN)
189 if (mode & IOPORT_MODE_PULLDOWN) {
190 base->PIO_PPDER = mask;
191 } else {
192 base->PIO_PPDDR = mask;
193 }
194#endif
195
196 if (mode & IOPORT_MODE_OPEN_DRAIN) {
197 base->PIO_MDER = mask;
198 } else {
199 base->PIO_MDDR = mask;
200 }
201
203 base->PIO_IFER = mask;
204 } else {
205 base->PIO_IFDR = mask;
206 }
207
208 if (mode & IOPORT_MODE_DEBOUNCE) {
209#if SAM3U || SAM3XA
210 base->PIO_DIFSR = mask;
211#else
212 base->PIO_IFSCER = mask;
213#endif
214 } else {
215#if SAM3U || SAM3XA
216 base->PIO_SCIFSR = mask;
217#else
218 base->PIO_IFSCDR = mask;
219#endif
220 }
221
222#if !defined(IOPORT_MODE_MUX_BIT1)
223 if (mode & IOPORT_MODE_MUX_BIT0) {
224 base->PIO_ABSR |= mask;
225 } else {
226 base->PIO_ABSR &= ~mask;
227 }
228#else
229 if (mode & IOPORT_MODE_MUX_BIT0) {
230 base->PIO_ABCDSR[0] |= mask;
231 } else {
232 base->PIO_ABCDSR[0] &= ~mask;
233 }
234
235 if (mode & IOPORT_MODE_MUX_BIT1) {
236 base->PIO_ABCDSR[1] |= mask;
237 } else {
238 base->PIO_ABCDSR[1] &= ~mask;
239 }
240#endif
241}
242
243__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin,
244 ioport_mode_t mode)
245{
247 arch_ioport_pin_to_mask(pin), mode);
248}
249
250__always_inline static void arch_ioport_set_port_dir(ioport_port_t port,
251 ioport_port_mask_t mask, enum ioport_direction group_direction)
252{
253 Pio *base = arch_ioport_port_to_base(port);
254
255 if (group_direction == IOPORT_DIR_OUTPUT) {
256 base->PIO_OER = mask;
257 } else if (group_direction == IOPORT_DIR_INPUT) {
258 base->PIO_ODR = mask;
259 }
260
261 base->PIO_OWER = mask;
262}
263
264__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin,
265 enum ioport_direction dir)
266{
267 Pio *base = arch_ioport_pin_to_base(pin);
268
269 if (dir == IOPORT_DIR_OUTPUT) {
270 base->PIO_OER = arch_ioport_pin_to_mask(pin);
271 } else if (dir == IOPORT_DIR_INPUT) {
272 base->PIO_ODR = arch_ioport_pin_to_mask(pin);
273 }
274
276}
277
278__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin,
279 bool level)
280{
281 Pio *base = arch_ioport_pin_to_base(pin);
282
283 if (level) {
285 } else {
287 }
288}
289
290__always_inline static void arch_ioport_set_port_level(ioport_port_t port,
291 ioport_port_mask_t mask, enum ioport_value level)
292{
293 Pio *base = arch_ioport_port_to_base(port);
294
295 if (level){
296 base->PIO_SODR = mask;
297 } else {
298 base->PIO_CODR = mask;
299 }
300}
301
302__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin)
303{
305}
306
309{
310 return arch_ioport_port_to_base(port)->PIO_PDSR & mask;
311}
312
313__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin)
314{
315 Pio *port = arch_ioport_pin_to_base(pin);
317
318 if (port->PIO_PDSR & arch_ioport_pin_to_mask(pin)) {
319 port->PIO_CODR = mask;
320 } else {
321 port->PIO_SODR = mask;
322 }
323}
324
325__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port,
327{
328 arch_ioport_port_to_base(port)->PIO_ODSR ^= mask;
329}
330
331__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port,
332 ioport_port_mask_t mask, enum ioport_sense pin_sense)
333{
334 Pio *base = arch_ioport_port_to_base(port);
335 /* AIMMR ELSR FRLHSR
336 * 0 X X IOPORT_SENSE_BOTHEDGES (Default)
337 * 1 0 0 IOPORT_SENSE_FALLING
338 * 1 0 1 IOPORT_SENSE_RISING
339 * 1 1 0 IOPORT_SENSE_LEVEL_LOW
340 * 1 1 1 IOPORT_SENSE_LEVEL_HIGH
341 */
342 switch(pin_sense) {
344 base->PIO_LSR = mask;
345 base->PIO_FELLSR = mask;
346 break;
348 base->PIO_LSR = mask;
349 base->PIO_REHLSR = mask;
350 break;
352 base->PIO_ESR = mask;
353 base->PIO_FELLSR = mask;
354 break;
356 base->PIO_ESR = mask;
357 base->PIO_REHLSR = mask;
358 break;
359 default:
360 base->PIO_AIMDR = mask;
361 return;
362 }
363 base->PIO_AIMER = mask;
364}
365
366__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin,
367 enum ioport_sense pin_sense)
368{
370 arch_ioport_pin_to_mask(pin), pin_sense);
371}
372
373#endif /* IOPORT_SAM_H */
#define IOPORT_MODE_PULLUP
Definition ioport_pio.h:78
#define IOPORT_MODE_GLITCH_FILTER
Definition ioport_pio.h:86
#define IOPORT_MODE_PULLDOWN
Definition ioport_pio.h:81
ioport_sense
IOPORT edge sense modes.
Definition ioport.h:97
#define IOPORT_MODE_OPEN_DRAIN
Definition ioport_pio.h:84
ioport_direction
IOPORT pin directions.
Definition ioport.h:76
#define IOPORT_MODE_MUX_BIT0
Definition ioport_pio.h:64
ioport_value
IOPORT levels.
Definition ioport.h:82
#define IOPORT_MODE_MUX_BIT1
Definition ioport_pio.h:67
#define IOPORT_MODE_DEBOUNCE
Definition ioport_pio.h:87
@ IOPORT_SENSE_LEVEL_HIGH
Definition ioport.h:102
@ IOPORT_SENSE_RISING
Definition ioport.h:100
@ IOPORT_SENSE_LEVEL_LOW
Definition ioport.h:101
@ IOPORT_SENSE_FALLING
Definition ioport.h:99
@ IOPORT_DIR_OUTPUT
Definition ioport.h:78
@ IOPORT_DIR_INPUT
Definition ioport.h:77
static __always_inline void arch_ioport_set_pin_level(ioport_pin_t pin, bool level)
Definition ioport_pio.h:278
static __always_inline void arch_ioport_set_port_sense_mode(ioport_port_t port, ioport_port_mask_t mask, enum ioport_sense pin_sense)
Definition ioport_pio.h:331
static __always_inline ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin)
Definition ioport_pio.h:97
#define IOPORT_PIO_OFFSET
Definition ioport_pio.h:43
uint32_t ioport_mode_t
Definition ioport_pio.h:92
uint32_t ioport_port_mask_t
Definition ioport_pio.h:95
uint32_t ioport_pin_t
Definition ioport_pio.h:93
static __always_inline void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, enum ioport_sense pin_sense)
Definition ioport_pio.h:366
static __always_inline void arch_ioport_init(void)
Definition ioport_pio.h:131
static __always_inline void arch_ioport_toggle_pin_level(ioport_pin_t pin)
Definition ioport_pio.h:313
#define IOPORT_BASE_ADDRESS
Definition ioport_pio.h:42
static __always_inline void arch_ioport_enable_pin(ioport_pin_t pin)
Definition ioport_pio.h:165
static __always_inline void arch_ioport_set_port_level(ioport_port_t port, ioport_port_mask_t mask, enum ioport_value level)
Definition ioport_pio.h:290
static __always_inline void arch_ioport_set_pin_dir(ioport_pin_t pin, enum ioport_direction dir)
Definition ioport_pio.h:264
static __always_inline void arch_ioport_set_port_mode(ioport_port_t port, ioport_port_mask_t mask, ioport_mode_t mode)
Definition ioport_pio.h:177
#define IOPORT_PIOD
Definition ioport_pio.h:48
static __always_inline ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin)
Definition ioport_pio.h:126
static __always_inline ioport_port_mask_t arch_ioport_get_port_level(ioport_port_t port, ioport_port_mask_t mask)
Definition ioport_pio.h:307
static __always_inline void arch_ioport_disable_pin(ioport_pin_t pin)
Definition ioport_pio.h:171
static __always_inline void arch_ioport_set_port_dir(ioport_port_t port, ioport_port_mask_t mask, enum ioport_direction group_direction)
Definition ioport_pio.h:250
#define IOPORT_PIOC
Definition ioport_pio.h:47
static __always_inline void arch_ioport_enable_port(ioport_port_t port, ioport_port_mask_t mask)
Definition ioport_pio.h:153
static __always_inline void arch_ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode)
Definition ioport_pio.h:243
static __always_inline bool arch_ioport_get_pin_level(ioport_pin_t pin)
Definition ioport_pio.h:302
static __always_inline Pio * arch_ioport_port_to_base(ioport_port_t port)
Definition ioport_pio.h:102
static __always_inline void arch_ioport_toggle_port_level(ioport_port_t port, ioport_port_mask_t mask)
Definition ioport_pio.h:325
static __always_inline Pio * arch_ioport_pin_to_base(ioport_pin_t pin)
Definition ioport_pio.h:121
static __always_inline void arch_ioport_disable_port(ioport_port_t port, ioport_port_mask_t mask)
Definition ioport_pio.h:159
uint32_t ioport_port_t
Definition ioport_pio.h:94
#define ID_PIOA
Parallel I/O Controller A (PIOA).
Definition sam4sd32c.h:331
#define ID_PIOB
Parallel I/O Controller B (PIOB).
Definition sam4sd32c.h:332
#define PIOC
(PIOC ) Base Address
Definition sam4sd32c.h:450
#define ID_PIOC
Parallel I/O Controller C (PIOC).
Definition sam4sd32c.h:333
Pio hardware registers.
__O uint32_t PIO_ESR
(Pio Offset: 0x00C0) Edge Select Register
__I uint32_t PIO_PDSR
(Pio Offset: 0x003C) Pin Data Status Register
__IO uint32_t PIO_ABCDSR[2]
(Pio Offset: 0x0070) Peripheral Select Register
__O uint32_t PIO_OWER
(Pio Offset: 0x00A0) Output Write Enable
__O uint32_t PIO_PUDR
(Pio Offset: 0x0060) Pull-up Disable Register
__O uint32_t PIO_IFDR
(Pio Offset: 0x0024) Glitch Input Filter Disable Register
__O uint32_t PIO_REHLSR
(Pio Offset: 0x00D4) Rising Edge/ High Level Select Register
__O uint32_t PIO_MDDR
(Pio Offset: 0x0054) Multi-driver Disable Register
__O uint32_t PIO_LSR
(Pio Offset: 0x00C4) Level Select Register
__O uint32_t PIO_AIMER
(Pio Offset: 0x00B0) Additional Interrupt Modes Enable Register
__O uint32_t PIO_CODR
(Pio Offset: 0x0034) Clear Output Data Register
__IO uint32_t PIO_ODSR
(Pio Offset: 0x0038) Output Data Status Register
__O uint32_t PIO_PDR
(Pio Offset: 0x0004) PIO Disable Register
__O uint32_t PIO_ODR
(Pio Offset: 0x0014) Output Disable Register
__O uint32_t PIO_AIMDR
(Pio Offset: 0x00B4) Additional Interrupt Modes Disables Register
__O uint32_t PIO_FELLSR
(Pio Offset: 0x00D0) Falling Edge/Low Level Select Register
__O uint32_t PIO_PER
(Pio Offset: 0x0000) PIO Enable Register
__O uint32_t PIO_IFSCER
(Pio Offset: 0x0084) Input Filter Slow Clock Enable Register
__O uint32_t PIO_IFSCDR
(Pio Offset: 0x0080) Input Filter Slow Clock Disable Register
__O uint32_t PIO_OER
(Pio Offset: 0x0010) Output Enable Register
__O uint32_t PIO_PPDDR
(Pio Offset: 0x0090) Pad Pull-down Disable Register
__O uint32_t PIO_PUER
(Pio Offset: 0x0064) Pull-up Enable Register
__O uint32_t PIO_IFER
(Pio Offset: 0x0020) Glitch Input Filter Enable Register
__O uint32_t PIO_MDER
(Pio Offset: 0x0050) Multi-driver Enable Register
__O uint32_t PIO_PPDER
(Pio Offset: 0x0094) Pad Pull-down Enable Register
__O uint32_t PIO_SODR
(Pio Offset: 0x0030) Set Output Data Register