268 SM_SUCCESS; |
268 SM_SUCCESS; |
269 } |
269 } |
270 |
270 |
271 for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { |
271 for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) { |
272 if (strcmp(dev_w1->family, "3a") == 0) { |
272 if (strcmp(dev_w1->family, "3a") == 0) { |
273 for (i = 0; i < 2; i++) { |
273 for (device = Config.devices; device; device = device->next) { |
274 for (device = Config.devices; device; device = device->next) { |
274 if ((strcmp(dev_w1->address, device->address) == 0) && (device->direction == DEVDIR_IN_BIN)) { |
275 if ((strcmp(dev_w1->address, device->address) == 0) && (device->subdevice == i) && (device->direction == DEVDIR_IN_BIN)) { |
275 /* |
|
276 * First make sure that this device is configured as input |
|
277 * to drive the output high. Fix if programmed as output. |
|
278 */ |
|
279 if ((rc = read_w1(device->address, (char *)"state")) >= 0) { |
|
280 state = (unsigned int)rc; |
|
281 output = ((state & 0x02) >> 1) + ((state & 0x08) >> 2); /* Both latch states */ |
|
282 if ((device->subdevice == 0) && ((state & 0x02) == 0)) { /* Fix A side */ |
|
283 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, device->subdevice, output, output | 0x01); |
|
284 output |= 0x01; |
|
285 write_w1(device->address, (char *)"output", output); |
|
286 mDelay(10); |
|
287 if ((rc = read_w1(device->address, (char *)"state")) >= 0) /* Read PIO again */ |
|
288 state = (unsigned int)rc; |
|
289 } |
|
290 if ((device->subdevice == 1) && ((state & 0x08) == 0)) { /* Fix B side */ |
|
291 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, device->subdevice, output, output | 0x02); |
|
292 output |= 0x02; |
|
293 write_w1(device->address, (char *)"output", output); |
|
294 mDelay(10); |
|
295 if ((rc = read_w1(device->address, (char *)"state")) >= 0) /* Read PIO again */ |
|
296 state = (unsigned int)rc; |
|
297 } |
|
298 dev_w1->rd_cache = state; |
|
299 |
|
300 newval = ((state & 0x04) >> 1) + (state & 0x01); |
|
301 dev_w1->wr_cache = newval; |
|
302 if (newval != dev_w1->value) { |
|
303 syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d => %d", dev_w1->address, device->subdevice, state, dev_w1->value, newval); |
|
304 dev_w1->value = newval; |
|
305 dev_w1->timestamp = time(NULL); |
|
306 changed = true; |
|
307 } |
|
308 |
|
309 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
276 /* |
310 /* |
277 * First make sure that this device is configured as input |
311 * Read PIOA or PIOB pin state bits |
278 * to drive the output high. Fix if programmed as output. |
|
279 */ |
312 */ |
280 if ((rc = read_w1(device->address, (char *)"state")) >= 0) { |
313 if (device->subdevice == 0) |
281 state = (unsigned int)rc; |
314 device->value = (state & 0x01) ? 0 : 1; |
282 output = ((state & 0x02) >> 1) + ((state & 0x08) >> 2); /* Both latch states */ |
315 else if (device->subdevice == 1) |
283 if ((i == 0) && ((state & 0x02) == 0)) { /* Fix A side */ |
316 device->value = (state & 0x04) ? 0 : 1; |
284 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, output | 0x01); |
317 device->timestamp = time(NULL); |
285 output |= 0x01; |
318 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
286 write_w1(device->address, (char *)"output", output); |
319 } |
287 mDelay(10); |
320 mDelay(20); |
288 if ((rc = read_w1(device->address, (char *)"state")) >= 0) /* Read PIO again */ |
321 } else if ((strcmp(dev_w1->address, device->address) == 0) && (device->direction == DEVDIR_OUT_BIN)) { |
289 state = (unsigned int)rc; |
322 /* |
290 } |
323 * Sync output state |
291 if ((i == 1) && ((state & 0x08) == 0)) { /* Fix B side */ |
324 */ |
292 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, output | 0x02); |
325 if ((rc = read_w1(device->address, (char *)"state")) >= 0) { |
293 output |= 0x02; |
326 state = (unsigned int)rc; |
294 write_w1(device->address, (char *)"output", output); |
327 newval = output = (state & 0x01) + ((state & 0x04) >> 1); |
295 mDelay(10); |
328 |
296 if ((rc = read_w1(device->address, (char *)"state")) >= 0) /* Read PIO again */ |
329 if (device->subdevice == 0) { |
297 state = (unsigned int)rc; |
330 newval = (newval & 0xfe); |
298 } |
331 newval |= (device->value) ? 0x00 : 0x01; |
299 dev_w1->rd_cache = state; |
332 } else if (device->subdevice == 1) { |
300 |
333 newval = (newval & 0xfd); |
301 newval = ((state & 0x04) >> 1) + (state & 0x01); |
334 newval |= (device->value) ? 0x00 : 0x02; |
302 dev_w1->wr_cache = newval; |
335 } |
303 if (newval != dev_w1->value) { |
336 |
304 syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d => %d", dev_w1->address, i, state, dev_w1->value, newval); |
337 dev_w1->wr_cache = newval; |
305 dev_w1->value = newval; |
338 if (output != newval) { |
|
339 if ((write_w1(dev_w1->address, (char *)"output", newval)) == 0) { |
|
340 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, device->subdevice, output, newval); |
|
341 dev_w1->value = newval; |
306 dev_w1->timestamp = time(NULL); |
342 dev_w1->timestamp = time(NULL); |
307 changed = true; |
343 changed = true; |
308 } |
|
309 |
|
310 // pthread_mutex_lock(&mutexes[LOCK_DEVICES]); |
|
311 /* |
|
312 * Read PIOA or PIOB pin state bits |
|
313 */ |
|
314 if (device->subdevice == 0) |
|
315 device->value = (state & 0x01) ? 0 : 1; |
|
316 else if (device->subdevice == 1) |
|
317 device->value = (state & 0x04) ? 0 : 1; |
|
318 device->timestamp = time(NULL); |
|
319 // pthread_mutex_unlock(&mutexes[LOCK_DEVICES]); |
|
320 } |
|
321 mDelay(20); |
|
322 } else if ((strcmp(dev_w1->address, device->address) == 0) && (device->subdevice == i) && (device->direction == DEVDIR_OUT_BIN)) { |
|
323 /* |
|
324 * Sync output state |
|
325 */ |
|
326 if ((rc = read_w1(device->address, (char *)"state")) >= 0) { |
|
327 state = (unsigned int)rc; |
|
328 newval = output = (state & 0x01) + ((state & 0x04) >> 1); |
|
329 |
|
330 if (device->subdevice == 0) { |
|
331 newval = (newval & 0xfe); |
|
332 newval |= (device->value) ? 0x00 : 0x01; |
|
333 } else if (device->subdevice == 1) { |
|
334 newval = (newval & 0xfd); |
|
335 newval |= (device->value) ? 0x00 : 0x02; |
|
336 } |
|
337 |
|
338 dev_w1->wr_cache = newval; |
|
339 if (output != newval) { |
|
340 if ((write_w1(dev_w1->address, (char *)"output", newval)) == 0) { |
|
341 syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, newval); |
|
342 dev_w1->value = newval; |
|
343 dev_w1->timestamp = time(NULL); |
|
344 changed = true; |
|
345 } |
|
346 } |
344 } |
347 } |
345 } |
348 } |
346 } |
349 } /* for (device = Config.devices; ... */ |
347 } /* for (device = Config.devices; ... */ |
350 } |
348 } |