[En-Nut-Discussion] Anyone working on 1-Wire support (DS1820) for ethernut?

Mike Cornelius mikec at calldirect.com.au
Mon Feb 3 23:27:53 CET 2003


Here is a copy/past from somthing I wrote, should get you going...
Delay_us is poorly named it does NOT delay an acurate number of
microseconds.
I fine tuned the delay values using my CRO, the values in the code below
suit a 3.6864mhz clock.
The ports/bits suit my board not Ethernut as such but that should be easy to
fix.
It could do with cleaning up if you're going to use it for anything serious
but it's a start.

Good Luck,

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mike Cornelius                      Internet: mikec at calldirect.com.au
Call Direct Cellular Solutions      Phone:    +61 2 99-65-75-85
Level 1 8-22 West St North Sydney   FAX:      +61 2 99-65-75-90
NSW 2060 Australia                  URL:      http://www.calldirect.com.au
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


void Delay_us(int nDelay)
{
	while (nDelay)
	{
		asm ("nop");
		nDelay--;
	}
}

char DS1WInit(u_char nPort, u_char nBit)
{
	char r = 0;

	cbi(PORTE,nBit);	// Set port driver to 0
	sbi(DDRE,nBit);		// Set DDR to output
	Delay_us(350);		// Initialiase 1 Wire Bus 480us (actualy 486us)
	cbi(DDRE,nBit);		// Set DDR to input (release bus)
	Delay_us(55);		// Wait for presence signal 70us

	if (bit_is_clear(PINE,nBit))
		r=1;			// return device presence signal

	Delay_us(320);		// Wait for end of reset slot

	return r;
}



void DS1WOutB(u_char nPort, u_char nBit, u_char nData)
{
	char i;

	cli();
	for (i = 8; i != 0; i--)
	{
		if (nData & 1)
		{
			sbi(DDRE,nBit);		// Set DDR to output
			Delay_us(0);		// Write 1 6us (actually 8us)
			cbi(DDRE,nBit);		// Set DDR to input (release bus)
			Delay_us(41);		// End timeslot 64us
		}
		else
		{
			sbi(DDRE,nBit);		// Set DDR to output
			Delay_us(39);		// Write 0 60us (Actually
			cbi(DDRE,nBit);		// Set DDR to input (release bus)
			Delay_us(2);		// End timeslot 10us
		}
		nData >>= 1;
	}
	sei();
}

char DS1WInB(u_char nPort, u_char nBit)
{
	char i,r = 0;
	char mask;


	mask = 1 << nBit;

	cli();
	//r |= 0x80;
	for (i = 8; i != 0; i--)
	{
		r >>= 1;

		sbi(DDRE,nBit);				// Set DDR to output
		asm ("nop");
		asm ("nop");
		asm ("nop");
		asm ("nop");
		cbi(DDRE,nBit);				// Set DDR to input (release bus)
		Delay_us(0);				// Delay 6us (actually 8us)
		if (bit_is_set(PINE,nBit))
		{
			r |= 0x80;
		}
		else
		{
			r &= ~0x80;
		}
		Delay_us(44);					// End timeslot 55us
	}
	sei();
	return r;
}

unsigned char DS1WReadByte(int nPort, unsigned short nBit, unsigned short
nAddr)
{
	DS1WInit(nPort, nBit);
	DS1WOutB(nPort, nBit, nAddr);
	return DS1WInB(nPort, nBit);
	//return 0;
}

unsigned char DS1WCommand(int nPort, unsigned short nBit, unsigned short
nAddr)
{
	DS1WInit(nPort, nBit);
	DS1WOutB(nPort, nBit, nAddr);
	return 0;
}

unsigned char DS1WWriteByte(u_char nPort, u_char nBit, u_char nAddr, u_char
data)
{
	DS1WInit(nPort, nBit);
	DS1WOutB(nPort, nBit, nAddr);
	DS1WOutB(nPort, nBit, data);
	return 0;
}


void IO_DSTemp(NUTDEVICE *stream, u_char *args)
{
	char	c;

	NutPrintString_P(stream, PSTR("\r\nDS1821 Temperature Sensors\r\n"));
	NutPrintString_P(stream, PSTR("Port Temp High Low Status\r\n"));
	if (DS1WInit(PORTE, 2))
	{
		NutPrintString_P(stream, PSTR("PE2  "));

		// Read Status Byte
		c = DS1WReadByte(PORTE, 2, 0xAC);
		DS1WCommand(PORTE, 2, 0xEE);						// Start conversion

		if (c & 0x01)
		{
			while ((DS1WReadByte(PORTE, 2, 0xAC) & 0x80) == 0)	// Wait for it to
complete
				NutThreadYield();
		}

		NutPrintInteger (stream, DS1WReadByte(PORTE, 2, 0xAA), 10, 3,
(FMTFLG_ZERO));
		NutPrintString_P(stream, PSTR("  "));
		NutPrintInteger (stream, DS1WReadByte(PORTE, 2, 0xA1), 10, 3,
(FMTFLG_ZERO));
		NutPrintString_P(stream, PSTR("  "));
		NutPrintInteger (stream, DS1WReadByte(PORTE, 2, 0xA2), 10, 3,
(FMTFLG_ZERO));
		NutPrintString_P(stream, PSTR(" "));

		// Show Status Byte
		if (c & 0x01) NutPrintString_P(stream, PSTR("1SHOT "));
		else NutPrintString_P(stream, PSTR("CONT  "));
		if (c & 0x02) NutPrintString_P(stream, PSTR("POL1 "));
		else NutPrintString_P(stream, PSTR("POL0 "));
		if (c & 0x04) NutPrintString_P(stream, PSTR("TSTAT"));
		//else NutPrintString_P(stream, PSTR(""));
		NutPrintString_P(stream, PSTR("\r\n"));

		// Turn on continuous mode if off
		if (c & 0x01)
		{
			c &= ~(0x01);
			DS1WWriteByte(PORTE, 2, 0x0C, c);
		}
	}
	NutPrintFlush(stream);
}


-----Original Message-----
From: en-nut-discussion-admin at egnite.de
[mailto:en-nut-discussion-admin at egnite.de]On Behalf Of Oliver Pirdszun
Sent: Tuesday, February 04, 2003 5:38 AM
To: en-nut-discussion at egnite.de
Subject: [En-Nut-Discussion] Anyone working on 1-Wire support (DS1820)
for ethernut?



Hi,

is anyone working on an 1-Wire protocol/bus support for ethernut? I want to
access a dallas DS1820 temperature sensor.

Regards
              Oliver
_______________________________________________
En-Nut-Discussion mailing list
En-Nut-Discussion at egnite.de
http://www.egnite.de/mailman/listinfo/en-nut-discussion




More information about the En-Nut-Discussion mailing list