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

Reply via email to