1. Circuit Diagram
2. Instructions for use
Code language: javascript
This driver implements two operating modes:
Normal operation mode: ./LedTest
Mask operation mode: ./LedTest led_mask
led_mask can only be: 000, 001, 010, 011....111
Three LEDs can be set at the same time, the LED corresponding to position 1 is lit, and the LED corresponding to position 0 is off
3. Driver code
Code language: javascript
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* Description of LED masks */
typedef enum{
LED_MASK_000,
LED_MASK_001,
LED_MASK_010,
LED_MASK_011,
LED_MASK_100,
LED_MASK_101,
LED_MASK_110,
LED_MASK_111,
LED_MASK_INIT,
}s3c2440_led_mask;
/* Describe the mode of operating LED */
typedef enum{
S3C2440_LED_MODE_MASK=0x11,
S3C2440_LED_MODE_GENERAL=0x22,
S3C2440_LED_MODE_INIT=0xff,
}s3c2440_led_mode;
/* Describe the operation of LED */
typedef enum{
S3C2440_LED_OP_ON=0x66,
S3C2440_LED_OP_OFF=0x88,
S3C2440_LED_OP_INIT=0xff,
}s3c2440_led_op;
/* Describe the position of the operating LED */
typedef enum{
S3C2440_LED_POS_GPF4,
S3C2440_LED_POS_GPF5,
S3C2440_LED_POS_GPF6,
S3C2440_LED_POS_INIT,
}s3c2440_led_pos;
/* Description of LED Mask Magic Number */
typedef enum{
S3C2440_BIT_MASK8=8,
S3C2440_BIT_MASK16=16,
}s3c2440_led_bit_mask;
#define FIRST_DRV_MAJOR 111
static struct class *first_drv_class;
static struct class_device *first_drv_class_dev;
volatile unsigned long *GPFCON = NULL;
volatile unsigned long *GPFDAT = NULL;
static int first_drv_open(struct inode *inode, struct file *file)
{
/* Configure GPF4,5,6 as output*/
*GPFCON &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
*GPFCON |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
return 0;
}
static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
beckon with;
s3c2440_led_mode mode = S3C2440_LED_MODE_INIT;
s3c2440_led_op op = S3C2440_LED_OP_INIT;
s3c2440_led_mask mask = LED_MASK_INIT;
s3c2440_led_pos led_pos = S3C2440_LED_POS_INIT;
copy_from_user(&val, buf, count); // copy_to_user
mode = val&0xff;
if(mode & S3C2440_LED_MODE_GENERAL)
{
led_pos = (val&0xff0000)>>S3C2440_BIT_MASK16;
op = (val&0xff00)>>S3C2440_BIT_MASK8;
}
else if(mode&S3C2440_LED_MODE_MASK)
{
mask = (val&0xff00)>>S3C2440_BIT_MASK8;
}
else
{
printk("[%s][%d]:s3c2440_led_mode is invalid!n", __FUNCTION__, __LINE__);
return -1;
}
if(mode==S3C2440_LED_MODE_MASK)
{
switch(mask)
{
case LED_MASK_000: *GPFDAT |= (1<<4) | (1<<5) | (1<<6); break;
case LED_MASK_001: *GPFDAT &= ~(1<<4); *GPFDAT |= (1<<5) | (1<<6); break;
case LED_MASK_010: *GPFDAT &= ~(1<<5); *GPFDAT |= (1<<4) | (1<<6); break;
case LED_MASK_011: *GPFDAT &= ~((1<<4) | (1<<5));*GPFDAT |= (1<<6); break;
case LED_MASK_100: *GPFDAT &= ~(1<<6);*GPFDAT |= (1<<4) | (1<<5); break;
case LED_MASK_101: *GPFDAT &= ~((1<<4) | (1<<6));*GPFDAT |= (1<<5); break;
case LED_MASK_110: *GPFDAT &= ~((1<<5) | (1<<6));*GPFDAT |= (1<<4); break;
case LED_MASK_111: *GPFDAT &= ~((1<<4) | (1<<5) | (1<<6)); break;
default:
printk("[%s][%d]:s3c2440_led_mask is invalid!n", __FUNCTION__, __LINE__);
return -1;
}
}
else
{
if(op==S3C2440_LED_OP_ON)
{
switch(led_pos)
{
case S3C2440_LED_POS_GPF4: *GPFDAT &= ~(1<<4); break;
case S3C2440_LED_POS_GPF5: *GPFDAT &= ~(1<<5); break;
case S3C2440_LED_POS_GPF6: *GPFDAT &= ~(1<<6); break;
default:
printk("[%s][%d]:s3c2440_led_pos is invalid!n", __FUNCTION__, __LINE__);
return -1;
}
}
else if(op==S3C2440_LED_OP_OFF)
{
switch(led_pos)
{
case S3C2440_LED_POS_GPF4: *GPFDAT |= (1<<4); break;
case S3C2440_LED_POS_GPF5: *GPFDAT |= (1<<5); break;
case S3C2440_LED_POS_GPF6: *GPFDAT |= (1<<6); break;
default:
printk("[%s][%d]:s3c2440_led_pos is invalid!n", __FUNCTION__, __LINE__);
return -1;
}
}
else
{
printk("[%s][%d]:s3c2440_led_op is invalid!n", __FUNCTION__, __LINE__);
return -1;
}
}
return 0;
}
static struct file_operations first_drv_fops = {
.owner = THIS_MODULE,
.open = first_drv_open,
.write = first_drv_write,
};
static int __init first_drv_init(void)
{
/* Major device number, name (any), file_operations structure. If the major device number is 0, the system will automatically assign a device number*/
register_chrdev(FIRST_DRV_MAJOR, "first_drv", &first_drv_fops); /* Register driver */
/* Create a class named first_drv under the system /sys/class/*/
first_drv_class = class_create(THIS_MODULE, "first_drv");
if(IS_ERR(first_drv_class))
return PTR_ERR(first_drv_class);
/* Create a device named xxx under /sys/class/first_drv/ according to the class, device number and name*/
first_drv_class_dev = class_device_create(first_drv_class, NULL,
MKDEV(FIRST_DRV_MAJOR, 0), NULL, "xxx");
if(unlikely(IS_ERR(first_drv_class_dev)))
return PTR_ERR(first_drv_class_dev);
/* Map registers */
GPFCON = (volatile unsigned long *)ioremap(0x56000050, 16);
GPFDAT = GPFCON + 1;
return 0;
}
static void __exit first_drv_exit(void)
{
unregister_chrdev(FIRST_DRV_MAJOR, "first_drv"); /* Uninstall the driver*/
class_device_unregister(first_drv_class_dev);
class_destroy(first_drv_class);
iounmap(GPFCON);
}
module_init(first_drv_init);
module_exit(first_drv_exit);
MODULE_LICENSE("GPL");
4. Test code
Code language: javascript
#include
#include
#include
#include
/* compile: arm-linux-gcc -o FirstDrvTest FirstDrvTest.c */
#define DEV_DEVICE "/dev/xxx"
#define TRUE 1
#define FALSE 0
#define BUF_SIZE_32 32
#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
typedef struct{
char input[BUF_SIZE_32];
unsigned char key;
}s3c2440_turn_key;
typedef enum{
LED_MASK_000,
LED_MASK_001,
LED_MASK_010,
LED_MASK_011,
LED_MASK_100,
LED_MASK_101,
LED_MASK_110,
LED_MASK_111,
LED_MASK_INIT,
}s3c2440_led_mask;
typedef enum{
S3C2440_LED_MODE_MASK=0x11,
S3C2440_LED_MODE_GENERAL=0x22,
S3C2440_LED_MODE_INIT=0xff,
}s3c2440_led_mode;
typedef enum{
S3C2440_LED_OP_ON=0x66,
S3C2440_LED_OP_OFF=0x88,
S3C2440_LED_OP_INIT=0xff,
}s3c2440_led_op;
typedef enum{
S3C2440_LED_POS_GPF4,
S3C2440_LED_POS_GPF5,
S3C2440_LED_POS_GPF6,
S3C2440_LED_POS_INIT,
}s3c2440_led_pos;
typedef enum{
S3C2440_BIT_MASK8=8,
S3C2440_BIT_MASK16=16,
}s3c2440_led_bit_mask;
typedef unsigned int BOOL;
static BOOL check_led_turn_is_legal(s3c2440_turn_key *map,
s3c2440_turn_key *map_array, int map_array_len);
int main(int argc, char *argv[])
{
int fd, val=0;
s3c2440_led_mode mode=S3C2440_LED_MODE_INIT;
s3c2440_led_mask mask=LED_MASK_INIT;
s3c2440_led_pos led_pos=S3C2440_LED_POS_INIT;
s3c2440_led_op op=S3C2440_LED_OP_INIT;
s3c2440_turn_key input_map, led_map, op_map;
s3c2440_turn_key s3c2440_key_map[]={
{
"000", 0},
{
"001", 1},
{
"010", 2},
{
"011", 3},
{
"100", 4},
{
"101", 5},
{
"110", 6},
{
"111", 7},
};
s3c2440_turn_key s3c2440_led_map[]={
{
"led1", S3C2440_LED_POS_GPF4},
{
"led2", S3C2440_LED_POS_GPF5},
{
"led3", S3C2440_LED_POS_GPF6},
};
s3c2440_turn_key s3c2440_op_map[]={
{
"on", S3C2440_LED_OP_ON},
{
"off", S3C2440_LED_OP_OFF},
};
if(argc==3 || argc==2)
;
else
goto usage_error;
switch(argc)
{
case 2: mode=S3C2440_LED_MODE_MASK; break;
case 3: mode=S3C2440_LED_MODE_GENERAL; break;
}
fd = open(DEV_DEVICE, O_RDWR);
if(fd<0)
goto open_error;
switch(mode)
Previous article:S3C2440 SPI
Next article:s3c2440 interrupt system
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- 【GD32L233C-START Review】RTC Electronic Clock
- Pengfeng Technology RVBoards-Nezha (RISC-V SBC) Allwinner Development Board Introduction 2
- Which video platform do you usually like to visit for learning or entertainment?
- Motech High Speed Power Supply Programmable Digital Power Supply PPS1201GSM Service Manual
- BP3286H Buck-Boost Closed-Loop SCR Dimming LED Driver IC
- [National Technology N32G457 Review] ADC Data Collection
- Why does TI's official website classify C2000 as MCUs?
- [TI Live] The latest innovative DLP automotive application solutions, dynamic ground lights, augmented reality head-up display "pat" you
- Winding inductance of electrolytic capacitor
- A beginner's tutorial on TCP server development in Linux using C language