SPI interface to DS1306

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
ndudman
Posts: 79
Joined: 25 December 2008, 14:00 PM

SPI interface to DS1306

Post by ndudman »

Hi

Iḿ just trying to get SPI working with a DS1306... but looking again through the specs it seems that the CE is active hight to enable the device... while I understand the SPICmd is active low... ? Am I missing something, Iḿ sure Im just misunderstanding something...

I was looking at the flags for the OpenSPI() command, but didnt see what I was looking for, or understand clearly.

Thanks
Neil

p.s I got working SPI to MAX6957 and then connection to LCD so getting a little more confidence... but Im stuck on this one.
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Re: SPI interface to DS1306

Post by mikep »

ndudman wrote:Iḿ just trying to get SPI working with a DS1306... but looking again through the specs it seems that the CE is active hight to enable the device... while I understand the SPICmd is active low... ?
CE is the SPI chip select per the datasheet. I searched around and the only solution appears to be an inverter on the CS line.
ndudman wrote:I was looking at the flags for the OpenSPI() command, but didnt see what I was looking for, or understand clearly.
Most SPI chips use an active low chip select. While it is conceptually possible to add support for an active high chip select, it is probably not worth it for the small number of chips that need it.

One other thing to try is to keep CE high all the time and not worry about the chip select - it might just work.
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: SPI interface to DS1306

Post by dkinzer »

mikep wrote:One other thing to try is to keep CE high all the time and not worry about the chip select - it might just work.
I would have guessed that this strategy would work but there is an indication in the datasheet that it might not. In particular, see Figure 13, SPI Write Data Transfer. It shows an inactive state on CE after a write which is labeled tCWH. The specification table above that figure gives a minimum time for tCWH of 1uS, suggesting that CE must go inactive after a write operation.

If you don't want to add the external inverter, it appears that you can use ShiftOut() and ShiftIn() to communicate with it using the 3-wire interface method (grounding the SERMOD input). This mode requires one less I/O line, by the way, compared to SPI.

Another alternative is to use an I2C version like the DS1307. This device is in a smaller package and doesn't support all of the features of the DS1306 (like alarms, for example).
- Don Kinzer
ndudman
Posts: 79
Joined: 25 December 2008, 14:00 PM

Post by ndudman »

Thanks for the replies guys

I was just trying this ... and telling the OPENSPI cmd to use a different pin. I dont think its good, perhaps because of timming issuers or something, I was just playing around, anyway it wasnt working.

Code: Select all

Call PutPin(csPin, zxOutputHigh)
	Call SPICmd(chan, 2, cmd, 0, resp)
	Call PutPin(csPin, zxOutputLow)
I have other SPI chips so cant leave CE enabled.

Iĺl give the shiftout and shiftin ago... along the lines of the LCD_4P.bas example interface to LCD.

Thanks
Neil
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

ndudman wrote:I have other SPI chips so cant leave CE enabled.
Just to point out that any pin can be the active low chip select for a SPI device. Each SPI device requires a different chip select wire.
Mike Perks
ndudman
Posts: 79
Joined: 25 December 2008, 14:00 PM

Post by ndudman »

Ive started with the following code, to check my understanding of shiftIn/ShiftOut... am I heading in the right dirction ?

Code: Select all

sub Main()
	cmd(1) = &H01 or &H02 or &H04
	call write2wire(&H8F, cmd, 1)
	call delay(2.3)
	call read2wire(&H0F, cmd, 1)
end SUB

sub write2wire(byval addr as byte, byRef data() as byte, byval dsize as byte)
	call PutPin(pinE, 1)
	Dim i as Byte
	Call ShiftOut(pinData, pinClock, 8, addr)
	for i = 1 to dsize		
		Call ShiftOut(pinData, pinClock, 8, data(i))
	next i
	call PutPin(pinE, 0)
'~ #ifdef DEBUG
	Debug.print "write2wire "; addr; " <";data&#40;1&#41;; ">"
'~ #endif
end sub

sub read2wire&#40;byval addr as byte, byRef data&#40;&#41; as byte, byval dsize as byte&#41;
	call PutPin&#40;pinE, 1&#41;
	Dim i as Byte
	Call ShiftOut&#40;pinData, pinClock, 8, addr&#41;
	for i = 1 to dsize		
		data&#40;i&#41; = ShiftIn&#40;pinData, pinClock, 8&#41;
	next i
	call PutPin&#40;pinE, 0&#41;
'~ #ifdef DEBUG
	Debug.print "read2wire "; addr; " <";data&#40;1&#41;; ">"
'~ #endif
end sub
Thanks
Neil
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

ndudman wrote:Ive started with the following code, to check my understanding of shiftIn/ShiftOut... am I heading in the right dirction ?
There are a couple of points that need attention.
  • Although it doesn't matter in this test code, you'll eventually want to add code to Main() to initially set the CE line low.
  • You need to initially set the clock line low in Main(). This establishes the "idle" state of the shift clock.
  • The 3-wire mode of the DS1306 operates LSB first but the ShiftOut() and ShiftIn() routines operate MSB first. Sometimes, you can use FlipBits() to reverse the bit order. However, in this case the timing relative to the clock edges of the data output by the DS1306 is not compatible with the sampling timing used by ShiftIn(). Consequently, you'll have to use ShiftOutEx()/ShiftInEx(). I would suggest using a flags value of &H01 for ShiftOutEx() and &H03 for ShiftInEx().
  • Because the DS1306 begins driving the output on the falling edge of the last clock of the address, you won't be able to use a single I/O pin for DI and DO.
  • Note that for a single byte read, the timing diagram in the DS1306 datasheet shows only 15 clock cycles. The ShiftOutEx()/ShiftInEx() sequence will produce 16 clock cycles. I don't know if this will confuse the device or not.
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

dkinzer wrote:Note that for a single byte read, the timing diagram in the DS1306 datasheet shows only 15 clock cycles.
On further reflection, I believe that you should be able to use ShiftOut()/ShiftIn() with the DS1306 configured for SPI mode.
- Don Kinzer
ndudman
Posts: 79
Joined: 25 December 2008, 14:00 PM

Post by ndudman »

Thanks again Don for your reflections and help on this...I got it working using the shiftIN/OUT configured as SPI device.

Heres the code if its of any help or reference to anyone else.

Neil

Code: Select all

sub write2wire&#40;byval addr as byte, byRef d&#40;&#41; as Byte, byval dsize as byte&#41;
	call PutPin&#40;pinE, 1&#41;
	Dim i as Byte
	'~ Call ShiftOutEx&#40;pinOutData, pinClock, 8, addr, &H00 &#41;
	Call ShiftOut&#40;pinOutData, pinClock, 8, addr&#41;
	for i = 1 to dsize		
		'~ Call ShiftOutEx&#40;pinOutData, pinClock, 8, data&#40;1&#41;, &H00&#41;
		Call ShiftOut&#40;pinOutData, pinClock, 8, d&#40;i&#41;&#41;
	next i
	call PutPin&#40;pinE, 0&#41;
#ifdef DEBUG
	Dim str as String = ""
	for i = 1 to dsize
		str = str & CStrHex&#40;d&#40;i&#41;&#41;  & "," 
	next i
	Debug.print "write2wire "; CStrHex&#40;addr&#41;; ", size=";dsize;"<";str; ">"
#endif
end sub
sub read2wire&#40;byval addr as byte, byRef d&#40;&#41; as Byte, byval dsize as byte&#41;
	Dim flags as Byte = 01
	call PutPin&#40;pinE, 1&#41;
	Dim i as Byte
	'~ Call ShiftOutEx&#40;pinOutData, pinClock, 8, addr, &H00&#41;
	Call ShiftOut&#40;pinOutData, pinClock, 8, addr&#41;
	for i = 1 to dsize		
		'~ data&#40;i&#41; = ShiftInEx&#40;pinInData, pinClock, 8, &H00&#41;
		d&#40;i&#41; =  ShiftIn&#40;pinInData, pinClock, 8&#41;
	next i
	call PutPin&#40;pinE, 0&#41;
#ifdef DEBUG
	Dim str as String = ""
	for i = 1 to dsize
		str = str & CStrHex&#40;d&#40;i&#41;&#41; & "," 
	next i
	Debug.print "read2wire "; CStrHex&#40;addr&#41;; ", size=";dsize; "<";str; ">"
#endif
end sub
Post Reply