one-wire bus driver

This forum is about you. Feel free to discuss anything is related to embedded and electronics, your awesome projects, your ideas, your announcements, not necessarily related to ChibiOS but to embedded in general. This forum is NOT for support.
Post Reply
dash
Posts: 17
Joined: Thu Oct 25, 2012 10:16 pm
Has thanked: 1 time
Been thanked: 4 times

one-wire bus driver

Post by dash »

A long time ago I wrote a 1-wire bus driver and now decided to share :)
my driver tested on STM32F107, but I think it is platform-independent,
since it uses the UART driver (imho finest bus timing).
the driver is configurable by next #define's

Code: Select all

#define HAL_USE_ONEWIRE        TRUE   // enable driver code

#define ONEWIRE_USE_OW1        TRUE     // 1wire bus #1
#define ONEWIRE_USE_OW2        FALSE    // 1wire bus #2
#define ONEWIRE_USE_SEARCH     FALSE    // compile 1wire search algorithm
#define ONEWIRE_USE_READROM    FALSE    // compile owReadRom
#define ONEWIRE_USE_CRC8       TRUE     // compile owCrc8
#define ONEWIRE_USE_SELECT     FALSE    // compile selective device support
#define ONEWIRE_USE_OVERDRIVE  FALSE    // compile OverDrive speed support


simple example - read TM on PB10 (there must be external pull-up)

Code: Select all

int main(void) {

  halInit();
  chSysInit();
  owInit();

// setup onewire bus
// set half-duplex mode & open-drain output
  palSetPadMode( GPIOB, 10, PAL_MODE_STM32_ALTERNATE_OPENDRAIN );
  OWD1.cfg.cr3 = USART_CR3_HDSEL;
  owStart( &OWD1, &UARTD3 );
   
  while (TRUE)
  {
    uint8_t rxbuf[8];

    if( RDY_OK == owReadRom( &OWD1, rxbuf ) )   // READ_ROM command
    {
      chprintf( syscon, "rx %02X %02X %02X %02X %02X %02X %02X %02X ",
        rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7] );

      if( 0 == owCrc8( rxbuf, sizeof(rxbuf) ) )    chprintf( syscon, "[crc ok]" );
      chprintf( syscon, "\r\n" );
    }
      
    chThdSleepMilliseconds(100);
  }
}


more complex example - read temperature sensor

Code: Select all

(init skipped)

  while(TRUE)
  {
    if( RDY_OK == owCommand( &OWD1, 0x44, NULL, 0 ) )
    {
      chThdSleepMilliseconds( 750 );
      if( RDY_OK == owCommand( &OWD1, 0xBE, rxbuf, -sizeof(rxbuf) ) )   // negative size - we will read bus
      {
        if( 0 == owCrc8( rxbuf, sizeof(rxbuf) ) )
        {
          int tempr = *((uint16_t*)rxbuf) >> 2;

          sprintf( txt, "T = %d.%d", tempr >> 2, (tempr & 3) * 25 );

(other code skipped)
        }
      }
    }

    chThdSleepSeconds( 2 );
  }


bus scan example

Code: Select all

(init skipped)

  owSearchStart( &OWD1, 0 );
  chprintf( (BaseSequentialStream *)&SD2, "Start search\r\n" );

  while(TRUE)
  {
    rom_id_t dev;

    result = owSearch( &OWD1, &dev );
    if( RDY_OK == result )
    {
      chprintf( (BaseSequentialStream *)&SD2, "found device =" );
      for( i = 0; i < 8; i++ )      chprintf( (BaseSequentialStream *)&SD2, " %02x", dev.arr[i] );
      chprintf( (BaseSequentialStream *)&SD2, "\r\n" );
               
      if( dev.arr[0] == 0x28 )   // temp sensor?
        test = dev;
    }
    else
      break;
  }

  if( RDY_RESET == result )
    chprintf( (BaseSequentialStream *)&SD2, "bus error\r\n" );
  else
  {
    owSelect( &OWD1, &test, FALSE );
         
    result = owCommand( &OWD1, 0x44, NULL, 0, FALSE );
    chprintf( (BaseSequentialStream *)&SD2, "result = %d\r\n", result );
  }


I will be glad if someone will find it useful :)
Attachments
onewire.zip
(4.08 KiB) Downloaded 640 times
Alexte
Posts: 27
Joined: Sun Jul 01, 2012 1:24 pm

Re: one-wire bus driver

Post by Alexte »

Hello Dash.
How to read the data on the same bus if several temperature sensors?
dash
Posts: 17
Joined: Thu Oct 25, 2012 10:16 pm
Has thanked: 1 time
Been thanked: 4 times

Re: one-wire bus driver

Post by dash »

Alexte wrote:Hello Dash.
How to read the data on the same bus if several temperature sensors?


If you know the serial numbers of your sensors, you can use owSelect to select the desired sensor. All subsequent commands will be addressed to the selected sensor.
To return to the "broadcast mode" select "device" with serial number 0.
If you do not know the serials of your sensors you need to scan the bus as in the last example.
Post Reply