source: roaraudio/plugins/roard/dmx-i2c.c @ 5905:30fa6187b488

Last change on this file since 5905:30fa6187b488 was 5905:30fa6187b488, checked in by phi, 11 years ago

added experimental DMX driver for I²C based devices

File size: 4.2 KB
Line 
1//dmx-i2c.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2013
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include <roard/include/roard.h>
27#include <sys/ioctl.h>
28#include <linux/i2c.h>
29#include <linux/i2c-dev.h>
30
31#define DEFAULT_DEVICE "/dev/i2c-1"
32#define DEFAULT_SLAVE  0x58
33
34#define ADDR_COMMAND   2
35#define ADDR_DATA      4
36
37#define COMMAND_DMX    0x3f
38
39struct state {
40 size_t startaddr;
41 size_t len;
42 uint8_t slave;
43 struct roar_vio_calls * vio;
44};
45
46static struct state * g_state;
47static struct state   g_state_init = {
48 .startaddr =  0,
49 .len       =  16,
50 .slave     = DEFAULT_SLAVE,
51 .vio       = NULL
52};
53
54static inline int __i2c_set_slave(void) {
55 struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SLAVE, .argp = (void*)(int)g_state->slave};
56
57 return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl);
58}
59static inline int __i2c_write(size_t off, const uint8_t value) {
60 union i2c_smbus_data data = {.byte = value};
61 struct i2c_smbus_ioctl_data args = {.read_write = I2C_SMBUS_WRITE, .command = off, .size = I2C_SMBUS_BYTE_DATA, .data = &data};
62 struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SMBUS, .argp = &args};
63
64 return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl);
65}
66
67static inline int __i2c_command(uint8_t command) {
68 return __i2c_write(ADDR_COMMAND, command);
69}
70
71static inline int __i2c_start_dmx(void) {
72 return __i2c_command(COMMAND_DMX);
73}
74
75static inline int __i2c_set_channel(size_t channel, uint8_t value) {
76 return __i2c_write(ADDR_DATA+channel, value);
77}
78
79static int _init  (struct roar_dl_librarypara * para) {
80 struct roar_keyval * p;
81 const char * dev = DEFAULT_DEVICE;
82
83 p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1);
84 if ( p != NULL && p->value != NULL )
85  g_state->startaddr = atoi(p->value);
86
87 p = roar_keyval_lookup(para->argv, "len", para->argc, 1);
88 if ( p != NULL && p->value != NULL )
89  g_state->len = atoi(p->value);
90
91 p = roar_keyval_lookup(para->argv, "slave", para->argc, 1);
92 if ( p != NULL && p->value != NULL )
93  g_state->slave = atoi(p->value);
94
95 p = roar_keyval_lookup(para->argv, "device", para->argc, 1);
96 if ( p != NULL && p->value != NULL )
97  dev = p->value;
98
99 g_state->vio = roar_vio_open_dstr_simple_new(dev, ROAR_VIOF_READWRITE);
100 if ( g_state->vio == NULL ) {
101  ROAR_ERR("_init(para=%p): Can not open device: %s: %s", para, dev, roar_errorstring);
102  return -1;
103 }
104
105 __i2c_set_slave();
106
107 return 0;
108}
109
110static int _free  (struct roar_dl_librarypara * para) {
111 (void)para;
112 roar_vio_close(g_state->vio);
113 g_state->vio = NULL;
114 return 0;
115}
116
117static int _update  (struct roar_dl_librarypara * para) {
118 size_t i;
119 int val;
120
121 (void)para;
122
123 __i2c_start_dmx();
124
125 for (i = 0; i < g_state->len; i++) {
126  val = light_dmxchannel_get(g_state->startaddr + i);
127  if ( val < 0 )
128   continue;
129  __i2c_set_channel(i, val);
130 }
131
132 return 0;
133}
134
135static struct roar_dl_appsched sched = {
136 .init   = _init,
137 .free   = _free,
138 .update = _update,
139 .tick   = NULL,
140 .wait   = NULL
141};
142
143ROAR_DL_PLUGIN_START(dmx_waveform) {
144 ROARD_DL_CHECK_VERSIONS();
145
146 ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-i2c", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO);
147 ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING);
148 ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0);
149 ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org");
150 ROAR_DL_PLUGIN_META_DESC("This plugin sends DMX data to RoarAudio DMX Transmitters using I²C");
151
152 ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init);
153 ROAR_DL_PLUGIN_REG_APPSCHED(&sched);
154} ROAR_DL_PLUGIN_END
155
156//ll
Note: See TracBrowser for help on using the repository browser.