Am Freitag, 15. Dezember 2006 03:05 schrieb Paul Alfille:
> Jan,
>
> The DS2409 code has been quite a chore to implement. OWFS has the most
> flexible of any implementation I know -- support for unlimitted branching,
> interleaved bus usage, and lazy bus changes. I'll be interested in any
> improvements you can make, but it isn't easy.
>
I made some progress in catching the "smart-on" problem -- a "single"
implementation in the DS2409 code branch just works as expected, only the
iButton connected to the main branch of the DS2409 responds to a 0x33 "read
ROM" command. Example code is attached.
The needed changes in the BUS_select code could be quite simple, I think. Just
the final BUS_reset in ow_select.c, line 90 has to be replaced by a more
sophisticated reset method. Pseudocode:
if last_branch_component(_path_) == "")
|| last_branch_component(_path_) == "bus.n")
{ BUS_reset(); }
else
{
Bus_select(last_branch_ds2409(_path_);
if last_branch_component(_path_) == "main")
{ DS2409_Smart_On_Main(_path_) }
else
{ DS2409_Smart_On_Aux(_path_) }
}
I'm digging deeper into the path functions next week, as the last_branch...
pseudofunctions may be the toughest part to implement.
Kind regards
Jan
--
Windows ist Kommunismus: Es hört sich gut an, funktioniert aber nicht.
/*
$Id: ow_2409.c,v 1.15 2006/06/16 22:15:19 alfille Exp $
OWFS -- One-Wire filesystem
OWHTTPD -- One-Wire Web Server
Written 2003 Paul H Alfille
email: [EMAIL PROTECTED]
Released under the GPL
See the header file: ow.h for full attribution
1wire/iButton system from Dallas Semiconductor
*/
/* General Device File format:
This device file corresponds to a specific 1wire/iButton chip type
( or a closely related family of chips )
The connection to the larger program is through the "device" data structure,
which must be declared in the acompanying header file.
The device structure holds the
family code,
name,
number of properties,
list of property structures, called "filetype".
Each filetype structure holds the
name,
estimated length (in bytes),
aggregate structure pointer,
data format,
read function,
write funtion,
generic data pointer
The aggregate structure, is present for properties that several members
(e.g. pages of memory or entries in a temperature log. It holds:
number of elements
whether the members are lettered or numbered
whether the elements are stored together and split, or separately and joined
*/
#include <config.h>
#include "owfs_config.h"
#include "ow_2409.h"
/* ------- Prototypes ----------- */
/* DS2409 switch */
yWRITE_FUNCTION( FS_discharge ) ;
uREAD_FUNCTION( FS_r_control ) ;
uWRITE_FUNCTION( FS_w_control ) ;
uREAD_FUNCTION( FS_r_sensed ) ;
uREAD_FUNCTION( FS_r_branch ) ;
uREAD_FUNCTION( FS_r_event ) ;
yWRITE_FUNCTION( FS_clearevent ) ;
aREAD_FUNCTION( FS_r_single ) ;
/* ------- Structures ----------- */
struct aggregate A2409 = { 2, ag_numbers, ag_aggregate, } ;
struct filetype DS2409[] = {
F_STANDARD ,
{"discharge" , 1, NULL, ft_yesno , fc_stable , {v:NULL} , {y:FS_discharge} , {v:NULL}, } ,
{"control" , 1, NULL, ft_unsigned , fc_stable , {u:FS_r_control}, {u:FS_w_control} , {v:NULL}, } ,
{"sensed" , 1,&A2409, ft_bitfield , fc_volatile, {u:FS_r_sensed} , {v:NULL} , {v:NULL}, } ,
{"branch" , 1,&A2409, ft_bitfield , fc_volatile, {u:FS_r_branch} , {v:NULL} , {v:NULL}, } ,
{"event" , 1,&A2409, ft_bitfield , fc_volatile, {u:FS_r_event} , {v:NULL} , {v:NULL}, } ,
{"clearevent", 1, NULL, ft_yesno , fc_stable , {v:NULL} , {y:FS_clearevent}, {v:NULL}, } ,
{"aux" , 0, NULL, ft_directory, fc_volatile, {v:NULL} , {v:NULL} , {i: 1}, } ,
{"main" , 0, NULL, ft_directory, fc_volatile, {v:NULL} , {v:NULL} , {i: 0}, } ,
{"single" , 15, NULL, ft_ascii, fc_volatile, {a:FS_r_single} , {v:NULL}, {i: 0 } , } ,
{"single_ds2400", 15, NULL, ft_ascii, fc_volatile, {a:FS_r_single} , {v:NULL}, {i: 1 } , } ,
} ;
DeviceEntry( 1F, DS2409 ) ;
/* ------- Functions ------------ */
/* DS2409 */
static int OW_r_control( BYTE * data, const struct parsedname * pn ) ;
static int OW_discharge( const struct parsedname * pn ) ;
static int OW_w_control( const UINT data , const struct parsedname * pn ) ;
static int OW_clearevent( const struct parsedname * pn ) ;
/* discharge 2409 lines */
static int FS_discharge(const int * y, const struct parsedname * pn) {
if ( (*y) && OW_discharge(pn) ) return -EINVAL ;
return 0 ;
}
/* Clear 2409 event bits (and alarm state) */
static int FS_clearevent(const int * y, const struct parsedname * pn) {
if ( (*y) && OW_clearevent(pn) ) return -EINVAL ;
return 0 ;
}
/* 2409 switch -- branch pin voltage */
static int FS_r_sensed(UINT * u , const struct parsedname * pn) {
BYTE data ;
if ( OW_r_control(&data,pn) ) return -EINVAL ;
// y[0] = data&0x02 ? 1 : 0 ;
// y[1] = data&0x08 ? 1 : 0 ;
u[0] = ((data>>1)&0x01) | ((data>>2)&0x02) ;
return 0 ;
}
/* 2409 switch -- branch status -- note that bit value is reversed */
static int FS_r_branch(UINT * u , const struct parsedname * pn) {
BYTE data ;
if ( OW_r_control(&data,pn) ) return -EINVAL ;
// y[0] = data&0x01 ? 0 : 1 ;
// y[1] = data&0x04 ? 0 : 1 ;
u[0] = (((data)&0x01) | ((data>>1)&0x02)) ^ 0x03 ;
return 0 ;
}
/* 2409 switch -- event status */
static int FS_r_event(UINT * u , const struct parsedname * pn) {
BYTE data ;
if ( OW_r_control(&data,pn) ) return -EINVAL ;
// y[0] = data&0x10 ? 1 : 0 ;
// y[1] = data&0x20 ? 1 : 0 ;
u[0] = (data>>4)&0x03 ;
return 0 ;
}
/* 2409 switch -- control pin state */
static int FS_r_control(UINT * u , const struct parsedname * pn) {
BYTE data ;
UINT control[] = { 2, 3, 0, 1, } ;
if ( OW_r_control(&data,pn) ) return -EINVAL ;
*u = control[data>>6] ;
return 0 ;
}
/* 2409 switch -- control pin state */
static int FS_w_control(const UINT * u , const struct parsedname * pn) {
if ( *u > 3 ) return -EINVAL ;
if ( OW_w_control(*u,pn) ) return -EINVAL ;
return 0 ;
}
static int OW_discharge( const struct parsedname * pn ) {
BYTE dis[] = { 0x99, } ;
struct transaction_log t[] = {
TRXN_START,
{ dis, NULL, 1, trxn_match } ,
TRXN_END,
} ;
if ( BUS_transaction( t, pn ) ) return 1 ;
UT_delay(100) ;
dis[0] = 0x66 ;
if ( BUS_transaction( t, pn ) ) return 1 ;
return 0 ;
}
static int OW_clearevent( const struct parsedname * pn ) {
BYTE clear[] = { 0x66, } ;
struct transaction_log t[] = {
TRXN_START,
{ clear, NULL, 1, trxn_match } ,
TRXN_END,
} ;
if ( BUS_transaction( t, pn ) ) return 1 ;
return 0 ;
}
static int OW_w_control( const UINT data , const struct parsedname * pn ) {
const BYTE d[] = { 0x20, 0xA0, 0x00, 0x40, } ;
BYTE p[] = { 0x5A, d[data], } ;
const BYTE r[] = { 0x80, 0xC0, 0x00, 0x40, } ;
BYTE info ;
struct transaction_log t[] = {
TRXN_START,
{ p, NULL, 2, trxn_match } ,
{ NULL, &info, 1, trxn_read } ,
TRXN_END,
} ;
if ( BUS_transaction( t, pn ) ) return 1 ;
/* Check that Info corresponds */
return (info&0xC0)==r[data] ? 0 : 1 ;
}
static int OW_r_control( BYTE * data , const struct parsedname * pn ) {
BYTE p[] = { 0x5A, 0xFF, } ;
struct transaction_log t[] = {
TRXN_START,
{ p, NULL, 2, trxn_match } ,
{ NULL, data, 1, trxn_read } ,
TRXN_END,
} ;
if ( BUS_transaction( t, pn ) ) return 1 ;
return 0 ;
}
/* just for testing purposes */
static int FS_r_single(char *buf, const size_t size, const off_t offset , const struct parsedname * pn) {
if ( pn->in->Adapter == adapter_fake ) {
return (pn->in->connin.fake.db.devices > 0) ;
} else {
ASCII ret_string[15] ;
BYTE smart_on_main[] = { 0xCC, 0xFF, } ;
BYTE pres[] = { 0xFF, 0xFF, } ;
BYTE read_ROM[] = { 0x33, } ;
BYTE resp[8] ;
BYTE match[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, } ;
struct transaction_log t[] = {
TRXN_START,
{ smart_on_main, NULL, 2, trxn_match } ,
{ NULL, pres, 2, trxn_read } ,
{ read_ROM, NULL, 1, trxn_match } ,
{ NULL, resp, 8, trxn_read } ,
TRXN_END,
} ;
/* check if DS2400 compatibility is needed */
if ( pn->ft->data.i ) read_ROM[0] = 0x0F;
if ( BUS_transaction( t, pn ) ) return -EINVAL ;
printf("FS_r_single (ds2409) pres=%02x conf=%02x dat=%02x.%02x%02x%02x%02x%02x%02x crc8=%02x crc8c=%02x\n",pres[0],pres[1],resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],CRC8(resp,7)) ;
if ( memcmp(resp, match, 8 ) ) { // some device(s) complained
if ( CRC8(resp, 8 ) ) { // crc8 error -- more than one device
ret_string[0]='\0';
return FS_output_ascii( buf, size, offset, ret_string, 1 ) ;
}
/* Return device id. */
bytes2string( ret_string, resp, 1 ) ;
ret_string[2]='.';
bytes2string( &ret_string[3], &resp[1], 6 ) ;
return FS_output_ascii( buf, size, offset, ret_string, 15 ) ;
} else { //no devices
ret_string[0]='\0';
return FS_output_ascii( buf, size, offset, ret_string, 1 ) ;
}
}
return 0 ;
}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Owfs-developers mailing list
Owfs-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/owfs-developers