9.7 KiB
PIN Device
Open PIN Device
int mr_dev_open(const char *path, int flags);
| Parameter | Description |
|---|---|
| path | Device path |
| flags | Open device flags |
| Return Value | |
>=0 |
Device descriptor |
<0 |
Error code |
path: The PIN device path is usually"pin".flags: Open device flags, supportsMR_O_RDONLY,MR_O_WRONLY,MR_O_RDWR.
Note: When using, different tasks should open the PIN device separately according to actual situations and use
appropriate flags for management and permission control to ensure they won't interfere with each other.
Close PIN Device
int mr_dev_close(int desc);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| Return Value | |
=0 |
Close successfully |
<0 |
Error code |
Note: Closing the device will not restore the previous configuration by default. The user needs to restore it according to the actual situation.
Control PIN Device
int mr_dev_ioctl(int desc, int cmd, void *args);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| cmd | Command code |
| args | Command parameter |
| Return Value | |
=0 |
Set successfully |
<0 |
Error code |
cmd: Command code, supports:MR_IOC_PIN_SET_NUMBER: Set pin numberMR_IOC_PIN_SET_MODE: Set pin modeMR_IOC_PIN_SET_EXTI_CALL: Set external interrupt callback functionMR_IOC_PIN_GET_NUMBER: Get pin numberMR_IOC_PIN_GET_EXTI_CALL: Get external interrupt callback function
Set/Get Pin Number
Pin Number
Different MCUs have different GPIO quantities, functions, naming rules, etc. So MR uses digital numbers to define GPIO pins for unified interfaces on different MCUs.
The default calculation formula is: Number = Port * 16 + Pin, where Port is the GPIO port number and Pin is the
GPIO pin number.
For example, PC13 corresponds to Port C, Pin 13, then Number = (C - A) * 16 + 13 = 32 + 13 = 45.
Note: This rule may not apply to all MCUs. Special requirements need to check the low-level driver settings.
/* Define pin number */
#define PIN_NUMBER 45
/* Set pin number */
mr_dev_ioctl(ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, PIN_NUMBER));
/* Get pin number */
int number;
mr_dev_ioctl(ds, MR_IOC_PIN_GET_NUMBER, &number);
Independent of PIN interface:
/* Define pin number */
#define PIN_NUMBER 45
/* Set pin number */
mr_dev_ioctl(ds, MR_IOC_SPOS, MR_MAKE_LOCAL(int, PIN_NUMBER));
/* Get pin number */
int number;
mr_dev_ioctl(ds, MR_IOC_GPOS, &number);
Set Pin Mode
Pin Mode
MR supports 6 common modes:
MR_PIN_MODE_NONE: No mode, pin returns to default statusMR_PIN_MODE_OUTPUT: Output mode, pin is push-pull output modeMR_PIN_MODE_OUTPUT_OD: Output mode, pin is open-drain output modeMR_PIN_MODE_INPUT: Input mode, pin is floating input modeMR_PIN_MODE_INPUT_DOWN: Input mode, pin is pull-down input modeMR_PIN_MODE_INPUT_UP: Input mode, pin is pull-up input mode
And 5 external interrupt modes:
MR_PIN_MODE_IRQ_RISING: External interrupt mode, triggered on rising edgeMR_PIN_MODE_IRQ_FALLING: External interrupt mode, triggered on falling edgeMR_PIN_MODE_IRQ_EDGE: External interrupt mode, triggered on both edgesMR_PIN_MODE_IRQ_LOW: External interrupt mode, triggered on low levelMR_PIN_MODE_IRQ_HIGH: External interrupt mode, triggered on high level
/* Define pin mode */
#define PIN_MODE MR_PIN_MODE_OUTPUT
/* Set pin mode */
mr_dev_ioctl(ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, PIN_MODE));
Independent of PIN interface:
/* Define pin mode */
#define PIN_MODE 1
/* Set pin mode */
mr_dev_ioctl(ds, MR_IOC_SCFG, MR_MAKE_LOCAL(int, PIN_MODE));
Set/Get External Interrupt Callback Function
#define PIN_NUMBER 45
/* Define external interrupt callback function */
void fn(int desc, void *args)
{
/* Get pin number */
ssize_t number = *(ssize_t *)args;
if (number == PIN_NUMBER)
{
/* Handle external interrupt event */
}
}
/* Set external interrupt callback function */
mr_dev_ioctl(ds, MR_IOC_PIN_SET_EXTI_CALL, fn);
/* Get external interrupt callback function */
void (*callback)(int desc, void *args);
mr_dev_ioctl(ds, MR_IOC_PIN_GET_EXTI_CALL, &callback);
Independent of PIN interface:
#define PIN_NUMBER 45
/* Define external interrupt callback function */
void fn(int desc, void *args)
{
/* Get pin number */
ssize_t number = *(ssize_t *)args;
if (number == PIN_NUMBER)
{
/* Handle external interrupt event */
}
}
/* Set external interrupt callback function */
mr_dev_ioctl(ds, MR_IOC_SRCB, fn);
/* Get external interrupt callback function */
void (*callback)(int desc, void *args);
mr_dev_ioctl(ds, MR_IOC_GRCB, &callback);
Note:
- All callbacks are called as soon as any pin triggers an external interrupt, be sure to check that the pin is correct.
Read PIN Device Pin Level
ssize_t mr_dev_read(int desc, void *buf, size_t count);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| buf | Read data buffer |
| count | Read data size |
| Return Value | |
>=0 |
Read data size |
<0 |
Error code |
/* Read pin level */
uint8_t pin_level;
int ret = mr_dev_read(ds, &pin_level, sizeof(pin_level));
/* Check if read successfully */
if (ret != sizeof(pin_level))
{
return ret;
}
Write PIN Device Pin Level
ssize_t mr_dev_write(int desc, const void *buf, size_t count);
| Parameter | Description |
|---|---|
| desc | Device descriptor |
| buf | Write data buffer |
| count | Write data size |
| Return Value | |
>=0 |
Write data size |
<0 |
Error code |
- Level:
0: Low level;1: High level.
/* Write pin level */
uint8_t pin_level = 1;
int ret = mr_dev_write(ds, &pin_level, sizeof(pin_level));
/* Check if write successfully */
if (ret != sizeof(pin_level))
{
return ret;
}
Usage Example:
#include "include/mr_lib.h"
/* Define LED pin (PC13) and KEY pin (PA0) */
#define LED_PIN_NUMBER 45
#define KEY_PIN_NUMBER 0
/* Define LED and KEY descriptors */
int led_ds = -1;
int key_ds = -1;
void key_call(int desc, void *args)
{
ssize_t number = *((ssize_t *)args);
if (number == KEY_PIN_NUMBER)
{
/* Print the callback function descriptor */
mr_printf("KEY callback\r\n");
}
}
void led_key_init(void)
{
int ret = MR_EOK;
/* Initialize LED */
led_ds = mr_dev_open("pin", MR_O_WRONLY);
if (led_ds < 0)
{
mr_printf("led open failed: %s\r\n", mr_strerror(led_ds));
return;
}
/* Print LED descriptor */
mr_printf("LED desc: %d\r\n", led_ds);
/* Set to LED pin */
mr_dev_ioctl(led_ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, LED_PIN_NUMBER));
/* Set LED pin to push-pull output mode */
ret = mr_dev_ioctl(led_ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_OUTPUT));
if (ret < 0)
{
mr_printf("led set mode failed: %s\r\n", mr_strerror(ret));
return;
}
/* Initialize KEY */
key_ds = mr_dev_open("pin", MR_O_RDONLY);
if (key_ds < 0)
{
mr_printf("key open failed: %s\r\n", mr_strerror(key_ds));
return;
}
/* Print KEY descriptor */
mr_printf("KEY desc: %d\r\n", key_ds);
/* Set to KEY pin */
mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_NUMBER, MR_MAKE_LOCAL(int, KEY_PIN_NUMBER));
/* Set KEY external interrupt callback function */
mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_EXTI_CALL, key_call);
/* Set KEY pin to external interrupt (falling edge) mode (without reconfiguring the callback function, use the previous result, i.e. the callback function set by LED) */
ret = mr_dev_ioctl(key_ds, MR_IOC_PIN_SET_MODE, MR_MAKE_LOCAL(int, MR_PIN_MODE_IRQ_FALLING));
if (ret < 0)
{
mr_printf("key set mode failed: %s\r\n", mr_strerror(ret));
}
}
/* Export to auto initialization (APP level) */
MR_INIT_APP_EXPORT(led_key_init);
int main(void)
{
/* Auto initialization (led_key_init function will be automatically called here) */
mr_auto_init();
while(1)
{
/* Toggle LED pin level */
uint8_t level = 0;
mr_dev_read(led_ds, &level, sizeof(level));
level = !level;
mr_dev_write(led_ds, &level, sizeof(level));
mr_delay_ms(500);
}
}
After pressing the KEY, the serial port prints "KEY callback" and the LED flips every 500ms.