MIDAS
Loading...
Searching...
No Matches
rpi_led.c
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: rpi_led.c
4 Created by: Stefan Ritt
5
6 Contents: Rapberry Pi LED sense hat Device Driver
7
8\********************************************************************/
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdarg.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <unistd.h>
16#include <fcntl.h>
17#include <sys/mman.h>
18#include <stdint.h>
19#include <string.h>
20#include <linux/fb.h>
21#include <sys/ioctl.h>
22#include "midas.h"
23
24/*---- globals -----------------------------------------------------*/
25
26/* following structure contains private variables to the device
27 driver. It is necessary to store it here in case the device
28 driver is used for more than one device in one frontend. If it
29 would be stored in a global variable, one device could over-
30 write the other device's variables. */
31
32typedef struct {
33 int fbfd;
34 uint16_t *map;
36
37#define FILESIZE (64 * sizeof(uint16_t))
38
39/*---- device driver routines --------------------------------------*/
40
41/* the init function creates a ODB record which contains the
42 settings and initialized it variables as well as the bus driver */
43
44INT rpi_led_init(HNDLE hkey, void **pinfo)
45{
47 struct fb_fix_screeninfo fix_info;
48
49 /* allocate info structure */
50 info = calloc(1, sizeof(RPI_LED_INFO));
51 *pinfo = info;
52
53 /* open the led frame buffer device */
54 info->fbfd = open("/dev/fb1", O_RDWR);
55 if (info->fbfd == -1) {
56 perror("Error (call to 'open')");
57 exit(EXIT_FAILURE);
58 }
59
60 /* read fixed screen info for the open device */
61 if (ioctl(info->fbfd, FBIOGET_FSCREENINFO, &fix_info) == -1) {
62 perror("Error (call to 'ioctl')");
63 close(info->fbfd);
64 exit(EXIT_FAILURE);
65 }
66
67 /* now check the correct device has been found */
68 if (strcmp(fix_info.id, "RPi-Sense FB") != 0) {
69 printf("Error: RPi-Sense FB not found\n");
70 close(info->fbfd);
71 exit(EXIT_FAILURE);
72 }
73
74 /* map the led frame buffer device into memory */
75 info->map = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, info->fbfd, 0);
76 if (info->map == MAP_FAILED) {
77 close(info->fbfd);
78 perror("Error mmapping the file");
79 exit(EXIT_FAILURE);
80 }
81
82 /* clear the led matrix */
83 memset(info->map, 0, FILESIZE);
84
85 return FE_SUCCESS;
86}
87
88/*----------------------------------------------------------------------------*/
89
91{
92 /* un-map and close */
93 if (munmap(info->map, FILESIZE) == -1) {
94 perror("Error un-mmapping the file");
95 }
96 close(info->fbfd);
97
98 /* free local variables */
99 free(info);
100
101 return FE_SUCCESS;
102}
103
104/*----------------------------------------------------------------------------*/
105
107{
108 uint16_t r, g, b, rgb;
109 uint32_t col;
110
111 col = (uint32_t)value;
112
113 r = ((col >> 16) & 0xFF) >> 3;
114 g = ((col >> 8) & 0xFF) >> 3;
115 b = ((col >> 0) & 0xFF) >> 3;
116 rgb = (r << 11) | (g << 6) | (b << 1);
117 info->map[channel] = rgb;
118
119 return FE_SUCCESS;
120}
121
122/*----------------------------------------------------------------------------*/
123
125{
126 uint16_t r, g, b, rgb;
127 uint32_t col;
128
129 /* read value from channel */
130 rgb = info->map[channel];
131 r = (rgb >> 11) & 0x1F;
132 g = (rgb >> 6) & 0x1F;
133 b = (rgb >> 1) & 0x1F;
134
135 col = (r << 16) | (g << 8) | b;
136 *pvalue = (float) col;
137
138 return FE_SUCCESS;
139}
140
141/*---- device driver entry point -----------------------------------*/
142
143INT rpi_led(INT cmd, ...)
144{
145 va_list argptr;
146 HNDLE hKey;
148 float *pvalue;
149 double value;
150 void *info;
151
152 va_start(argptr, cmd);
154
155 switch (cmd) {
156 case CMD_INIT:
157 hKey = va_arg(argptr, HNDLE);
158 info = va_arg(argptr, void *);
160 break;
161
162 case CMD_EXIT:
163 info = va_arg(argptr, void *);
165 break;
166
167 case CMD_SET:
168 info = va_arg(argptr, void *);
169 channel = va_arg(argptr, INT);
170 value = va_arg(argptr, double);
172 break;
173
174 case CMD_GET:
175 info = va_arg(argptr, void *);
176 channel = va_arg(argptr, INT);
177 pvalue = va_arg(argptr, float *);
178 status = rpi_led_get(info, channel, pvalue);
179 break;
180
181 default:
182 break;
183 }
184
185 va_end(argptr);
186
187 return status;
188}
189
190/*------------------------------------------------------------------*/
#define FE_SUCCESS
Definition midas.h:718
#define CMD_INIT
Definition midas.h:763
#define CMD_GET
Definition midas.h:788
#define CMD_SET
Definition midas.h:778
#define CMD_EXIT
Definition midas.h:764
void ** info
Definition fesimdaq.cxx:41
INT channel
HNDLE hKey
INT HNDLE
Definition midas.h:132
int INT
Definition midas.h:129
double value[100]
Definition odbhist.cxx:42
DWORD status
Definition odbhist.cxx:39
INT rpi_led_init(HNDLE hkey, void **pinfo)
Definition rpi_led.c:44
INT rpi_led_exit(RPI_LED_INFO *info)
Definition rpi_led.c:90
INT rpi_led_set(RPI_LED_INFO *info, INT channel, double value)
Definition rpi_led.c:106
INT rpi_led(INT cmd,...)
Definition rpi_led.c:143
INT rpi_led_get(RPI_LED_INFO *info, INT channel, float *pvalue)
Definition rpi_led.c:124
#define FILESIZE
Definition rpi_led.c:37
uint16_t * map
Definition rpi_led.c:34