// This file has been prepared for Doxygen automatic documentation generation.
/*! \file ********************************************************************
*
* Atmel Corporation
*
* \li File:               OWISWBitFunctions.c
* \li Compiler:           IAR EWAAVR 3.20a
* \li Support mail:       avr@atmel.com
*
* \li Supported devices:  All AVRs.
*
* \li Application Note:   AVR318 - Dallas 1-Wire(R) master.
*                         
*
* \li Description:        Polled software only implementation of the basic 
*                         bit-level signalling in the 1-Wire(R) protocol.
*
*                         $Revision: 1.9 $
*                         $Date: 2010-07-09 13:34:33 $
****************************************************************************/

#include "OWIPolled.h"

#ifdef OWI_SOFTWARE_DRIVER

#include <avr/io.h>
#include <avr/interrupt.h>//before changing it was inavr.h
#include <util/delay.h>

#include "OWIBitFunctions.h"

/* not used *
void OWI_ResetPulse(unsigned char pins)
{

    OWI_PULL_BUS_LOW(pins);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    
    OWI_RELEASE_BUS(pins);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(35);
}
*/

/*! \brief Initialization of the one wire bus(es). (Software only driver)
 *  
 *  This function initializes the 1-Wire bus(es) by releasing it and
 *  waiting until any presence sinals are finished.
 *
 *  \param  pins    A bitmask of the buses to initialize.
 */
void OWI_Init(unsigned char pins)
{
    OWI_RELEASE_BUS(pins);
    // The first rising edge can be interpreted by a slave as the end of a
    // Reset pulse. Delay for the required reset recovery time (H) to be 
    // sure that the real reset is interpreted correctly.
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);//DELAY H MODE
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
}


/*! \brief  Write a '1' bit to the bus(es). (Software only driver)
 *
 *  Generates the waveform for transmission of a '1' bit on the 1-Wire
 *  bus.
 *
 *  \param  pins    A bitmask of the buses to write to.
 */

void OWI_WriteBit1(unsigned char pins)
{
    uint8_t intState;
    
    // Disable interrupts.
    intState = SREG;
    cli();//cli() to disable, sei() to enable
    
    // Drive bus low and delay.
    OWI_PULL_BUS_LOW(pins);
    _delay_us(1);
    
    // Release bus and delay.
    OWI_RELEASE_BUS(pins);
    _delay_us(80);
    
    // Restore interrupts.
    SREG=intState;
}


/*! \brief  Write a '0' to the bus(es). (Software only driver)
 *
 *  Generates the waveform for transmission of a '0' bit on the 1-Wire(R)
 *  bus.
 *
 *  \param  pins    A bitmask of the buses to write to.
 */
void OWI_WriteBit0(unsigned char pins)
{
    uint8_t intState;
    
    // Disable interrupts.
    intState = SREG;
    cli();
    
    // Drive bus low and delay.
    OWI_PULL_BUS_LOW(pins);
    _delay_us(70);
    
    // Release bus and delay.
    OWI_RELEASE_BUS(pins);
    _delay_us(30);

    // Restore interrupts.
    SREG=intState;
}

/*! \brief  Write a '0' to the bus(es). (Software only driver)
 *
 *  Generates the waveform for transmission of a '0' bit on the 1-Wire(R)
 *  bus. just for conversion in parasitic mode (different delay)
 *
 *  \param  pins    A bitmask of the buses to write to.
 */
void OWI_WriteBit0ShortRelease(unsigned char pins)
{
    uint8_t intState;

    // Disable interrupts.
    intState = SREG;
    cli();

    // Drive bus low and delay.
    OWI_PULL_BUS_LOW(pins);
    _delay_us(70);

    // Release bus and delay.
    OWI_RELEASE_BUS(pins);
    _delay_us(1);
    
    // Restore interrupts.
    SREG=intState;
}


/*! \brief  Read a bit from the bus(es). (Software only driver)
 *
 *  Generates the waveform for reception of a bit on the 1-Wire(R) bus(es).
 *
 *  \param  pins    A bitmask of the bus(es) to read from.
 *
 *  \return A bitmask of the buses where a '1' was read.
 */
unsigned char OWI_ReadBit(unsigned char pins)
{
    uint8_t intState;
    unsigned char bitsRead;
    
    // Disable interrupts.
    intState = SREG;
    cli();
    
    // Drive bus low and delay.
    OWI_PULL_BUS_LOW(pins);
    _delay_us(1); // very short down!
    
    // Release bus and delay.
    OWI_RELEASE_BUS(pins);
    _delay_us(10);
    
    // Sample bus and delay.
    bitsRead = OWI_PIN & pins;
    _delay_us(80);
    
    // Restore interrupts.
    SREG = intState;

    return bitsRead;
}


/*! \brief  Send a Reset signal and listen for Presence signal. (software
 *  only driver)
 *
 *  Generates the waveform for transmission of a Reset pulse on the 
 *  1-Wire(R) bus and listens for presence signals.
 *
 *  \param  pins    A bitmask of the buses to send the Reset signal on.
 *
 *  \return A bitmask of the buses where a presence signal was detected.
 */
unsigned char OWI_DetectPresence(unsigned char pins)
{
    uint8_t intState;
    unsigned char presenceDetected;
    
    // Disable interrupts.
    intState = SREG;
    cli();
    
    // Drive bus low and delay.
    OWI_PULL_BUS_LOW(pins);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);//DELAY H MODE
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);

    
    // Release bus and delay.
    OWI_RELEASE_BUS(pins);
    /*    
     During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus
     low for a minimum of 480μs. The bus master then releases the bus and goes into receive mode (RX).
     When the bus is released, the 5kΩ pullup resistor pulls the 1-Wire bus high. When the DS18B20 detects
     this rising edge, it waits 15μs to 60μs and then transmits a presence pulse by pulling the 1-Wire bus low
     for 60μs to 240μs.
    */
    _delay_us(65); 



    // Sample bus to detect presence signal and delay.
    presenceDetected = ((~OWI_PIN) & pins);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    _delay_us(100);
    
    // Restore interrupts.

    SREG = intState;
    
    return presenceDetected;
}


#endif
