source: roaraudio/plugins/roard/dmx-i2c.c @ 5906:006573352519

Last change on this file since 5906:006573352519 was 5906:006573352519, checked in by phi, 11 years ago

updated protocol support to support /banks/

File size: 4.4 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_BANK      4
36#define ADDR_DATA      5
37
38#define COMMAND_DMX    0x3f
39
40struct state {
41 size_t startaddr;
42 size_t len;
43 uint8_t slave;
44 struct roar_vio_calls * vio;
45};
46
47static struct state * g_state;
48static struct state   g_state_init = {
49 .startaddr =  0,
50 .len       =  16,
51 .slave     = DEFAULT_SLAVE,
52 .vio       = NULL
53};
54
55static inline int __i2c_set_slave(void) {
56 struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SLAVE, .argp = (void*)(int)g_state->slave};
57
58 return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl);
59}
60static inline int __i2c_write(size_t off, const uint8_t value) {
61 union i2c_smbus_data data = {.byte = value};
62 struct i2c_smbus_ioctl_data args = {.read_write = I2C_SMBUS_WRITE, .command = off, .size = I2C_SMBUS_BYTE_DATA, .data = &data};
63 struct roar_vio_sysio_ioctl ctl = {.cmd = I2C_SMBUS, .argp = &args};
64
65 return roar_vio_ctl(g_state->vio, ROAR_VIO_CTL_SYSIO_IOCTL, &ctl);
66}
67
68static inline int __i2c_command(uint8_t command) {
69 return __i2c_write(ADDR_COMMAND, command);
70}
71
72static inline int __i2c_start_dmx(void) {
73 return __i2c_command(COMMAND_DMX);
74}
75
76static inline int __i2c_set_channel(size_t channel, uint8_t value) {
77 size_t bank, offset;
78
79 bank = channel/32;
80 offset = bank*32;
81
82 if ( __i2c_write(ADDR_BANK, bank) == -1 )
83  return -1;
84
85 return __i2c_write(ADDR_DATA+channel-offset, value);
86}
87
88static int _init  (struct roar_dl_librarypara * para) {
89 struct roar_keyval * p;
90 const char * dev = DEFAULT_DEVICE;
91
92 p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1);
93 if ( p != NULL && p->value != NULL )
94  g_state->startaddr = atoi(p->value);
95
96 p = roar_keyval_lookup(para->argv, "len", para->argc, 1);
97 if ( p != NULL && p->value != NULL )
98  g_state->len = atoi(p->value);
99
100 p = roar_keyval_lookup(para->argv, "slave", para->argc, 1);
101 if ( p != NULL && p->value != NULL )
102  g_state->slave = atoi(p->value);
103
104 p = roar_keyval_lookup(para->argv, "device", para->argc, 1);
105 if ( p != NULL && p->value != NULL )
106  dev = p->value;
107
108 g_state->vio = roar_vio_open_dstr_simple_new(dev, ROAR_VIOF_READWRITE);
109 if ( g_state->vio == NULL ) {
110  ROAR_ERR("_init(para=%p): Can not open device: %s: %s", para, dev, roar_errorstring);
111  return -1;
112 }
113
114 __i2c_set_slave();
115
116 return 0;
117}
118
119static int _free  (struct roar_dl_librarypara * para) {
120 (void)para;
121 roar_vio_close(g_state->vio);
122 g_state->vio = NULL;
123 return 0;
124}
125
126static int _update  (struct roar_dl_librarypara * para) {
127 size_t i;
128 int val;
129
130 (void)para;
131
132 __i2c_start_dmx();
133
134 for (i = 0; i < g_state->len; i++) {
135  val = light_dmxchannel_get(g_state->startaddr + i);
136  if ( val < 0 )
137   continue;
138  __i2c_set_channel(i, val);
139 }
140
141 return 0;
142}
143
144static struct roar_dl_appsched sched = {
145 .init   = _init,
146 .free   = _free,
147 .update = _update,
148 .tick   = NULL,
149 .wait   = NULL
150};
151
152ROAR_DL_PLUGIN_START(dmx_waveform) {
153 ROARD_DL_CHECK_VERSIONS();
154
155 ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-i2c", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO);
156 ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING);
157 ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0);
158 ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org");
159 ROAR_DL_PLUGIN_META_DESC("This plugin sends DMX data to RoarAudio DMX Transmitters using I²C");
160
161 ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init);
162 ROAR_DL_PLUGIN_REG_APPSCHED(&sched);
163} ROAR_DL_PLUGIN_END
164
165//ll
Note: See TracBrowser for help on using the repository browser.