forked from RIOT-OS/RIOT
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request RIOT-OS#20679 from maribu/cpu/msp430/periph_gpio_ll
cpu/msp430: Implement periph_gpio_ll & periph_gpio_ll_irq
- Loading branch information
Showing
25 changed files
with
826 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,6 @@ | |
*/ | ||
|
||
#include "cpu.h" | ||
#include "kernel_init.h" | ||
#include "irq.h" | ||
#include "sched.h" | ||
#include "thread.h" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
/* | ||
* Copyright (C) 2024 Marian Buschsieweke | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup cpu_msp430 | ||
* @ingroup drivers_periph_gpio_ll | ||
* @{ | ||
* | ||
* @file | ||
* @brief CPU specific part of the Peripheral GPIO Low-Level API | ||
* | ||
* @author Marian Buschsieweke <[email protected]> | ||
*/ | ||
|
||
#ifndef GPIO_LL_ARCH_H | ||
#define GPIO_LL_ARCH_H | ||
|
||
#include "cpu.h" | ||
#include "periph_cpu.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef DOXYGEN /* hide implementation specific details from Doxygen */ | ||
|
||
/* the memory layout of all GPIO peripherals is compatible, but the location | ||
* in the address space is pretty much random */ | ||
|
||
#define GPIO_PORT_1 ((gpio_port_t)&PORT_1.base) | ||
#define GPIO_PORT_2 ((gpio_port_t)&PORT_2.base) | ||
#define GPIO_PORT_3 ((gpio_port_t)&PORT_3.base) | ||
#define GPIO_PORT_4 ((gpio_port_t)&PORT_4.base) | ||
#define GPIO_PORT_5 ((gpio_port_t)&PORT_5.base) | ||
#define GPIO_PORT_6 ((gpio_port_t)&PORT_6.base) | ||
/* Port 7 and 8 have different memory layout and are only available on F2xx/G2xx | ||
* MCUs */ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
# define GPIO_PORT_7 ((gpio_port_t)&PORT_7) | ||
# define GPIO_PORT_8 ((gpio_port_t)&PORT_8) | ||
#endif | ||
|
||
/* IMPORTANT IMPLEMENTATION INFO | ||
* ============================= | ||
* | ||
* - MSP430 F2xx/G2xx do have PORT 7 and PORT 8, but those have an incompatible | ||
* memory layout compared to the other ports. Hence, they need extra handling. | ||
* However, constant folding should get ride of the branch and overhead if the | ||
* GPIO port is a compile time constant | ||
* - MSP430 has bit manipulation instructions that work on memory. E.g. | ||
* `BIC.B %[mask], @%[ptr]` will implement `*ptr &= ~(mask)` in a single | ||
* instruction. Same for setting or XORing bits. Hence, the code below | ||
* may often look like it is missing `irq_disable()` ... `irq_restore()`, but | ||
* in fact will be atomic due to the MSP430 instruction set. | ||
*/ | ||
|
||
gpio_port_t gpio_port(uword_t num); | ||
|
||
static inline uword_t gpio_ll_read(gpio_port_t port) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
const msp430_port_p7_p8_t *p = (void *)port; | ||
return p->IN; | ||
} | ||
#endif | ||
const msp430_port_t *p = (void *)port; | ||
return p->IN; | ||
} | ||
|
||
static inline uword_t gpio_ll_read_output(gpio_port_t port) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
const msp430_port_p7_p8_t *p = (void *)port; | ||
return p->OD; | ||
} | ||
#endif | ||
const msp430_port_t *p = (void *)port; | ||
return p->OD; | ||
} | ||
|
||
static inline void gpio_ll_set(gpio_port_t port, uword_t mask) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
msp430_port_p7_p8_t *p = (void *)port; | ||
p->OD |= mask; | ||
return; | ||
} | ||
#endif | ||
msp430_port_t *p = (void *)port; | ||
p->OD |= mask; | ||
} | ||
|
||
static inline void gpio_ll_clear(gpio_port_t port, uword_t mask) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
msp430_port_p7_p8_t *p = (void *)port; | ||
p->OD &= ~(mask); | ||
return; | ||
} | ||
#endif | ||
msp430_port_t *p = (void *)port; | ||
p->OD &= ~(mask); | ||
} | ||
|
||
static inline void gpio_ll_toggle(gpio_port_t port, uword_t mask) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
msp430_port_p7_p8_t *p = (void *)port; | ||
p->OD ^= mask; | ||
return; | ||
} | ||
#endif | ||
msp430_port_t *p = (void *)port; | ||
p->OD ^= mask; | ||
} | ||
|
||
static inline void gpio_ll_write(gpio_port_t port, uword_t value) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
msp430_port_p7_p8_t *p = (void *)port; | ||
p->OD = value; | ||
return; | ||
} | ||
#endif | ||
msp430_port_t *p = (void *)port; | ||
p->OD = value; | ||
} | ||
|
||
static inline gpio_port_t gpio_get_port(gpio_t pin) | ||
{ | ||
return gpio_port(gpio_get_pin_num(pin)); | ||
} | ||
|
||
static inline uint8_t gpio_get_pin_num(gpio_t pin) | ||
{ | ||
return pin >> 8; | ||
} | ||
|
||
static inline void gpio_ll_switch_dir_output(gpio_port_t port, uword_t outputs) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
msp430_port_p7_p8_t *p = (void *)port; | ||
p->DIR |= outputs; | ||
return; | ||
} | ||
#endif | ||
msp430_port_t *p = (void *)port; | ||
p->DIR |= outputs; | ||
} | ||
|
||
static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t inputs) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
if (port >= (uintptr_t)(&PORT_7)) { | ||
msp430_port_p7_p8_t *p = (void *)port; | ||
p->DIR &= ~(inputs); | ||
return; | ||
} | ||
#endif | ||
msp430_port_t *p = (void *)port; | ||
p->DIR &= ~(inputs); | ||
} | ||
|
||
static inline gpio_port_t gpio_port_pack_addr(void *addr) | ||
{ | ||
return (gpio_port_t)addr; | ||
} | ||
|
||
static inline void * gpio_port_unpack_addr(gpio_port_t port) | ||
{ | ||
if (port < RAMSTART) { | ||
return NULL; | ||
} | ||
|
||
return (void *)port; | ||
} | ||
|
||
static inline bool is_gpio_port_num_valid(uint_fast8_t num) | ||
{ | ||
#if defined(CPU_FAM_MSP430_F2XX_G2XX) | ||
return (num > 0) && (num <= 8); | ||
#else | ||
return (num > 0) && (num <= 6); | ||
#endif | ||
} | ||
|
||
uword_t gpio_port_num(gpio_port_t port); | ||
|
||
#endif /* DOXYGEN */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* GPIO_LL_ARCH_H */ | ||
/** @} */ |
Oops, something went wrong.