C Code
/*******************
E128 iButton Reading function
Author: mdhill
Edited by: Taylor Penn and Michael Wittenberg
Date: 5/9/08
********************/
/*
iButton Reading Procedure
The communication with the iButton is a 1-Wire scheme.
This means that you have to dynamically change the control
port between being an input and being an output.
Remember to have a pull-up resistor on the data line.
- Set the pin as an output (OUT). Set the line low for 500usec.
Set the pin to an input (IN).
Wait approximately 50usec.
Read the pin.
If it's low, the iButton is present.
Repeat the process until the iButton is found.
- Conduct a Reset Sequence.
Set pin as OUT.
Set line low for 500usec.
Set line high for 500usec.
This Reset Sequence must be done at the beginning of any new read.
- Send the Read ROM command (0x33), LSB first.
Write a 1 by setting line low for approximately 5usec and
then set to IN for remainder of time frame (approximately 75usec total).
Write a 0 by setting line low for approximately 60usec and
then set to IN for remainder of time frame (approximately 75usec total).
- Send a Read command for each bit you wish to read.
Set line low for 5usec and then set to IN.
Read line at 15usec from beginning of setting line low.
If the line is high, the bit transmitted is a 1.
If the line is low, the bit transmitted is a 0.
Wait until end of fram (75usec from beginning of setting line low)
before issuing another Read command.
- Bytes and bits are sent LSB. If you are reading an example SN of 0x09,
then you will read bits as follows: 10010000. In our case, were are reading
the last two bytes of the SN and therefore only have to read 24 bits
instead of 64. Why 24 bits? The first 8 bits are an iButton "family code"
that is not part of the serial number.
*/
/************* #Includes ****************/
#include <stdio.h>
#include <bitdefs.h>
#include <ADS12.h>
#include "mc9s12e128.h"
//#include "TimerModule.h" // For timing functions //
#include "iButton.h"
#include "s12TIM.h"
/************* #Defines *****************/
#define IBUTTON_HI BIT5HI
#define IBUTTON_LO BIT5LO
#define IBUTTON_DDR DDRP
#define IBUTTON_PT PTP
#define HI 1
#define LO 0
#define FOUND TRUE
#define NOT_FOUND FALSE
#define _5_US 40
#define _10_US 98
#define _15_US 156
#define _50_US 562
#define _60_US 678
#define _70_US 794
#define _75_US 852
#define _500_US 5782
/*********** Function Prototypes **********/
//char PollForiButton(void);
void ResetSequence(void);
void SendReadROMCommand(void);
long ReadAddress(void);
char ReadNextBit(void);
void SetLineLO(void);
void SetLineHI(void);
void SetLineInput(void);
char ReadLine(void);
void Wait(int time);
/*********** Module Variables ************/
long SerialNumber = 0;
unsigned char Serialhighbyte = 0; //changed these two from ints to chars
unsigned char Seriallowbyte = 0;
int Serialjunk = 0;
long Serialreverse = 0;
/*********** Test Harness Switches *******/
//#define _READ_TEST
//#define _POLL_TEST
//#define _READ_BIT_TEST
#define _MAIN_LOOP
/*********** Functions ********************/
/*void main(void) {
// Init the timer module and whatnot
InitiButtonModule(); */
unsigned char GetiButtonMSB(void)
{
return Serialhighbyte;
}
unsigned char GetiButtonLSB(void)
{
return Seriallowbyte;
}
void ReadiButton(void)
{
printf("Starting ReadiButton function \r\n");
ResetSequence();
SendReadROMCommand();
// Read the address //
SerialNumber = ReadAddress();
//}
}
//#endif
void InitiButtonModule(void) {
// Initializes the timer module if it hasn't already been initialized //
//InitTimerModule();
//stole this stuff from InitTimerModule()
TIM0_TSCR1 = _S12_TEN; //Enable timer system
TIM0_TSCR2 = (_S12_PR0); //Set prescale /2 --> to 12MHz
// TIM0_TSCR2 = ~(_S12_PR0|_S12_PR1|_S12_PR2); // no prescale, we're rolling fast
// Initializing some output ports, to blip a line
//DDRT = 0xFF;
// set them to all low, just in case
//PTT = 0x00;
//printf("Finished InitiButtonModule \r\n");
return;
}
void Wait(int time)
{
static int startTime = 0;
static int nTicks = 0;
startTime = TIM0_TCNT;
while(1)
{
nTicks = TIM0_TCNT - startTime;
if (nTicks > time)
{
break;
}
}
}
char PollForiButton(void) {
// Polls for an iButton, returns FOUND or NOT_FOUND //
char Success = NOT_FOUND;
printf("Searching for iButton.......\r\n");
SetLineLO(); // Set the pin low
Wait(_500_US); // Wait 500us
SetLineInput(); // Set pin as input
Wait(_50_US); // Wait 50us
if ((IBUTTON_PT&IBUTTON_HI))
{
// keep waiting
} else
{
printf("Found an iButton\r\n");
Success = FOUND;
}
return Success;
}
void ResetSequence(void) {
// This Reset Sequence must be done at the beginning of any new read.//
printf("...INITIATING RESET\r\n");
SetLineLO();
Wait(_500_US);
SetLineHI();
Wait(_500_US);
return;
}
void SendReadROMCommand(void) {
// Send Read ROM Command: 0x33, LSB first, according to the instructions //
// * Write a 1 by setting line low for approximately 5usec and //
// then set to IN for remainder of time frame (approximately 75usec). //
// * Write a 0 by setting line low for approximately 60usec and //
// then set to IN for remainder of time frame (approximately 75usec) //
SetLineLO(); // Write a 1 //
Wait(_5_US);
SetLineInput();
Wait(_70_US);
SetLineLO(); // Write a 1 //
Wait(_5_US);
SetLineInput();
Wait(_70_US);
SetLineLO(); // Write a 0 //
Wait(_60_US);
SetLineInput();
Wait(_15_US);;
SetLineLO(); // Write a 0 //
Wait(_60_US);
SetLineInput();
Wait(_15_US);
SetLineLO(); // Write a 1 //
Wait(_5_US);
SetLineInput();
Wait(_70_US);
SetLineLO(); // Write a 1 //
Wait(_5_US);
SetLineInput();
Wait(_70_US);
SetLineLO(); // Write a 0 //
Wait(_60_US);
SetLineInput();
Wait(_15_US);
SetLineLO(); // Write a 0 //
Wait(_60_US);
SetLineInput();
Wait(_15_US);
// return;
}
long ReadAddress(void) {
/*
int i = 23;
long int Address = 0;
// Throw out the first 8 bits by shifting them right //
// off the edge and replace them with the 16 we're
// interested in, which should remain for happiness with addresses //
for (i=24; i>0; i--) { // stop reading after 24 bits
Address>>=1; // shift the bits right before the next read-assignment
if(ReadNextBit()) { // if the bit is hi
Address |= BIT15HI;
} else { // if the bit is lo
Address &= BIT15LO;
}
}
return Address;
*/
int i = 0;
int j = 0;
long int Address = 0;
// throw out the first 8
for(i=0; i<8; i++)
{
Serialjunk /= 2; // shift the bits to the right
if(ReadNextBit())
{
Serialjunk |= BIT7HI;
} else
{
// leave it low
}
}
for(j=0; j<16; j++)
{
Address /= 2; // shift the bits to the right
Serialreverse *= 2;
if (j>7)
{
Serialhighbyte /= 2;
} else
{
Seriallowbyte /= 2;
}
if(ReadNextBit())
{
if (j>7)
{
Serialhighbyte |= BIT7HI;
} else
{
Seriallowbyte |= BIT7HI;
}
Address |= BIT15HI;
Serialreverse++;
} else
{
// leave it low
}
}
return Address;
}
char ReadNextBit(void) {
// Reads the next bit from the iButton //
char bit;
SetLineLO(); // Set line low/output, wait 5us //
Wait(_5_US);
SetLineInput(); // Set line as input, wait 10us //
Wait(_10_US);
bit = ReadLine(); // read the state of the line //
Wait(_60_US); // prevent another read attempt from coming too soon //
return bit;
}
void SetLineLO(void) {
// Sets iButton pin as output, and makes it LO //
IBUTTON_DDR |= IBUTTON_HI; // Set Ibutton Line as output //
IBUTTON_PT &= IBUTTON_LO; // Set line LO //
return;
}
void SetLineHI(void) {
// Sets iButton pin as output, and makes it HI //
IBUTTON_DDR |= IBUTTON_HI; // Set Ibutton Line as output //
IBUTTON_PT |= IBUTTON_HI; // Set line HI //
return;
}
void SetLineInput(void) {
// Sets iButton pin as an input //
IBUTTON_DDR &= IBUTTON_LO; // Set Ibutton line as input //
return;
}
char ReadLine(void) {
// Reads the iButton line. Returns 1 if HI, 0 if LO //
char bit = HI;
SetLineInput(); //line is always in input when this is called // Set pin as an input //
if(!(IBUTTON_PT & IBUTTON_HI)) { // if NOT (port and bit5), the the bit is lo
bit = LO; // Isolate the bit of interest //
}
return bit;
}