herselmann
Joined: 31 May 2008 Posts: 7
|
Overdrive Touch Driver for Maxim/Dallas iButtons |
Posted: Sat May 31, 2008 12:02 pm |
|
|
Code: |
/***********************************************************************************
Title: 1-Wire Overdrive Speed Driver
Author: Rudolph Herselman
Orig File Name: Overdrive_Touch.c
Date: 29 December 2007
Version: 1.0
Target MCU: PIC family
Description: Driver for the Dallas/Maxim range of 1-Wire devices,
capable of operating at normal and overdrive speed
Requirments: Clock freq fast enough to generate a delay of
LESS than 0.85us (see note "Overdrive Speed" below)
Change Log:
Version Date Editor Details
---------------------------------------------------------------------------
1.0 29/12/07 R.Herselman Initial release
---------------------------------------------------------------------------
Notes:
This driver is provided as is, and no warranty is given that it is bug free
and I will not be held liable for any damages caused directly or indirectly
whilst using this driver.
Consult the app note for any copyrights pertaining to the use of this code
in commercial products.
Below are the defines used for the various time delays used in
the Maxim/Dallas 1-Wire protocol. For more information on the time
delays consult APPLICATION NOTE 126, "1-Wire Communication Through Software"
The ABC's used in the defines corrosponds to the ABC's used in the appnote,
refer to appnote for detailed explanation of their meaning.
Standard Speed:
The standard speed uses a normal "delay_us(x)" function (where x is one of the
A0-J0 defines).
Overdrive Speed:
The overdrive speed uses a "delay_cycles(x)" function (where x is one of the
A1-J1 defines) because the delays are very short. Thus the values need to be
adjusted acording to the clock freq of the micro.
As an example:
A 16F877 running at 20Mhz will have a cycle of (1/((20e6)/4)) = 0.2us
To get a delay of 7.5us we delay the micro for (7.5/0.2) cycles ~ 38,
This will yield a daley of: 38*0.2 = 7.6us
Driver has been tested on various iButtons and seems to work fine, I have not
done any real speed tests to determine the exact speed but there is definetly
an improvement in data transfer, anyone wishing to conduct such tests and post
their results are welcome.
Schematic:
Vcc
|
|
/
\
/ <---- Pullup resistor 4K7,
\ refer to datasheet/app
/ notes for alternate values
|
|
iButton touches here--> )------o---------> Any IO pin on micro
and on GND connection Remember to change the
#define for the touch_pin
***********************************************************************************/
#ifndef Touch_pin
#define Touch_Pin pin_XX //Define your touch pin here
#endif
//************ Standard Speed ******************
// Current (us) Range(us)
// Min Rec Max
#Define A0 6 // 5 5 15
#Define B0 64 // 59 64 N/A
#Define C0 60 // 60 60 120
#Define D0 10 // 8 10 N/A
#Define E0 9 // 5 9 12
#Define F0 55 // 50 55 N/A
#Define G0 0 // 0 0 0
#Define H0 480 // 480 480 640
#Define I0 70 // 63 70 78
#Define J0 410 // 410 410 N/A
//****************** Overdrive Speed ******************
// Current (cycles) Range(us) Curent(us) @ 20MHz
// Min Rec Max
#Define A1 7 // 1 1.5 1.85 1.4
#Define B1 38 // 7.5 7.5 N/A 7.6
#Define C1 38 // 7 7.5 14 7.6
#Define D1 13 // 2.5 2.5 N/A 2.6
#Define E1 3 // 0.5 0.75 0.85 0.6
#Define F1 35 // 6.75 7 N/A 7
#Define G1 13 // 2.5 2.5 N/A 2.6
#Define H1 350 // 68 70 80 70
#Define I1 42 // 7.2 8.5 8.8 8.4
#Define J1 200 // 39.5 40 N/A 40
Boolean OverDrive=False; // Global variable used to indicate overdrive status
// Overdrive = 0 -> Normal, Overdrive = 1 -> Fast
//******************************************************************************
//Function issues a reset pulse and returns TRUE if device is present
//******************************************************************************
Boolean Touch_Present()
{
Boolean Present;
if (OverDrive)
{
delay_cycles(G1);
output_low(Touch_Pin);
delay_cycles(H1);
output_float(TOUCH_PIN);
delay_cycles(I1);
present=!input(TOUCH_PIN);
delay_cycles(J1);
}
else
{
delay_us(G0);
output_low(Touch_Pin);
delay_us(H0);
output_float(TOUCH_PIN);
delay_us(I0);
present=!input(TOUCH_PIN);
delay_us(J0);
}
if(present)
return(TRUE);
else
return(FALSE);
}
//******************************************************************************
//Function writes a byte of data to the device, auto changes speed
//******************************************************************************
void touch_write_byte(BYTE data)
{
BYTE i;
if(OverDrive)
{
for(i=1;i<=8;++i)
{
if (shift_right(&data,1,0))
{
output_low(Touch_Pin);
Delay_cycles(A1);
output_float(Touch_Pin);
Delay_cycles(B1);
}
else
{
output_low(Touch_Pin);
Delay_cycles(C1);
output_float(Touch_Pin);
Delay_cycles(D1);
}
}
}
else
{
for(i=1;i<=8;++i)
{
if (shift_right(&data,1,0))
{
output_low(Touch_Pin);
Delay_us(A0);
output_float(Touch_Pin);
Delay_us(B0);
}
else
{
output_low(Touch_Pin);
Delay_us(C0);
output_float(Touch_Pin);
Delay_us(D0);
}
}
}
}
//******************************************************************************
//Function reads a byte of data from the device, auto changes speed
//******************************************************************************
BYTE touch_read_byte()
{
BYTE i,data;
if(OverDrive)
{
for(i=1;i<=8;++i)
{
output_low(TOUCH_PIN);
delay_cycles(A1);
output_float(TOUCH_PIN);
delay_cycles(E1);
shift_right(&data,1,input(TOUCH_PIN));
delay_cycles(F1);
}
}
else
{
for(i=1;i<=8;++i)
{
output_low(TOUCH_PIN);
delay_us(A0);
output_float(TOUCH_PIN);
delay_us(E0);
shift_right(&data,1,input(TOUCH_PIN));
delay_us(F0);
}
}
return(data);
}
//******************************************************************************
//Function issues a reset command, then if device is present it issues a
//Overdrive Skip ROM command [0x3C] it then checks to see if device is still
//present. So instead of calling Touch_Present() just call OverDrive_Present() it
//will do the same thing but will also automatically change the speed if needed.
//******************************************************************************
Boolean OverDrive_Present()
{
OverDrive = 0;
if (!Touch_Present())
return(False);
touch_write_byte(0x3C);
OverDrive = 1;
if (!Touch_Present())
overdrive = 0;
return (Touch_Present());
}
//******************************************************************************
//Function issues a reset command appropriate for the speed used
//******************************************************************************
void touch_reset()
{
if (OverDrive)
{
delay_cycles(G1);
output_low(TOUCH_PIN);
delay_cycles(H1);
output_float(TOUCH_PIN);
delay_cycles(I1);
delay_cycles(J1);
}
else
{
delay_us(G0);
output_low(TOUCH_PIN);
delay_us(H0);
output_float(TOUCH_PIN);
delay_us(I0);
delay_us(J0);
}
}
|
_________________ There are only 10 kinds of people, those who understand binary and those who don't. |
|