simple one wire bus driver

,

verions 2, actually used by a dsp production, and it worked very well

.h file & .c file

 
/*************************************************************************** 
 * Author: OBKoro1
 * Date: 2023-05-08 22:26:35
 * LastEditors: OBKoro1
 * LastEditTime: Do not edit
 * FilePath: Do not edit
 * Description: 
 * 
 * Copyright (c) 2023 by 用户/公司名, All Rights Reserved. 
 *****************************************************************************/


#ifndef __GPIO_1WIRE_BUS_DRIVER_H__
#define __GPIO_1WIRE_BUS_DRIVER_H__

#include "CSysCfg.h"
#include "Config.h"

void Init1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio);
/****************************************************************************
 * master generate the reset signal
*****************************************************************************/
void Reset1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio);
/****************************************************************************
 * this step better generate at the callback of IRQhandler
 * once IRQ oucured slave should check and sure the rest signal.
 * return:
 *       0 : there comes the reset signal
 *       -1 : there has no reset signal
*****************************************************************************/
int8 RstCheck1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio);
/****************************************************************************
 * slave generate the response signal
 * first phase is low level 
 * and then fallowed with the high level
 * return: 
 *        none
*****************************************************************************/
void Rsp1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio);
/****************************************************************************
 * this func should call by the master after it send the reset phase
 * read and count the time  check if there comes the right rsp signal.
 * return:
 *       0 : there comes the rsp signal
 *      -1 : there has no rsp signal
*****************************************************************************/
int8 RspCheck1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio);
/****************************************************************************
 * send byte for slave, MSB sent first.
 * return:
 *        0: 写入成功
 *       -1: 写入失败
*****************************************************************************/
int8 WriteByte_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST*const  pWireGpio, const uint8_t BYTE);
/****************************************************************************
 * read byte from slave, MSB come first.
 * return:
*****************************************************************************/
int8 ReadByte_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio, uint8* const vReadValue);

#endif // !__GPIO_IIC_DRIVER__H

/******************************************************************************
 * simple one wire bus protocol
 * all this transmition start by the master reset event which followed by a responsible
 * event from slave. and then the slave should send bytes utill it finished.
 * step:
 *     1. master generate the reset GpioSignal
 *     2. slave liten and send the response signal
 *     3. slave write the bytes signal.
 * 
*******************************************************************************/

#define JBF_1WIRE_RESET_LOW_US              (750U)  /*主机启动低电平保持时间  480us ~ 960us*/
#define JBF_1WIRE_RESET_HIGH_US             (30U)    /*主机释放总线后进入读入模式等待从机发送回复帧20us ~ 40us*/
#define JBF_1WIRE_RSP_LOW_US                (85U)    /*从机响应低电平保持时间 60us ~ 120us*/
#define JBF_1WIRE_RSP_HIGH_US               (80U)    /*从机释放总线 60us ~ 120*/
#define JBF_1WIRE_WRITE_BIT_START_US        (14U)    /*从机开始写阶段强制低电平保持时间 0~15us*/
#define JBF_1WIRE_WRITE_BIT_0_US            (60U)    /*bit_0,随后高电平保持时间 60 ~ 120*/
#define JBF_1WIRE_WRITE_BIT_1_US            (60U)    /*bit_1,随后高电平保持时间 60 ~ 120*/ 
#define JBF_1WIRE_WIRE_READ_TIME            (30U)     /*主机采样电平时间点*/
#define JBF_1WIRE_WRITE_BIT_INTERVAL        (2U)     /*下一个字节写操作之间的最小间隔*/
#define JBF_1WIRE_AJUST_TIME                (100U)    /*用来做一些缓冲时间*/

#define JBF_1WIRE_STATE_CHECK(GPIO, LEVEL, COUNTER, US)                   \
    while ((JBF_GPIO_INPUT_READ(GPIO) == (LEVEL)) && ((COUNTER) <= (US))) \
    {                                                                     \
        (COUNTER)++;                                                      \
        JBF_MCU_DELAY_US();                                             \
    }

#define JBF_1WIRE_STATE_WAIT(GPIO, LEVEL, COUNTER, US)                      \
    while ((JBF_GPIO_INPUT_READ(GPIO) != (LEVEL)) && ((COUNTER) <= (US))) \
    {                                                                       \
        (COUNTER)++;                                                        \
        JBF_MCU_DELAY_US();                                                 \
    }

/****************************************************************************
 * 
 * 注意, 经测试,延时计时时发现读取操作也要占去时间的,所以延时计时时时间值可设定
 * 为原先预设值的一半,
 * exp  : 
 *      while ((JBF_GPIO_INPUT_READ(_GPIO) == 0) && (_count <= (n)))
 *      {
 *          _count ++;
 *          JBF_MCU_DELAY_US();
 *      }
 *      经测试,实际延迟效果为  n x 2 - 4 us左右。
 ****************************************************************************/
void Init1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio)
{
    DDL_ASSERT(pWireGpio);
    tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    DDL_ASSERT(pGPIO);
    JBF_GPIO_CFG_OUT_PP(pGPIO);
}
/****************************************************************************
 * master generate the reset signal
*****************************************************************************/
void Reset1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio)
{
    DDL_ASSERT(pWireGpio);
    tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    DDL_ASSERT(pGPIO);
    JBF_GPIO_CFG_OUT_PP(pGPIO);
    JBF_GPIO_OUTPUT_LOW(pGPIO);
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RESET_LOW_US); //start reset, set low for 750us,at least 480us
    JBF_GPIO_OUTPUT_HIGH(pGPIO);//release it ,wait peer dev responsing.
    JBF_MCU_DELAY_XUS(JBF_1WIRE_RESET_HIGH_US);
}
/****************************************************************************
 * this step better generate at the callback of IRQhandler
 * once IRQ oucured slave should check and sure the rest signal.
 * return:
 *       0 : there comes the reset signal
 *       -1 : there has no reset signal
*****************************************************************************/
int8 RstCheck1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio)
{
    DDL_ASSERT(pWireGpio);
    tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    DDL_ASSERT(pGPIO);

    uint16 _count = 0;
    int ret = -1;
    JBF_GPIO_CFG_MODE_IN(pGPIO);
    /*waite bus shift to low, if it's high then need to wait*/
    JBF_1WIRE_STATE_WAIT(pGPIO, JBF_GPIO_LEVEL_LOW, _count, JBF_1WIRE_AJUST_TIME);
    if (_count >= JBF_1WIRE_AJUST_TIME)
    {
        return -1; /*there is no rst signal*/
    }
    _count = 0;
    /*for normal situation, master will release to high level after JBF_1WIRE_RESET_LOW_US*/
    JBF_1WIRE_STATE_CHECK(pGPIO, JBF_GPIO_LEVEL_LOW, _count, JBF_1WIRE_RESET_LOW_US);
    if (_count >= JBF_1WIRE_RESET_LOW_US ) 
    {
        ret = -1; /* low level keeping time override*/
    }
    /*一旦检测到停止,则进入reset的higt电平阶段,应该为HIGH_US_RESET时间 */
    JBF_MCU_DELAY_XUS(JBF_1WIRE_RESET_HIGH_US); 
    if (JBF_GPIO_INPUT_READ(pGPIO))
        ret = 0; 
    else 
        ret = -1; //there master should pull up the bus line;
    return ret;
}
/****************************************************************************
 * slave generate the response signal
 * first phase is low level 
 * and then fallowed with the high level
 * return: 
 *        none
*****************************************************************************/
void Rsp1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio)
{
    DDL_ASSERT(pWireGpio);
    tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    DDL_ASSERT(pGPIO);
    JBF_GPIO_CFG_OUT_PP(pGPIO);
    JBF_GPIO_OUTPUT_LOW(pGPIO);
    JBF_MCU_DELAY_XUS(JBF_1WIRE_RSP_LOW_US);
    JBF_GPIO_OUTPUT_HIGH(pGPIO);
    JBF_MCU_DELAY_XUS(JBF_1WIRE_RSP_HIGH_US);
}
/****************************************************************************
 * this func should call by the master after it sending the reset phase
 * read and count the time  check if there comes the right rsp signal.
 * return:
 *       0 : there comes the rsp signal
 *      -1 : there has no rsp signal
*****************************************************************************/
int8 RspCheck1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio)
{
    uint16 _count = 0;
    DDL_ASSERT(pWireGpio);
    tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    DDL_ASSERT(pGPIO);

    JBF_GPIO_CFG_MODE_IN(pGPIO);
    /*wait low level signal in JBF_1WIRE_RSP_LOW_US*/
    JBF_1WIRE_STATE_WAIT(pGPIO, JBF_GPIO_LEVEL_LOW, _count, (JBF_1WIRE_AJUST_TIME));
    if (_count >= JBF_1WIRE_AJUST_TIME)
    {
        JBF_DEBUG_STRING_ERROR("rsp check phase 1\r\n");
        return -1;
    }
    _count = 0;
    /*low level keeps in JBF_1WIRE_RSP_LOW_US*/
    
    JBF_1WIRE_STATE_CHECK(pGPIO, JBF_GPIO_LEVEL_LOW, _count, JBF_1WIRE_RSP_LOW_US);
    if (_count >= JBF_1WIRE_RSP_LOW_US )
    {
        JBF_DEBUG_STRING_ERROR("rsp check phase 2\r\n");
        return -1;//超过时间了,还没拉高证明从机反馈信号错误
    }
    /*wait more JBF_1WIRE_RSP_HIGH_US then to read*/
    JBF_MCU_DELAY_XUS(JBF_1WIRE_RSP_HIGH_US);
    if (JBF_GPIO_INPUT_READ(pGPIO))
    {
        return 0;
    }else{
        JBF_DEBUG_STRING_ERROR("33333333333\r\n");
        return -1;
    }
}
/****************************************************************************
 * this func should call by the slave after it ready for sendingt Bytes 
 * read and count the time  check if there comes the right start signal.
 * return:
 *       0 : there comes the start signal
 *      -1 : there has no start signal
*****************************************************************************/
#if 1
static int8_t GetStartSignal(const tGPIO_PORT_ST* const pGPIO)
{
    uint16_t _count = 0xFFFF;
    while (_count--)
    {
        if (!JBF_GPIO_INPUT_READ(pGPIO) || (_count == 0)) /*check if there comes low level*/
            break;
    }
    if (_count == 0)
    {
        return -1;
    }
    _count = 0xFFFF;
    while (_count--)
    {
        if ((JBF_GPIO_INPUT_READ(pGPIO) || (_count == 0))) /*check if there comese high level*/
            break;
    }
    if (_count == 0)
    {
        return -1;
    }
    return 0;
} 
#endif

 

/****************************************************************************
 * slave send byte , MSB sent first.
 * return:
 *        0: 写入成功
 *       -1: 写入失败
*****************************************************************************/
int8 WriteByte_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio, const uint8 value)
{
	tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    uint8 _cnt = 0, _byte ;
    _byte = value;

    DDL_ASSERT(pWireGpio);
    DDL_ASSERT(pGPIO);

    JBF_GPIO_CFG_MODE_IN(pGPIO); /*等待主机发送读启动脉冲*/
    if (GetStartSignal(pGPIO) != 0)
    {
        JBF_DEBUG_STRING_ERROR("GetStartSignal\r\n");
        return -1;
    }

    JBF_GPIO_CFG_OUT_PP(pGPIO);/*可以开始写入了*/
    for (_cnt = 0; _cnt < 8; _cnt++)
    {
        JBF_GPIO_OUTPUT_LOW(pGPIO);
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_START_US);/*强制低电平时间  0 ~ 15us*/
      
        if (_byte & 0x80)
        {
            JBF_GPIO_OUTPUT_HIGH(pGPIO);/*写1,保持高到后续时间*/
            JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_WRITE_BIT_1_US);
        }
        else
        {
            JBF_GPIO_OUTPUT_LOW(pGPIO);/*写0,拉低到后续时间*/
            JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_WRITE_BIT_0_US);
            JBF_GPIO_OUTPUT_HIGH(pGPIO);/*释放总线*/
        }
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);/*下一个bit间隔*/
        _byte <<= 1;
    }
    return 0;
}

/****************************************************************************
 * master read byte, MSB come first.
 * return: 0: get right value,   -1: error
*****************************************************************************/
int8 ReadByte_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_ST* const pWireGpio, uint8* const vReadValue)
{
    uint8 _cnt, _byte = 0;
    uint16_t _rest_time = 0, _count = 0xFFFF;
    tGPIO_PORT_ST* pGPIO = &(pWireGpio->wire_gpio);
    DDL_ASSERT(pWireGpio);
    DDL_ASSERT(pGPIO);

    JBF_GPIO_CFG_OUT_PP(pGPIO);
    JBF_GPIO_OUTPUT_LOW(pGPIO); /*主机拉低,触发启动脉冲*/
    JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);//byte起始同步时间,给对方时间调整.
    JBF_GPIO_OUTPUT_HIGH(pGPIO); /*主机拉高,告诉发送方可以开始*/
    JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);//byte起始同步时间,给对方时间调整.
    JBF_GPIO_CFG_MODE_IN(pGPIO); /*开始接收*/
    for (_cnt = 0; _cnt < 8; _cnt++)
    {
        _byte <<= 1;
        _count = 0xFFFF;
        while (_count--)
        {
            if ((JBF_GPIO_INPUT_READ(pGPIO) == JBF_GPIO_LEVEL_LOW) || (_count == 0));/*变low后再王后续进行*/
                break;
        }
        if (_count == 0)
        {
            return -1;/*等待从机拉高恢复电平,如果一直为低,那么线路故障*/
        }
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WIRE_READ_TIME);/*30us采集点*/
        if (JBF_GPIO_INPUT_READ(pGPIO))/*如果这个时候是高则对方发送bit为1*/
        {
            _byte |= 1; /*否则为默认0*/
        }
        _rest_time = (JBF_1WIRE_WRITE_BIT_START_US + JBF_1WIRE_WRITE_BIT_0_US - JBF_1WIRE_WIRE_READ_TIME);
        JBF_MCU_DELAY_XUS(_rest_time);/*把剩下的bit时间消耗完*/
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);/*下一个bit间隔*/
        _count = 0xFFFF;
        while (_count--)
        {
            if (JBF_GPIO_INPUT_READ(pGPIO) || (_count == 0));/*等待变高对方释放总线*/
                break;
        }
        if (_count == 0)
        {
            return -1;/*等待从机拉高恢复电平,如果一直为低,那么线路故障*/
        }
    }
    *vReadValue = _byte;
    return 0;
}

 以上面的为准

/******************************************************************************
 * simple one wire bus protocol
 * all this transmition start by the master reset event which followed by a responsible
 * event from slave. and then the slave should send bytes utill it finished.
 * step:
 *     1. master generate the reset GpioSignal
 *     2. slave liten and send the response signal
 *     3. slave write the bytes signal.
 * 
*******************************************************************************/

#define JBF_1WIRE_RESET_LOW_US              (750U)  /*主机启动低电平保持时间  480us ~ 960us*/
#define JBF_1WIRE_RESET_HIGH_US             (30U)    /*主机释放总线后进入读入模式等待从机发送回复帧20us ~ 40us*/
#define JBF_1WIRE_RSP_LOW_US                (85U)    /*从机响应低电平保持时间 60us ~ 120us*/
#define JBF_1WIRE_RSP_HIGH_US               (80U)    /*从机释放总线 60us ~ 120*/
#define JBF_1WIRE_WRITE_BIT_START_US        (14U)    /*从机开始写阶段强制低电平保持时间 0~15us*/
#define JBF_1WIRE_WRITE_BIT_0_US            (60U)    /*bit_0,随后高电平保持时间 60 ~ 120*/
#define JBF_1WIRE_WRITE_BIT_1_US            (60U)    /*bit_1,随后高电平保持时间 60 ~ 120*/ 
#define JBF_1WIRE_WIRE_READ_TIME            (30U)     /*主机采样电平时间点*/
#define JBF_1WIRE_WRITE_BIT_INTERVAL        (2U)     /*下一个字节写操作之间的最小间隔*/
#define JBF_1WIRE_AJUST_TIME                (100U)    /*用来做一些缓冲时间*/

#define JBF_1WIRE_STATE_CHECK(GPIO, LEVEL, COUNTER, US)                   \
    while ((JBF_GPIO_INPUT_READ(GPIO) == (LEVEL)) && ((COUNTER) <= (US))) \
    {                                                                     \
        (COUNTER)++;                                                      \
        JBF_MCU_DELAY_US();                                               \
    }

#define JBF_1WIRE_STATE_WAIT(GPIO, LEVEL, COUNTER, US)                    \
    while ((JBF_GPIO_INPUT_READ(GPIO) != (LEVEL)) && ((COUNTER) <= (US))) \
    {                                                                     \
        (COUNTER)++;                                                      \
        JBF_MCU_DELAY_US();                                               \
    }

/****************************************************************************
 * 
 * 注意, 经测试,延时计时时发现读取操作也要占去时间的,所以延时计时时时间值可设定
 * 为原先预设值的一半,
 * exp  : 
 *      while ((JBF_GPIO_INPUT_READ(_GPIO) == 0) && (_count <= (n)))
 *      {
 *          _count ++;
 *          JBF_MCU_DELAY_US();
 *      }
 *      经测试,实际延迟效果为  n x 2 - 4 us左右。
 ****************************************************************************/
void Init1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio)
{
    tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    ASSERT(pWireGpio);
    ASSERT(pGPIO);
    JBF_GPIO_CFG_OUT_PP(pGPIO);
}
/****************************************************************************
 * master generate the reset signal
*****************************************************************************/
void Reset1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio)
{
    tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    ASSERT(pWireGpio);
    ASSERT(pGPIO);
    JBF_GPIO_CFG_OUT_PP(pGPIO);
    JBF_GPIO_OUTPUT_LOW(pGPIO);
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RESET_LOW_US); //start reset, set low for 750us,at least 480us
    JBF_GPIO_OUTPUT_HIGH(pGPIO);//release it ,wait peer dev responsing.
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RESET_HIGH_US);
}
/****************************************************************************
 * this step better generate at the callback of IRQhandler
 * once IRQ oucured slave should check and sure the rest signal.
 * return:
 *       0 : there comes the reset signal
 *       -1 : there has no reset signal
*****************************************************************************/
int8_t RstCheck1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio)
{
	  uint16_t _count = 0; 
		int ret = -1;
    tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    ASSERT(pWireGpio);
    ASSERT(pGPIO);

    JBF_GPIO_CFG_MODE_IN(pGPIO);
    /*waite bus shift to low, if it's high then need to wait*/
    JBF_1WIRE_STATE_WAIT(pGPIO, JBF_GPIO_LEVEL_LOW, _count, JBF_1WIRE_AJUST_TIME);
    if (_count >= JBF_1WIRE_AJUST_TIME)
    {
        return -1; /*there is no rst signal*/
    }
    _count = 0;
    /*for normal situation, master will release to high level after JBF_1WIRE_RESET_LOW_US*/
    JBF_1WIRE_STATE_CHECK(pGPIO, JBF_GPIO_LEVEL_LOW, _count, JBF_1WIRE_RESET_LOW_US);
    if (_count >= JBF_1WIRE_RESET_LOW_US ) 
    {
        return -1;/* low level keeping time override*/
    }
   /*一旦检测到停止,则进入reset的higt电平阶段,应该为HIGH_US_RESET时间*/
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RESET_HIGH_US);  
  
    if (JBF_GPIO_INPUT_READ(pGPIO))
        ret = 0; 
    else 
        ret = -1; //there master should pull up the bus line;
    return ret;
}
/****************************************************************************
 * slave generate the response signal
 * first phase is low level 
 * and then fallowed with the high level
 * return: 
 *        none
*****************************************************************************/
void Rsp1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio)
{
    tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    ASSERT(pWireGpio);
    ASSERT(pGPIO);
    JBF_GPIO_CFG_OUT_PP(pGPIO);
    JBF_GPIO_OUTPUT_LOW(pGPIO);
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RSP_LOW_US);
    JBF_GPIO_OUTPUT_HIGH(pGPIO);
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RSP_HIGH_US);
}
/****************************************************************************
 * this func should call by the master after it sending the reset phase
 * read and count the time  check if there comes the right rsp signal.
 * return:
 *       0 : there comes the rsp signal
 *      -1 : there has no rsp signal
*****************************************************************************/
int8_t RspCheck1Wire_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio)
{
    uint16_t _count = 0;
    tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    ASSERT(pWireGpio);
    ASSERT(pGPIO);

    JBF_GPIO_CFG_MODE_IN(pGPIO);
    /*wait low level signal in JBF_1WIRE_RSP_LOW_US*/
    JBF_1WIRE_STATE_WAIT(pGPIO, JBF_GPIO_LEVEL_LOW, _count, (JBF_1WIRE_AJUST_TIME));
    if (_count >= JBF_1WIRE_AJUST_TIME)
    {
        return -1;
    }
    _count = 0;
    /*low level keeps in JBF_1WIRE_RSP_LOW_US*/
    JBF_1WIRE_STATE_CHECK(pGPIO, JBF_GPIO_LEVEL_LOW, _count, JBF_1WIRE_RSP_LOW_US);
    if (_count >= JBF_1WIRE_RSP_LOW_US )
    {
        return -1;//超过时间了,还没拉高证明从机反馈信号错误
    }
    /*wait more JBF_1WIRE_RSP_HIGH_US then to read*/
    JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_RSP_HIGH_US);
    if (JBF_GPIO_INPUT_READ(pGPIO))
    {
        return 0;
    }else{
        JBF_DEBUG_STRING_ERROR("33333333333\r\n");
        return -1;
    }
}
/****************************************************************************
 * this func should call by the slave after it ready for sendingt Bytes 
 * read and count the time  check if there comes the right start signal.
 * return:
 *       0 : there comes the start signal
 *      -1 : there has no start signal
*****************************************************************************/
#if 1
static int8_t GetStartSignal(const tGPIO_Port_t* pGPIO)
{
    uint16_t _count = 0xFFFF;
    while (_count--)
    {
        if (!(JBF_GPIO_INPUT_READ(pGPIO))) /*check if there comes low level*/
            break;
    }
    if (_count == 0)
    {
        return -1;
    }
    _count = 0xFFFF;
    while (_count--)
    {
        if ((JBF_GPIO_INPUT_READ(pGPIO))) /*check if there comese high level*/
            break;
    }
    if (_count == 0)
    {
        return -1;
    }
    return 0;
} 
#endif

 

/****************************************************************************
 * slave send byte , MSB sent first.
 * return:
 *        0: 写入成功
 *       -1: 写入失败
*****************************************************************************/
int8_t WriteByte_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio, uint8_t value)
{
	tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    uint8_t _cnt = 0, _byte ;
    _byte = value;

    ASSERT(pWireGpio);
    ASSERT(pGPIO);

    JBF_GPIO_CFG_MODE_IN(pGPIO); /*等待主机发送读启动脉冲*/
    if (GetStartSignal(pGPIO) != 0)
    {
        JBF_DEBUG_STRING_ERROR("GetStartSignal\r\n");
        return -1;
    }

    JBF_GPIO_CFG_OUT_PP(pGPIO);/*可以开始写入了*/
    for (_cnt = 0; _cnt < 8; _cnt++)
    {
        JBF_GPIO_OUTPUT_LOW(pGPIO);
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_START_US);/*强制低电平时间  0 ~ 15us*/
        if (_byte & 0x80)
        {
            JBF_GPIO_OUTPUT_HIGH(pGPIO);/*写1,保持高到后续时间*/
            JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_WRITE_BIT_1_US);
        }
        else
        {
            JBF_GPIO_OUTPUT_LOW(pGPIO);/*写0,拉低到后续时间*/
            JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_WRITE_BIT_0_US);
            JBF_GPIO_OUTPUT_HIGH(pGPIO);/*释放总线*/
        }
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);/*JBF_1WIRE_WRITE_BIT_INTERVAL 帧间隔*/
        _byte <<= 1;
    }
    return 0;
}

/****************************************************************************
 * master read byte, MSB come first.
 * return: 0: get right value,   -1: error
*****************************************************************************/
int8_t ReadByte_CDrv1WireBus(tGPIO_1WIRE_BUS_INFO_t* pWireGpio, uint8_t* vReadValue)
{
    uint8_t _cnt, _byte = 0;
    uint16_t _rest_time = 0, _count = 0xFFFF;
    tGPIO_Port_t* pGPIO = &(pWireGpio->wire_gpio);
    ASSERT(pWireGpio);
    ASSERT(pGPIO);

    JBF_GPIO_CFG_OUT_PP(pGPIO);
    JBF_GPIO_OUTPUT_LOW(pGPIO); /*主机拉低,触发启动脉冲*/
    JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);//byte起始同步时间,给对方时间调整.
    JBF_GPIO_OUTPUT_HIGH(pGPIO); /*主机拉高,告诉发送方可以开始*/
    JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);//byte起始同步时间,给对方时间调整.
    JBF_GPIO_CFG_MODE_IN(pGPIO); /*开始接收*/
    for (_cnt = 0; _cnt < 8; _cnt++)
    {
        _byte <<= 1;
        _count = 0xFFFF;
        while (_count--)
        {
            if (JBF_GPIO_INPUT_READ(pGPIO) == JBF_GPIO_LEVEL_LOW);
                break;
        }
        if (_count == 0)
        {
            return -1;/*等待从机拉高恢复电平,如果一直为低,那么线路故障*/
        }
        JBF_MCU_DELAY_XUS_EX(JBF_1WIRE_WIRE_READ_TIME);/*等待30*/
        if (JBF_GPIO_INPUT_READ(pGPIO))/*如果这个时候是高则对方发送bit为1*/
        {
            _byte |= 1; /*否则为默认0*/
        }
        _rest_time = (JBF_1WIRE_WRITE_BIT_START_US + JBF_1WIRE_WRITE_BIT_0_US - JBF_1WIRE_WIRE_READ_TIME);
        JBF_MCU_DELAY_XUS_EX(_rest_time);/*把剩下的bit时间消耗完*/
        JBF_MCU_DELAY_XUS(JBF_1WIRE_WRITE_BIT_INTERVAL);
        _count = 0xFFFF;
        while (_count--)
        {
            if (JBF_GPIO_INPUT_READ(pGPIO));/*等待变高对方释放总线*/
                break;
        }
        if (_count == 0)
        {
            return -1;/*等待从机拉高恢复电平,如果一直为低,那么线路故障*/
        }
    }
    *vReadValue = _byte;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/loveboon1/article/details/130499142
今日推荐