added checks to pin configuration
This commit is contained in:
parent
15a4f817f2
commit
060ffddcf1
2
Makefile
2
Makefile
|
@ -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
37
src/checks.c
Normal 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
11
src/checks.h
Normal 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
|
41
src/lcd.c
41
src/lcd.c
|
@ -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;
|
||||
|
||||
result = lcd_validate_gpio();
|
||||
|
||||
if(result < 0)
|
||||
return result;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
gpio_direction_output(lcddev.used_pins[i], 0);
|
||||
|
||||
// gpio_direction_output(lcddev.gpio, 0);
|
||||
return 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;
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue