added checks to pin configuration

This commit is contained in:
Lauchmelder 2022-06-10 22:02:28 +02:00
parent 15a4f817f2
commit 060ffddcf1
5 changed files with 82 additions and 13 deletions

View file

@ -1,5 +1,5 @@
obj-m = lcd.o
lcd-y = src/lcd.o src/io.o
lcd-y = src/lcd.o src/io.o src/checks.o
KVERSION = $(shell uname -r)

37
src/checks.c Normal file
View file

@ -0,0 +1,37 @@
#include "checks.h"
#include <linux/module.h>
#include "lcd.h"
#define LCD_MIN_GPIO 2
#define LCD_MAX_GPIO 27
static int sub_pin = LCD_MIN_GPIO;
int lcd_is_valid_gpio(int pin)
{
return (LCD_MIN_GPIO <= pin && pin <= LCD_MAX_GPIO);
}
int lcd_assign_gpio(int pin)
{
if(lcd_is_valid_gpio(pin))
return pin;
printk(KERN_WARNING "%s: GPIO pin %d is invalid. Using %d instead\n", THIS_MODULE->name, pin, sub_pin);
return sub_pin++;
}
int lcd_check_duplicates(const int* used_pins)
{
int i, j;
for(i = 0; i < 7; i++)
for(j = i + 1; j < 8; j++)
if(used_pins[i] == used_pins[j])
return -EFAULT;
return 0;
}

11
src/checks.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef _LCD_CHECKS_H
#define _LCD_CHECKS_H
struct lcd_gpio_config;
int lcd_is_valid_gpio(int pin);
int lcd_assign_gpio(int pin);
int lcd_check_duplicates(const int* config);
#endif

View file

@ -5,6 +5,7 @@
#include <linux/gpio.h>
#include "lcd.h"
#include "checks.h"
MODULE_LICENSE("GPL");
@ -85,7 +86,10 @@ static int __init lcd_init_module(void)
result = lcd_init_gpio();
if(result < 0)
{
printk(KERN_ERR "%s: Failed to configure GPIO pins\n", THIS_MODULE->name);
return result;
}
printk(KERN_INFO "%s: Module loaded!\n", THIS_MODULE->name);
return result;
@ -120,26 +124,41 @@ static int __init lcd_init_cdev(void)
static int __init lcd_init_gpio(void)
{
lcd_validate_gpio();
int result, i;
// gpio_direction_output(lcddev.gpio, 0);
return 0;
result = lcd_validate_gpio();
if(result < 0)
return result;
for(i = 0; i < 8; i++)
gpio_direction_output(lcddev.used_pins[i], 0);
return result;
}
static int __init lcd_validate_gpio(void)
{
int result = 0;
struct lcd_gpio_config* config = &lcddev.config;
lcddev.used_pins = (int*)config;
config->power = pin_power;
config->rs = pin_rs;
config->rw = pin_rw;
config->enable = pin_enable;
config->power = lcd_assign_gpio(pin_power);
config->rs = lcd_assign_gpio(pin_rs);
config->rw = lcd_assign_gpio(pin_rw);
config->enable = lcd_assign_gpio(pin_enable);
memcpy(config->data, pin_data, 4 * sizeof(int));
config->data[0] = lcd_assign_gpio(pin_data[0]);
config->data[1] = lcd_assign_gpio(pin_data[1]);
config->data[2] = lcd_assign_gpio(pin_data[2]);
config->data[3] = lcd_assign_gpio(pin_data[3]);
// TODO: Check if pin configuration is valid
// - no duplicate pins?
// - all pin numbers in range?
result = lcd_check_duplicates(lcddev.used_pins);
if(result < 0)
{
printk(KERN_ERR "%s: Invalid pin configuration (duplicate pin usage)\n", THIS_MODULE->name);
return result;
}
return 0;
}

View file

@ -3,6 +3,7 @@
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/semaphore.h>
#define LCD_MAJOR 0
#define LCD_MINOR 0
@ -18,7 +19,7 @@ struct lcd_gpio_config
int power;
int rs, rw, enable;
int data[4];
};
} __attribute__((packed));
struct lcd_dev
{
@ -26,6 +27,7 @@ struct lcd_dev
struct cdev dev;
struct semaphore sem;
struct lcd_gpio_config config;
int* used_pins;
};
#endif