Connect with us

Send data with one wire protocol?

Discussion in 'Microcontrollers, Programming and IoT' started by ArFa, Jan 21, 2013.

Scroll to continue with content
  1. ArFa

    ArFa

    17
    0
    Dec 7, 2010
    Hi there,
    I want to send data through one wire protocol from stm8.
    So, stm8 will act as one wire slave device, and send those data to another device through one wire protocol.

    Please if you can, tell me how to solve this problem !
     
  2. (*steve*)

    (*steve*) ¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd Moderator

    25,448
    2,809
    Jan 21, 2010
    I suggest you read the documentation on the protocol. (of course you realise that you need more than one wire)
     
  3. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    Try Googling "implement 1-wire slave" (without the quotes). There's been plenty of discussion.

    It should not be too difficult, provided that you can guarantee a fairly low interrupt latency - that is, your interrupt handler needs to get control within a few microseconds of the 1-wire master driving the bus low. If it doesn't, it won't be able to hold the bus low when the master releases it, to transmit a 0-bit. So all the other code running on the device must not lock out interrupts for more than a few microseconds, maximum.

    A timer running at 1 MHz or higher with an available free-running count register could help with the timing, or you can just use instruction cycle counting if the micro behaves consistently in this respect.

    There's a fair amount of work required to implement the full protocol, but if you understand the master end, implementing a slave end shouldn't be too hard.

    I've never done it though. There might be a stumbling block somewhere.

    Have a look at the other people who have tried it. If you have any specific questions, ask them here and I may be able to help.

    Edit: A small amount of external hardware would probably greatly decrease the load and requirements on the firmware. You can get micros with a PLD or FPGA block built in; these would be ideal.
     
    Last edited: Jan 23, 2013
  4. ArFa

    ArFa

    17
    0
    Dec 7, 2010
    Thanks for your answers...
    I've an arduino code for master end, and a code for a slave also in arduino.
    I understood it, but the problem is that I'm not able to measure the low bus time from master, so i can't read the command by master.
    Do you have any idea for programming stm8s from arduino ?

    if you are interested, i could post arduino codes, and my stm8s code.
     
  5. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    It's interesting that you say you can't measure the bus low time on the slave. On the master, you need to be able to distinguish a received 0-bit from a received 1-bit, so your code must already be capable of this; as I see it, the major difference between master and slave is that the slave needs to be able to deal with received bus transitions at any time, and respond within a few microseconds, if it's transmitting. So I assume it's this difference between the master and slave code that causes the problem with measuring the bus low time. I would need to see your master and slave code to be able to say whether you can fix this problem with code changes only.

    The best (or only) way to handle one-wire communication in any MCU depends very much on the peripherals available in that MCU.

    For example, if you can only interrupt on the falling edge of the 1-wire bus, your interrupt handler needs to quickly branch according to the context of the bus and either transmit a 1-bit, receive a 1-bit, transmit a 0-bit, or receive a 0-bit; in the latter two cases, the MCU needs to wait inside the interrupt handler for the duration of a 0-bit, and this will cause significant overhead and latency for other interrupt sources.

    If you have a timer with input capture and/or output compare, especially if there is double-buffering or triple-buffering, you may be able to avoid spending any significant time in the interrupt handler. A master implementation I wrote for the MSP430 received data using an input capture, so it didn't have to wait for the end of a 0-bit; the input capture logic would capture the timestamp of the falling edge and the rising edge, so a simple subtraction would give the low-period time, and the distinction between a 1-bit and a 0-bit could be made from that value.

    I haven't used the STM8S myself, but a quick look at a data sheet for a small device shows that it has plenty of input capture and output compare capability. This should be able to help reduce the firmware overhead of implementing a 1-wire receiver. The data sheet I found doesn't describe the CAPCOM features in any detail; if you know of a detailed description, please post the URL.

    As I mentioned before, the best option is hardware support - a 1-wire interface circuit that can transmit and receive bits or bytes at a time with only very loose requirements for the firmware, both in terms of overhead, and required interrupt latency.

    As I said, I'm not familiar with the STM8S architecture, but I do know the AVR architecture. Actually I think I've written a 1-wire bus driver for AVR, but not a slave. But please go ahead and post the code here and I'll see if I can help.
     
    Last edited: Jan 24, 2013
  6. ArFa

    ArFa

    17
    0
    Dec 7, 2010
    thnx for reply KrisBlueNZ,
    Actually I don't know about CAPCOM, but my programming logic is based in interrupts, so every bit received from master fires an interrupt, than I would transmit the data bit.
    The codes are as follows:

    one wire master -> reader (Arduino for avr):
    Code:
    #include <inttypes.h>
    #include "pins_arduino.h"
    extern "C" {
    //#include "WConstants.h"
    #include "Arduino.h"
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    }
    // you can exclude onewire_search by defining that to 0
    #ifndef ONEWIRE_SEARCH
    #define ONEWIRE_SEARCH 1
    #endif
    
    // You can exclude CRC checks altogether by defining this to 0
    #ifndef ONEWIRE_CRC
    #define ONEWIRE_CRC 1
    #endif
    
    // Select the table-lookup method of computing the 8-bit CRC
    // by setting this to 1.  The lookup table no longer consumes
    // limited RAM, but enlarges total code size by about 250 bytes
    #ifndef ONEWIRE_CRC8_TABLE
    #define ONEWIRE_CRC8_TABLE 0
    #endif
    
    // You can allow 16-bit CRC checks by defining this to 1
    // (Note that ONEWIRE_CRC must also be 1.)
    #ifndef ONEWIRE_CRC16
    #define ONEWIRE_CRC16 0
    #endif
    
    #define FALSE 0
    #define TRUE  1
    
    class OneWire
    {
      private:
        uint8_t bitmask;
        volatile uint8_t *baseReg;
    
    #if ONEWIRE_SEARCH
        // global search state
        unsigned char ROM_NO[8];
        uint8_t LastDiscrepancy;
        uint8_t LastFamilyDiscrepancy;
        uint8_t LastDeviceFlag;
    #endif
    
      public:
        OneWire( uint8_t pin);
    
        // Perform a 1-Wire reset cycle. Returns 1 if a device responds
        // with a presence pulse.  Returns 0 if there is no device or the
        // bus is shorted or otherwise held low for more than 250uS
        uint8_t reset(void);
    
        // Issue a 1-Wire rom select command, you do the reset first.
        void select( uint8_t rom[8]);
    
        // Issue a 1-Wire rom skip command, to address all on bus.
        void skip(void);
    
        // Write a byte. If 'power' is one then the wire is held high at
        // the end for parasitically powered devices. You are responsible
        // for eventually depowering it by calling depower() or doing
        // another read or write.
        void write(uint8_t v, uint8_t power = 0);
    
        // Read a byte.
        uint8_t read(void);
    
        // Write a bit. The bus is always left powered at the end, see
        // note in write() about that.
        void write_bit(uint8_t v);
    
        // Read a bit.
        uint8_t read_bit(void);
    
        // Stop forcing power onto the bus. You only need to do this if
        // you used the 'power' flag to write() or used a write_bit() call
        // and aren't about to do another read or write. You would rather
        // not leave this powered if you don't have to, just in case
        // someone shorts your bus.
        void depower(void);
    
    #if ONEWIRE_SEARCH
        // Clear the search state so that if will start from the beginning again.
        void reset_search();
    
        // Look for the next device. Returns 1 if a new address has been
        // returned. A zero might mean that the bus is shorted, there are
        // no devices, or you have already retrieved all of them.  It
        // might be a good idea to check the CRC to make sure you didn't
        // get garbage.  The order is deterministic. You will always get
        // the same devices in the same order.
        uint8_t search(uint8_t *newAddr);
    #endif
    
    #if ONEWIRE_CRC
        // Compute a Dallas Semiconductor 8 bit CRC, these are used in the
        // ROM and scratchpad registers.
        static uint8_t crc8( uint8_t *addr, uint8_t len);
    
    #if ONEWIRE_CRC16
        // Compute a Dallas Semiconductor 16 bit CRC. Maybe. I don't have
        // any devices that use this so this might be wrong. I just copied
        // it from their sample code.
        static unsigned short crc16(unsigned short *data, unsigned short len);
    #endif
    #endif
    };
    
    
    OneWire::OneWire(uint8_t pin)
    {
    	bitmask =  digitalPinToBitMask(pin);
    	baseReg = portInputRegister(digitalPinToPort(pin));
    #if ONEWIRE_SEARCH
    	reset_search();
    #endif
    }
    
    
    #define DIRECT_READ(base, mask)		(((*(base)) & (mask)) ? 1 : 0)
    #define DIRECT_MODE_INPUT(base, mask)	((*(base+1)) &= ~(mask))
    #define DIRECT_MODE_OUTPUT(base, mask)	((*(base+1)) |= (mask))
    #define DIRECT_WRITE_LOW(base, mask)	((*(base+2)) &= ~(mask))
    #define DIRECT_WRITE_HIGH(base, mask)	((*(base+2)) |= (mask))
    
    
    // Perform the onewire reset function.  We will wait up to 250uS for
    // the bus to come high, if it doesn't then it is broken or shorted
    // and we return a 0;
    //
    // Returns 1 if a device asserted a presence pulse, 0 otherwise.
    //
    uint8_t OneWire::reset(void)
    {
    	uint8_t mask=bitmask;
    	volatile uint8_t *reg asm("r30") = baseReg;
    	uint8_t r;
    	uint8_t retries = 125;
    
    	cli();
    	DIRECT_MODE_INPUT(reg, mask);
    	sei();
    	// wait until the wire is high... just in case
    	do {
    		if (--retries == 0) return 0;
    		delayMicroseconds(2);
    	} while ( !DIRECT_READ(reg, mask));
    
    	cli();
    	DIRECT_WRITE_LOW(reg, mask);
    	DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
    	sei();
    	delayMicroseconds(500); // send reset signal
    	cli();
    	DIRECT_MODE_INPUT(reg, mask);	// allow it to float
    	delayMicroseconds(80);
    	r = !DIRECT_READ(reg, mask);
    	sei();
    	delayMicroseconds(420);
            /*
            if(r)
              Serial.println("Presence received");
            else
              Serial.println("Presence not received");
              */
    	return r;
    }
    
    //
    // Write a bit. Port and bit is used to cut lookup time and provide
    // more certain timing.
    //
    void OneWire::write_bit(uint8_t v)
    {
    	uint8_t mask=bitmask;
    	volatile uint8_t *reg asm("r30") = baseReg;
    
    	if (v & 1) {
    		cli();
    		DIRECT_WRITE_LOW(reg, mask);
    		DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
    		delayMicroseconds(10);
    		DIRECT_WRITE_HIGH(reg, mask);	// drive output high
    		sei();
    		delayMicroseconds(55);
    	} else {
    		cli();
    		DIRECT_WRITE_LOW(reg, mask);
    		DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
    		delayMicroseconds(65);
    		DIRECT_WRITE_HIGH(reg, mask);	// drive output high
    		sei();
    		delayMicroseconds(5);
    	}
    }
    
    //
    // Read a bit. Port and bit is used to cut lookup time and provide
    // more certain timing.
    //
    uint8_t OneWire::read_bit(void)
    {
    	uint8_t mask=bitmask;
    	volatile uint8_t *reg asm("r30") = baseReg;
    	uint8_t r;
    
    	cli();
    	DIRECT_MODE_OUTPUT(reg, mask);
    	DIRECT_WRITE_LOW(reg, mask);
    	delayMicroseconds(3);
    	DIRECT_MODE_INPUT(reg, mask);	// let pin float, pull up will raise
    	delayMicroseconds(9);
    	r = DIRECT_READ(reg, mask);
    	sei();
    	delayMicroseconds(53);
    	return r;
    }
    
    //
    // Write a byte. The writing code uses the active drivers to raise the
    // pin high, if you need power after the write (e.g. DS18S20 in
    // parasite power mode) then set 'power' to 1, otherwise the pin will
    // go tri-state at the end of the write to avoid heating in a short or
    // other mishap.
    //
    void OneWire::write(uint8_t v, uint8_t power /* = 0 */) {
        uint8_t bitMask;
    
        for (bitMask = 0x01; bitMask; bitMask <<= 1) {
    	OneWire::write_bit( (bitMask & v)?1:0);
        }
        if ( !power) {
    	cli();
    	DIRECT_MODE_INPUT(baseReg, bitmask);
    	DIRECT_WRITE_LOW(baseReg, bitmask);
    	sei();
        }
    }
    
    //
    // Read a byte
    //
    uint8_t OneWire::read() {
        uint8_t bitMask;
        uint8_t r = 0;
    
        for (bitMask = 0x01; bitMask; bitMask <<= 1) {
    	if ( OneWire::read_bit()) r |= bitMask;
        }
        return r;
    }
    
    //
    // Do a ROM select
    //
    void OneWire::select( uint8_t rom[8])
    {
        int i;
        
        write(0x55);           // Choose ROM
    
        for( i = 0; i < 8; i++) write(rom[i]);
    }
    
    //
    // Do a ROM skip
    //
    void OneWire::skip()
    {
        write(0xCC);           // Skip ROM
    }
    
    void OneWire::depower()
    {
    	cli();
    	DIRECT_MODE_INPUT(baseReg, bitmask);
    	sei();
    }
    
    #if ONEWIRE_SEARCH
    
    //
    // You need to use this function to start a search again from the beginning.
    // You do not need to do it for the first search, though you could.
    //
    void OneWire::reset_search()
      {
      // reset the search state
      LastDiscrepancy = 0;
      LastDeviceFlag = FALSE;
      LastFamilyDiscrepancy = 0;
      for(int i = 7; ; i--)
        {
        ROM_NO[i] = 0;
        if ( i == 0) break;
        }
      }
    
    //
    // Perform a search. If this function returns a '1' then it has
    // enumerated the next device and you may retrieve the ROM from the
    // OneWire::address variable. If there are no devices, no further
    // devices, or something horrible happens in the middle of the
    // enumeration then a 0 is returned.  If a new device is found then
    // its address is copied to newAddr.  Use OneWire::reset_search() to
    // start over.
    //
    // --- Replaced by the one from the Dallas Semiconductor web site ---
    //--------------------------------------------------------------------------
    // Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
    // search state.
    // Return TRUE  : device found, ROM number in ROM_NO buffer
    //        FALSE : device not found, end of search
    //
    uint8_t OneWire::search(uint8_t *newAddr)
    {
       uint8_t id_bit_number;
       uint8_t last_zero, rom_byte_number, search_result;
       uint8_t id_bit, cmp_id_bit;
    
       unsigned char rom_byte_mask, search_direction;
    
       // initialize for search
       id_bit_number = 1;
       last_zero = 0;
       rom_byte_number = 0;
       rom_byte_mask = 1;
       search_result = 0;
    
       // if the last call was not the last one
       if (!LastDeviceFlag)
       {
          // 1-Wire reset
          if (!reset())
          {
             // reset the search
             LastDiscrepancy = 0;
             LastDeviceFlag = FALSE;
             LastFamilyDiscrepancy = 0;
             return FALSE;
          }
          
          // issue the search command
          write(0xF0);
    
          // loop to do the search
          do
          {
             // read a bit and its complement
             id_bit = read_bit();
             cmp_id_bit = read_bit();
             
             // check for no devices on 1-wire
             if ((id_bit == 1) && (cmp_id_bit == 1))
                break;
             else
             {
                // all devices coupled have 0 or 1
                if (id_bit != cmp_id_bit)
                   search_direction = id_bit;  // bit write value for search
                else
                {
                   // if this discrepancy if before the Last Discrepancy
                   // on a previous next then pick the same as last time
                   if (id_bit_number < LastDiscrepancy)
                      search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
                   else
                      // if equal to last pick 1, if not then pick 0
                      search_direction = (id_bit_number == LastDiscrepancy);
    
                   // if 0 was picked then record its position in LastZero
                   if (search_direction == 0)
                   {
                      last_zero = id_bit_number;
    
                      // check for Last discrepancy in family
                      if (last_zero < 9)
                         LastFamilyDiscrepancy = last_zero;
                   }
                }
    
                // set or clear the bit in the ROM byte rom_byte_number
                // with mask rom_byte_mask
                if (search_direction == 1)
                  ROM_NO[rom_byte_number] |= rom_byte_mask;
                else
                  ROM_NO[rom_byte_number] &= ~rom_byte_mask;
    
                // serial number search direction write bit
                write_bit(search_direction);
    
                // increment the byte counter id_bit_number
                // and shift the mask rom_byte_mask
                id_bit_number++;
                rom_byte_mask <<= 1;
    
                // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
                if (rom_byte_mask == 0)
                {
                    rom_byte_number++;
                    rom_byte_mask = 1;
                }
             }
          }
          while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7
    
          // if the search was successful then
          if (!(id_bit_number < 65))
          {
             // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
             LastDiscrepancy = last_zero;
    
             // check for last device
             if (LastDiscrepancy == 0)
                LastDeviceFlag = TRUE;
    
             search_result = TRUE;
          }
       }
    
       // if no device found then reset counters so next 'search' will be like a first
       if (!search_result || !ROM_NO[0])
       {
          LastDiscrepancy = 0;
          LastDeviceFlag = FALSE;
          LastFamilyDiscrepancy = 0;
          search_result = FALSE;
       }
       for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
       return search_result;
      }
    
    #endif
    
    #if ONEWIRE_CRC
    // The 1-Wire CRC scheme is described in Maxim Application Note 27:
    // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
    //
    
    #if ONEWIRE_CRC8_TABLE
    // This table comes from Dallas sample code where it is freely reusable,
    // though Copyright (C) 2000 Dallas Semiconductor Corporation
    static const uint8_t PROGMEM dscrc_table[] = {
          0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
        157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,
         35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,
        190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
         70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,
        219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,
        101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,
        248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,
        140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
         17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
        175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
         50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
        202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,
         87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
        233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
        116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
    
    //
    // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
    // and the registers.  (note: this might better be done without to
    // table, it would probably be smaller and certainly fast enough
    // compared to all those delayMicrosecond() calls.  But I got
    // confused, so I use this table from the examples.)
    //
    uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
    {
    	uint8_t crc = 0;
    
    	while (len--) {
    		crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
    	}
    	return crc;
    }
    #else
    //
    // Compute a Dallas Semiconductor 8 bit CRC directly.
    //
    uint8_t OneWire::crc8( uint8_t *addr, uint8_t len)
    {
    	uint8_t crc = 0;
    	
    	while (len--) {
    		uint8_t inbyte = *addr++;
    		for (uint8_t i = 8; i; i--) {
    			uint8_t mix = (crc ^ inbyte) & 0x01;
    			crc >>= 1;
    			if (mix) crc ^= 0x8C;
    			inbyte >>= 1;
    		}
    	}
    	return crc;
    }
    #endif
    
    #if ONEWIRE_CRC16
    static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
    
    //
    // Compute a Dallas Semiconductor 16 bit CRC. I have never seen one of
    // these, but here it is.
    //
    unsigned short OneWire::crc16(unsigned short *data, unsigned short len)
    {
        unsigned short i;
        unsigned short crc = 0;
    
        for ( i = 0; i < len; i++) {
    	unsigned short cdata = data[len];
    
    	cdata = (cdata ^ (crc & 0xff)) & 0xff;
    	crc >>= 8;
    
    	if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) crc ^= 0xc001;
    
    	cdata <<= 6;
    	crc ^= cdata;
    	cdata <<= 1;
    	crc ^= cdata;
        }
        return crc;
    }
    #endif
    
    #endif
    
    
    OneWire  ds(12);
    //LiquidCrystal lcd(7,6,5,4,3,2);
    byte addr[8];
    String keyStatus="";
    
    void setup(void) {
      Serial.begin(115200);
      //lcd.begin(16,2);
    }
    
    void loop(void) {
      //getKeyCode();
      
      if ( !ds.search(addr)) {
          ds.reset_search();
          return;
      }
      
      
      Serial.println("=================================");
      for(int i=0;i<8;i++)
      {
        Serial.print(addr[i],HEX);
        Serial.print(" ");
      }
      Serial.println("\n=================================");
      keyStatus="ok";
      ds.reset(); 
    }
    

    one wire slave -> writer (Arduino for avr)
    Code:
    #include <inttypes.h>
    #include "pins_arduino.h"
    
    
    extern "C" {
    #include "Arduino.h"
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    }
    
    // You can exclude CRC checks altogether by defining this to 0
    #ifndef ONEWIRESLAVE_CRC
    #define ONEWIRESLAVE_CRC 1
    #endif
    
    // Select the table-lookup method of computing the 8-bit CRC
    // by setting this to 1.  The lookup table no longer consumes
    // limited RAM, but enlarges total code size by about 250 bytes
    #ifndef ONEWIRESLAVE_CRC8_TABLE
    #define ONEWIRESLAVE_CRC8_TABLE 0
    #endif
    
    #define FALSE 0
    #define TRUE  1
    
    #define ONEWIRE_NO_ERROR 0
    #define ONEWIRE_READ_TIMESLOT_TIMEOUT 1
    #define ONEWIRE_WRITE_TIMESLOT_TIMEOUT 2
    #define ONEWIRE_WAIT_RESET_TIMEOUT 3
    #define ONEWIRE_VERY_LONG_RESET 4
    #define ONEWIRE_VERY_SHORT_RESET 5
    #define ONEWIRE_PRESENCE_LOW_ON_LINE 6
    
    class OneWireSlave {
      private:
        bool recvAndProcessCmd();
        bool waitTimeSlot();
        uint8_t pin_bitmask;
        volatile uint8_t *baseReg;
        char rom[8];
      public:
        OneWireSlave(uint8_t pin);
        void setRom(char rom[8]);
        bool waitForRequest(bool ignore_errors);
        bool waitReset(uint16_t timeout_ms);
        bool waitReset();
        bool presence(uint8_t delta);
        bool presence();
        bool search();
        uint8_t sendData(char buf[], uint8_t data_len);
        uint8_t recvData(char buf[], uint8_t data_len);
        void send(uint8_t v);
        uint8_t recv(void);
        void sendBit(uint8_t v);
        uint8_t recvBit(void);
    #if ONEWIRESLAVE_CRC
        static uint8_t crc8(char addr[], uint8_t len);
    #endif
        uint8_t errno;
    };
    
    
    #define DIRECT_READ(base, mask)        (((*(base)) & (mask)) ? 1 : 0)
    #define DIRECT_MODE_INPUT(base, mask)  ((*(base+1)) &= ~(mask))
    #define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) |= (mask))
    #define DIRECT_WRITE_LOW(base, mask)   ((*(base+2)) &= ~(mask))
    #define DIRECT_WRITE_HIGH(base, mask)  ((*(base+2)) |= (mask))
    
    /* тайм слот ожидается 120 микросекунд (стандартная длина тайм-слота 60-120 micrs)
     * при компиляции с флагом -Os в цикле ожидания присутствуют следующие команды:
     * ld, ldi, and, and, or, breq, subi, sbci
     * общая продолжительность цикла составляет 10 тактов.
     * Таблицу соответствия между командами микроконтроллера и количеством тактов
     * можно найти в даташите на микроконтроллер, см. раздел
     * Instruction Set Summary в конце даташита. */
    #define TIMESLOT_WAIT_RETRY_COUNT microsecondsToClockCycles(120) / 10L
    
    OneWireSlave::OneWireSlave(uint8_t pin) {
        pin_bitmask = digitalPinToBitMask(pin);
        baseReg = portInputRegister(digitalPinToPort(pin));
    }
    
    void OneWireSlave::setRom(char rom[8]) {
    #if ONEWIRESLAVE_CRC
        for (int i=0; i<7; i++)
            this->rom[i] = rom[i];
        this->rom[7] = crc8(this->rom, 7);
    #else
        for (int i=0; i<8; i++)
            this->rom[i] = rom[i];
    #endif
    }
    
    bool OneWireSlave::waitForRequest(bool ignore_errors) {
        errno = ONEWIRE_NO_ERROR;
        for (;;) {
            if (!waitReset(0) )
                continue;
            if (!presence() )
                continue;
            if (recvAndProcessCmd() )
                return TRUE;
            else if ((errno == ONEWIRE_NO_ERROR) || ignore_errors)
                continue;
            else
                return FALSE;
        }
    }
    
    bool OneWireSlave::recvAndProcessCmd() {
        char addr[8];
    
        for (;;) {
          switch (recv() ) {
            case 0xF0: // SEARCH ROM
                search();
                return FALSE;
            case 0x33: // READ ROM
                sendData(rom, 8);
                if (errno != ONEWIRE_NO_ERROR)
                    return FALSE;
                break;
            case 0x55: // MATCH ROM
                recvData(addr, 8);
                if (errno != ONEWIRE_NO_ERROR)
                    return FALSE;
                for (int i=0; i<8; i++)
                    if (rom[i] != addr[i])
                        return FALSE;
                return TRUE;
            case 0xCC: // SKIP ROM
                return TRUE;
            default: // Unknow command
                if (errno == ONEWIRE_NO_ERROR)
                    break; // skip if no error
                else
                    return FALSE;
          }
        }
    }
    
    bool OneWireSlave::search() {
    
      uint8_t bitmask;
        uint8_t bit_send, bit_recv;
    
        for (int i=0; i<8; i++) {
            for (bitmask = 0x01; bitmask; bitmask <<= 1) {
                bit_send = (bitmask & rom[i])?1:0;
                sendBit(bit_send);
                sendBit(!bit_send);
                bit_recv = recvBit();
                if (errno != ONEWIRE_NO_ERROR)
                    return FALSE;
                if (bit_recv != bit_send)
                    return FALSE;
            }
        }
        return TRUE;
    }
    
    bool OneWireSlave::waitReset(uint16_t timeout_ms) {
      
      uint8_t mask = pin_bitmask;
        volatile uint8_t *reg asm("r30") = baseReg;
        unsigned long time_stamp;
    
        errno = ONEWIRE_NO_ERROR;
        cli();
        DIRECT_MODE_INPUT(reg, mask);
        sei();
        if (timeout_ms != 0) {
            time_stamp = micros() + timeout_ms*1000;
            while (DIRECT_READ(reg, mask)) {
                if (micros() > time_stamp) {
                    errno = ONEWIRE_WAIT_RESET_TIMEOUT;
                    return FALSE;
                }
            }
        } else
            while (DIRECT_READ(reg, mask)) {};
        time_stamp = micros() + 540;
        while (DIRECT_READ(reg, mask) == 0) {
            if (micros() > time_stamp) {
                errno = ONEWIRE_VERY_LONG_RESET;
                return FALSE;
            }
        }
        if ((time_stamp - micros()) > 70) {
            errno = ONEWIRE_VERY_SHORT_RESET;
            return FALSE;
        }
        delayMicroseconds(30);
        return TRUE;
    }
    bool OneWireSlave::waitReset() {
        return waitReset(1000);
    }
    
    bool OneWireSlave::presence(uint8_t delta) {
      uint8_t mask = pin_bitmask;
        volatile uint8_t *reg asm("r30") = baseReg;
        
        errno = ONEWIRE_NO_ERROR;
        cli();
        DIRECT_WRITE_LOW(reg, mask);
        DIRECT_MODE_OUTPUT(reg, mask);    // drive output low
        sei();
        delayMicroseconds(120);
        cli();
        DIRECT_MODE_INPUT(reg, mask);     // allow it to float
        sei();
        delayMicroseconds(300 - delta);
        if ( !DIRECT_READ(reg, mask)) {
            errno = ONEWIRE_PRESENCE_LOW_ON_LINE;
            return FALSE;
        } else
        {
            return TRUE;
        }
    }
    bool OneWireSlave::presence() {
        return presence(25);
    }
    
    uint8_t OneWireSlave::sendData(char buf[], uint8_t len) {
        uint8_t bytes_sended = 0;
    
        for (int i=0; i<len; i++) {
            send(buf[i]);
            if (errno != ONEWIRE_NO_ERROR)
                break;
            bytes_sended++;
        }
        
        
        return bytes_sended;
    }
    
    uint8_t OneWireSlave::recvData(char buf[], uint8_t len) {
        uint8_t bytes_received = 0;
        
        for (int i=0; i<len; i++) {
            buf[i] = recv();
            if (errno != ONEWIRE_NO_ERROR)
                break;
            bytes_received++;
        }
        return bytes_received;
    }
    
    void OneWireSlave::send(uint8_t v) {
        errno = ONEWIRE_NO_ERROR;
        for (uint8_t bitmask = 0x01; bitmask && (errno == ONEWIRE_NO_ERROR); bitmask <<= 1)
            sendBit((bitmask & v)?1:0);
    }
    
    uint8_t OneWireSlave::recv() {
        uint8_t r = 0;
    
        errno = ONEWIRE_NO_ERROR;
        for (uint8_t bitmask = 0x01; bitmask && (errno == ONEWIRE_NO_ERROR); bitmask <<= 1)
            if (recvBit())
                r |= bitmask;
        return r;
    }
    
    void OneWireSlave::sendBit(uint8_t v) {
        uint8_t mask = pin_bitmask;
        volatile uint8_t *reg asm("r30") = baseReg;
    
        cli();
        DIRECT_MODE_INPUT(reg, mask);
        if (!waitTimeSlot() ) {
            errno = ONEWIRE_WRITE_TIMESLOT_TIMEOUT;
            sei();
            return;
        }
        if (v & 1)
            delayMicroseconds(30);
        else {
            cli();
            DIRECT_WRITE_LOW(reg, mask);
            DIRECT_MODE_OUTPUT(reg, mask);
            delayMicroseconds(30);
            DIRECT_WRITE_HIGH(reg, mask);
            sei();
        }
        sei();
        return;
    }
    
    uint8_t OneWireSlave::recvBit(void) {
        uint8_t mask = pin_bitmask;
        volatile uint8_t *reg asm("r30") = baseReg;
        uint8_t r;
    
        cli();
        DIRECT_MODE_INPUT(reg, mask);
        if (!waitTimeSlot() ) {
            errno = ONEWIRE_READ_TIMESLOT_TIMEOUT;
            sei();
            return 0;
        }
        delayMicroseconds(30);
        r = DIRECT_READ(reg, mask);
        sei();
        return r;
    }
    
    bool OneWireSlave::waitTimeSlot() {
        uint8_t mask = pin_bitmask;
        volatile uint8_t *reg asm("r30") = baseReg;
        uint16_t retries;
    
        retries = TIMESLOT_WAIT_RETRY_COUNT;
        while ( !DIRECT_READ(reg, mask))
            if (--retries == 0)
                return FALSE;
        retries = TIMESLOT_WAIT_RETRY_COUNT;
        while ( DIRECT_READ(reg, mask))
            if (--retries == 0)
                return FALSE;
        return TRUE;
    }
    
    #if ONEWIRESLAVE_CRC
    // The 1-Wire CRC scheme is described in Maxim Application Note 27:
    // "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
    //
    
    #if ONEWIRESLAVE_CRC8_TABLE
    // This table comes from Dallas sample code where it is freely reusable,
    // though Copyright (C) 2000 Dallas Semiconductor Corporation
    static const uint8_t PROGMEM dscrc_table[] = {
          0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
        157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,
         35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,
        190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
         70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,
        219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,
        101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,
        248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,
        140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
         17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
        175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
         50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
        202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,
         87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
        233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
        116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
    
    //
    // Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
    // and the registers.  (note: this might better be done without to
    // table, it would probably be smaller and certainly fast enough
    // compared to all those delayMicrosecond() calls.  But I got
    // confused, so I use this table from the examples.)
    //
    uint8_t OneWireSlave::crc8(char addr[], uint8_t len)
    {
        uint8_t crc = 0;
    
        while (len--) {
            crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
        }
        return crc;
    }
    #else
    //
    // Compute a Dallas Semiconductor 8 bit CRC directly.
    //
    uint8_t OneWireSlave::crc8(char addr[], uint8_t len)
    {
        uint8_t crc = 0;
        
        while (len--) {
            uint8_t inbyte = *addr++;
            for (uint8_t i = 8; i; i--) {
                uint8_t mix = (crc ^ inbyte) & 0x01;
                crc >>= 1;
                if (mix) crc ^= 0x8C;
                inbyte >>= 1;
            }
        }
        return crc;
    }
    #endif
    
    #endif
    
    char romadd[8] = {0x01, 0xAD, 0xDA, 0xCE, 0x0F, 0x00, 0x00, 0x00}; 
    OneWireSlave ds(8); 
    
    
    void setup() 
    { ds.setRom(romadd); 
    
    Serial.begin(115200);
    } 
    
    void loop() 
    { ds.waitForRequest(false); }
    
    

    my code in stm8s for one wire slave writer:
    Code:
    #include"stm8s.h"
    #include <iostm8S105c6.h>
    #include <intrinsics.h>
    
    //
    //  Setup Timer 2 to generate an interrupt every 480 clock ticks (30 uS).
    //
    
    char A[64] = "1010101010101010101010101010101010101010101010101010101010101010"; // serial number to send to one wire
    //int i ;
    void SetupTimer2(char a) //40 us
    {
        TIM2_PSCR = 0x00;       //  Prescaler = 1.
        if(a == 'r') // 
        {
          TIM2_ARRH = 0x04;       //  Wait for 480.
          TIM2_ARRL = 0x38;       
        }
        else if(a == 'p')
        {
          TIM2_ARRH = 0x01;       //  High byte of 120.
          TIM2_ARRL = 0x18;       
        }
        else if(a == 'b')
        {
          TIM2_ARRH = 0x00;       //  wait for 30us.
          TIM2_ARRL = 0x3c;       
        }
        else if(a == 'c')
        {
          TIM2_ARRH = 0x00;       //  wait for 10us.
          TIM2_ARRL = 0x14;       
        }
    
       // TIM2_IER_UIE = 1;       //  Turn on the interrupts.
        TIM2_CR1_CEN = 1;       //  Finally enable the timer.
    }
    //
    //  Timer 2 Overflow handler.
    //
    
    #pragma vector = TIM2_OVR_UIF_vector
    __interrupt void TIM2_UPD_OVF_IRQHandler(void)
    {
        TIM2_SR1_UIF = 0;              //  Reset the interrupt otherwise it will fire again straight away.
        TIM1_IER_UIE = 0;
    }
    
    int i_count;
    char proc_isr;
    #pragma vector = 6
    __interrupt void EXTI_PORTB_IRQHandler(void) // B interrupt
    {
           PB_CR2 = 0x00; // disable EXTI_PORTB
           if(i_count<1)
           {
           SetupTimer2('r'); // delay_us(510);
           __enable_interrupt();
           __wait_for_interrupt();
           //__disable_interrupt();          
           PB_ODR_ODR4 = 0;//low -> presence
           PB_DDR = 0xff;
           
           SetupTimer2('p');//delay_us(140);
           
           __enable_interrupt();
           __wait_for_interrupt();
           }
           else
           if(i_count<9) // receive command from master -> 0xF0 search();
           {}
           else
           if(i_count<73) // send data bits
           {
             if(A[i_count-8] == 0)
             {
               //send 0 bit
               PB_ODR_ODR4 = 0;//low -> bit
               PB_DDR = 0xff;
               SetupTimer2('b');//delay us = 60 us
               __enable_interrupt();
               __wait_for_interrupt();
               
               // send 1 bit
               PB_ODR_ODR4 = 1;
               PB_DDR = 0x00;
               SetupTimer2('b');//delay us = 60 us
               __enable_interrupt();
               __wait_for_interrupt();
             }
             else
             {
               // send 1 bit
               PB_DDR = 0x00;
               SetupTimer2('b');//delay us = 60 us
               __enable_interrupt();
               __wait_for_interrupt();
    
               // send 0 bit
               PB_DDR = 0xff;
               SetupTimer2('b');//delay us = 60 us
               __enable_interrupt();
               __wait_for_interrupt();
               
             }
             
               PB_DDR = 0x00;
               SetupTimer2('b');//delay 30us for recv signal, do nothing.
               __enable_interrupt();
               __wait_for_interrupt();
           }
           i_count++;
           if(i_count>73)
             i_count = 0;
           //rim();
        PB_CR2 = 0x00;
    }
    
    //
    //  Main program loop.
    //
    void main()
    {
       i_count = 0;
       
       PB_ODR_ODR4 = 1;
       PB_DDR = 0x00; // porta D pin 4 input
       PB_CR1 = 0xff;         //  PB4 is pull-up input.
       PB_CR2 = 0xff;         //  PB4 is with interrupt
       EXTI_CR1_PBIS = 2;      //  Interrupt on falling edge.
       EXTI_CR2_TLIS = 0;      //  Falling edge only.
       __enable_interrupt();
        i_count = 0;
        while (1)
        {
          __wait_for_interrupt();
           PB_DDR = 0x00; // porta D pin 4 input
           PB_CR1 = 0xff;         //  PB4 is pull-up input.
           PB_CR2 = 0xff;
           EXTI_CR1_PBIS = 2;      //  Interrupt on falling edge.
           EXTI_CR2_TLIS = 0;      //  Falling edge only.
        }
    }
    
    Note: stm8s has 16 MHz frequency.
     
  7. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    OK, I've had a look at your code but it is not well documented.

    I would like to see some general documentation about how it all works, and comments at the start of each function describing what the function does, how it does it, what the parameters and return value means, and anything else that will aid understanding by a programmer who is not already familiar with the general design principles and structure of the driver.

    In my opinion, this should be a normal part of any program. If you add this documentation I will be able to help you further.
     
  8. ArFa

    ArFa

    17
    0
    Dec 7, 2010
    #include"stm8s.h"
    #include <iostm8S105c6.h>
    #include <intrinsics.h>

    char A[64] = "1010101010101010101010101010101010101010101010101010101010101010"; // serial number to send to one wire
    void SetupTimer2(char a) // this initialize the timer to count for reset, presence and bit slot time
    {
    TIM2_PSCR = 0x00; // Prescaler = 1.
    if(a == 'r') // wait reset time = 510us
    {
    TIM2_ARRH = 0x04; // High byte of 510 us.
    TIM2_ARRL = 0x38;
    }
    else if(a == 'p') // count for 120 us
    {
    TIM2_ARRH = 0x01; // High byte of 120.
    TIM2_ARRL = 0x18;
    }
    else if(a == 'b') // count for bit time = 30us
    {
    TIM2_ARRH = 0x00; // wait for 30us.
    TIM2_ARRL = 0x3c;
    }

    // TIM2_IER_UIE = 1; // Turn on the interrupts.
    TIM2_CR1_CEN = 1; // Finally enable the timer.
    }
    //
    // Timer 2 Overflow handler.
    //
    // timer will count to it's value and then will be stopped. This enables to do nothings (NOPs)
    #pragma vector = TIM2_OVR_UIF_vector
    __interrupt void TIM2_UPD_OVF_IRQHandler(void)
    {
    TIM2_SR1_UIF = 0; // Reset the interrupt otherwise it will fire again straight away.
    TIM1_IER_UIE = 0; // disable interrupt
    }

    int i_count; // counts how interrupts are coming
    #pragma vector = 6
    __interrupt void EXTI_PORTB_IRQHandler(void) // portB interrupt
    {
    PB_CR2 = 0x00; // disable EXTI_PORTB interrupt
    if(i_count<1) // if is the first interrupt then it's reset signal, so wait for 512us (reset plus recovery time) then drive bus low and wait presence time (120us)
    {

    SetupTimer2('r'); // set timer to count up to 510us
    __enable_interrupt(); // this will enable timer interrupt
    __wait_for_interrupt(); // this will wait for timer interrupt and does nothing.
    //__disable_interrupt();

    PB_ODR_ODR4 = 0;//low -> presence
    PB_DDR = 0xff; // set portB output

    SetupTimer2('p');//set timer to count up to 120us

    __enable_interrupt();
    __wait_for_interrupt();
    }
    else
    if(i_count<9) // receive command from master (8bits = 8 interrupts)
    {}
    else
    if(i_count<73) // send data bits
    {
    // if A[i_count-8] == 0 then send bit 0, after that, send its complement (like in arduino writer)
    // to send 0 bit, set pinPB4 =0, then set portB output and wait for bit time
    // to send 1 bit, set pin PB4 = 1, then set portB input (to pull-up bus) and wait bit time
    if(A[i_count-8] == 0)
    {
    //send 0 bit
    PB_ODR_ODR4 = 0;//low -> bit
    PB_DDR = 0xff;
    SetupTimer2('b');//delay us = 30 us
    __enable_interrupt();
    __wait_for_interrupt();

    // send 1 bit
    PB_ODR_ODR4 = 1;
    PB_DDR = 0x00;
    SetupTimer2('b');//delay us = 30us
    __enable_interrupt();
    __wait_for_interrupt();
    }
    else
    // if A[i_count -8] == 1 then send 1 bit and its complement
    // to send 1 bit then set portB input (to pull-up) and wait for bit time (30us)
    // to send 0 bit, set pin PB4 low, portB output and wait bit time (30us)
    {
    // send 1 bit
    PB_DDR = 0x00;
    SetupTimer2('b');//delay us = 30 us
    __enable_interrupt();
    __wait_for_interrupt();

    // send 0 bit
    PB_ODR_ODR4 = 0;
    PB_DDR = 0xff;
    SetupTimer2('b');//delay us = 30 us
    __enable_interrupt();
    __wait_for_interrupt();

    }
    // after the master received data bits, it will send back that bit, it's irrelevant to us, so we will do nothing while it's coming
    PB_DDR = 0x00;
    SetupTimer2('b');//delay 30us for recv signal, do nothing.
    __enable_interrupt();
    __wait_for_interrupt();
    }
    i_count++;
    if(i_count>73) // if there are 73 interrupts then reset the sequence
    i_count = 0; // set i_count = 0, so when other interrupt will come, it will be the reset signal and we will send the presence and other data.
    //rim();
    PB_CR2 = 0x00; // this will enable the portB interrupt
    }

    //
    // Main program loop.
    //
    void main()
    {
    i_count = 0;

    PB_ODR_ODR4 = 1; // set pin PB4 low, this will be used as one wire pin
    PB_DDR = 0x00; // porta D pin 4 input to catch interrupts
    PB_CR1 = 0xff; // PB4 is pull-up input.
    PB_CR2 = 0xff; // PB4 is with interrupt.
    EXTI_CR1_PBIS = 2; // Interrupt on falling edge.
    EXTI_CR2_TLIS = 0; // Falling edge only.
    __enable_interrupt();
    i_count = 0;
    while (1)
    {
    __wait_for_interrupt();
    }
    }

    in this link you will find the I/O port configuration summary (table 17. page 101/441)

    I'm sorry if I don't explained it well :(

    thanks in advance ...
     
  9. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    OK I'm having a look at your code.

    Your comments are very minimal. This makes it hard for me to figure out what your code is doing, because I don't know what you're trying to achieve.

    Comments on individual lines are helpful, but larger blocks of comments before functions and at the start, giving the "bigger picture", are extremely valuable to everyone apart from the person who has just written the module and has all that information in their head.

    I think a documentation block at the start, explaining the general principles of operation and how the timer and I/O pins are used, would be a great help to me, and to you, when you come back to this code in ten years and can't remember anything about it.

    What device ist the code is written to run on? You should make a note of that in the comments.

    Finally, a schematic of the one-wire interface would be helpful.
     
    Last edited: Jan 27, 2013
  10. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    There are several problems with your code. The major problem is the approach you seem to have taken is not workable.

    I need to know the exact details of the peripherals you have to work with, so I need the full part number of the device you want to use, as well as the schematic of the 1-wire interface.

    Also, why have you chosen that particular device, and do you have the option of using a different device?
     
  11. ArFa

    ArFa

    17
    0
    Dec 7, 2010
    Look, in the main function are initialization of IO ports to receive external interrupts, when external interrupt is fired, then it checks if it's first or another interrupt, if it's the first interrupt then it is reset interrupt and it remain low for 480us and goes high for 30us, so the whole reset signal width is 510us, after this delay we should send the presence signal for 120us.
    If it's 2nd to 9th (8 interrupts after reset interrupt) it does nothing because those interrupts are the master command 0xF0 (search command), after those interrupts, in every interrupt that is fired we will send one or zero bit, which are one wire ID (ibutton ID).
    In arduino it says that we should send the bit itself and it's complement.
    The whole bit signal width should be 60us, so half of that is 30us.
    To achieve these delays I've used the timer2 several initializations, so if we should wait for 510us, we initialize the timer to count up to (510*2)(hex) (I've no idea why it is so), and so on...
    So, when we send a bit to the master, we set the bus low or high (depending the value of bit we want to send), set the timer, and wait until the timer interrupt fires, this guarantees us that we've waited Xus (depending what we want to send, presence or bit signal). When timer interrupt fires, it stops the timer so it wont fire again until we don't initialize it again.

    Developing environments is IAR Embedded Workbench .
    Device type is stm8s105C6 (will act as one wire slave), gps Teltonika FM1100 or arduino (as one wire master).

    i have no option of using a different device, i should use anyhow stm8s105f6 and gps Teltonika FM1100.

    Another problem is that, gps Teltonika FM1100 (which works with one wire protocol) doesn't read the arduino slave, do you have any idea why?

    Thanks in advance
     
  12. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    Do you have a schematic diagram for the one-wire interface in the Arduino slave?

    Do you have a schematic diagram for the one-wire interface in the STM8S circuit?

    What other functions does the firmware in the STM8S module need to perform?

    What internal peripherals are available to the 1-wire slave code? Is either of the timers available?
     
    Last edited: Jan 28, 2013
  13. KrisBlueNZ

    KrisBlueNZ Sadly passed away in 2015

    8,393
    1,270
    Nov 28, 2011
    Thanks for the expanation.

    I've had a look at your code, the data sheet for the MCU, and the other information you've provided. In my opinion you are a long way from being ready to write this code.

    You do not have a specification of what you want to do with the 1-wire interface - you haven't even described your requirements in any detail. You aren't familiar with the MCU architecture. You don't have a schematic. You are way out of your depth.

    I don't say these things to be insulting or to put you down; I'm trying to help. If you want to get this project going, you need to hire someone with embedded systems design and programming experience. There is little point in me trying to help because I can't give you the type or level of help you need.
     
  14. ArFa

    ArFa

    17
    0
    Dec 7, 2010
    Anyway, thank you very much for your replies ... And I'm sorry if I've troubled you :S
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-