Help with serial interface DS1302
JonathanL
Posts: 3
Hi all,
I am having a lot of problems communicating with the DS1302 timekeeping chip. I have checked and rechecked everything to no avail, I cannot seem to get anything out of the chip (and maybe to it?). I verified my logic signals with a scope but I only have one probe at this time so I can't confirm clock timing for sure, but I am pretty sure it should be okay.
Below is a copy of my program, I'm new to assembly programming and this is my first one so sorry if it's strange or stupid, etc. What I am trying to do is clear the write protect register, write a value to the seconds register and then read that value back.
What I get is either nothing or just '1' in BYTE_INPUT, and I disconnected the chip from the SX and still got the 1 so I don't know where that comes from. If anyone can help me out, take a look at the program, etc. I would greatly appreciate it. The datasheet for the DS1302 can be found here: http://pdfserv.maxim-ic.com/en/ds/DS1302.pdf
Thanks for any time and help!!
Code:
I am having a lot of problems communicating with the DS1302 timekeeping chip. I have checked and rechecked everything to no avail, I cannot seem to get anything out of the chip (and maybe to it?). I verified my logic signals with a scope but I only have one probe at this time so I can't confirm clock timing for sure, but I am pretty sure it should be okay.
Below is a copy of my program, I'm new to assembly programming and this is my first one so sorry if it's strange or stupid, etc. What I am trying to do is clear the write protect register, write a value to the seconds register and then read that value back.
What I get is either nothing or just '1' in BYTE_INPUT, and I disconnected the chip from the SX and still got the 1 so I don't know where that comes from. If anyone can help me out, take a look at the program, etc. I would greatly appreciate it. The datasheet for the DS1302 can be found here: http://pdfserv.maxim-ic.com/en/ds/DS1302.pdf
Thanks for any time and help!!
Code:
;-------------------------- DEVICE DIRECTIVES -------------------------- DEVICE SX28,OSCHS3 DEVICE TURBO,STACKX,OPTIONX IRC_CAL IRC_SLOW RESET Initialize ;------------------------------ VARIABLES AND CONSTANTS ---------------- ; General purpose temporary registers ; Used in timing loops and temporary storage where the W ; register is inappropriate. temp1 EQU $08 temp2 EQU $09 temp3 EQU $0A ; Pins for general purpose serially-clocked communication PIN_CLOCK = 0 ; clock pin PIN_IO = 0 ; input/output pin BYTE_INPUT EQU $0B BYTE_OUTPUT EQU $0C ; DS timekeeping chip pin defintions DS_CLK EQU rc.2 ;pin 2 of port c, DS clock pin DS_IO EQU rc.1 ;pin 1 of port c, DS I/O pin DS_RST EQU rc.0 ;pin 0 of port c, DS reset (RST) pin. ; DS register address definitions (commands) ; start with seconds at 100000000 (0x80) and increment ; these are write addresses, to read add one, ex: seconds = 81h DS_REG_SECONDS = $80 DS_REG_MINUTES = $82 DS_REG_HOURS = $84 DS_REG_DATE = $86 DS_REG_MONTH = $88 DS_REG_DAY = $8A DS_REG_YEAR = $8C DS_REG_CONTROL = $8E DS_REG_CHARGE = $90 DS_REG_BURST = $BE ;---------------------------- DEBUG SETTINGS --------------------------- FREQ 400_000 WATCH BYTE_INPUT,8,UBIN ;WATCH temp3,8,UBIN ;WATCH RC.1,8,UDEC ;------------------------ INITIALIZATION ROUTINE ----------------------- Initialize ;Configure port settings mov rc, #%00000000 ;Port C output low mov !rc,#%00000000 ;Port c output direction (all pins) clr BYTE_INPUT ;---------------------------- MAIN PROGRAM ----------------------------- Main PIN_CLOCK = DS_CLK PIN_IO = DS_IO ;clear write protect register setb DS_RST mov BYTE_OUTPUT,#DS_REG_CONTROL call ByteOut mov BYTE_OUTPUT,#%00000000 call ByteOut clrb DS_RST nop ;set seconds setb DS_RST mov BYTE_OUTPUT,#DS_REG_DATE call ByteOut mov BYTE_OUTPUT,#%00001100 call ByteOut clrb DS_RST nop ;read seconds mov !rc,#%0000010 ; input redirection setb DS_RST ; set device select mov BYTE_OUTPUT,#DS_REG_DATE + 1 call ByteOut call ByteIn clrb DS_RST ;;;; SUB: ByteIn ;;;; Clocks in a byte by generating clock on PIN_CLOCK and reading clocked pin on PIN_IO and ;;;; placing it in BYTE_INPUT. Data is valid on falling clock edge. ;;;; Setup: ;;;; PIN_IO Valid port pin representing serial device IO (must be set input on tristates) ;;;; PIN_CLOCK Valid port pin representing serial device clock ;;;; BYTE_INPUT Input byte storage ByteIn mov temp1,#9 ; setup counter for 9 (8 bits/byte jmp if not zero :Nextbit djnz temp1,:Clockbit ; have we clocked in a full bit? mov temp1,#9 ; if we have, reset the counter for the next byte read ret ; if there is one, and return :Clockbit setb PIN_CLOCK ; set the clock high: 5V:70ns / 2.0V:280ns clk-data-hld clrb PIN_CLOCK ; put the clock low movb BYTE_INPUT.0,PIN_IO ; put the bit in the byte rl BYTE_INPUT ; rotate the byte to the left jmp :Nextbit ; jump to the next bit in the byte ;;;; SUB: ByteOut ;;;; Puts the register byte BYTE_OUTPUT onto the pin PIN_IO bit by bit, producing a rising edge ;;;; valid clock on PIN_CLOCK for each bit. Must be ran via a call statement. ;;;; Setup: ;;;; PIN_IO Valid port pin representing serial device IO (must be set to output on tristates) ;;;; PIN_CLOCK Valid port pin representing serial device clock ;;;; BYTE_OUTPUT Byte to be clocked out ByteOut mov temp1,#9 ; setup counter with 9 (8 bits/byte jmp if not zero) mov temp2,BYTE_OUTPUT ; save the byte output in case it was needed by caller :Nextbit djnz temp1,:Clockbit ; do we have more bits to clock out? mov temp1,#9 ; if we don't reset the counter for the next byte mov BYTE_OUTPUT,temp2 ; Put the byte back in case the caller needs it ret ; if there is one, and return :Clockbit movb PIN_IO,BYTE_OUTPUT.0 ; put the LSB of the output byte to the output pin setb PIN_CLOCK ; put the clock high clrb PIN_CLOCK ; put the clock low rr BYTE_OUTPUT ; rotate the byte to the right to get the next bit jmp :Nextbit ; jump to the next bit in the byte (if there is one)
Comments
It's just a simple clockin/clockout routine, anyone spots any obvious errors?
Thanks,
Jon
I confess I skimmed your code (so this may be dumb), but I have a question. Are you using the pull up resistors on the SX as the sole means of providing pull up to the device you're interfacing to, or does the device have active outputs that actually drive the SX inputs?
Thanks, PeterM
There were additional errors I fixed once I was actually communicating with the device regarding handling of the bits in the read byte routine. The RR instruction likes to move the carry flag around once you get to the last bit, so I had to add an extra jump if equal to stop the rotate on the last bit and manually specify move the value of the IO pin into the last bit of the byte.
Everything is working okay now, I can read all values and set them, and read to/from the extra RAM on the device, so no pull ups are required I assume (?). I have found the clock works up to about 4 MHz SX·speed at 5V·without having to insert delay loops. At 3V it works up to 1 MHz.
I will be posting up the completed code once I finish it for communicating with the clock (get/set time,·read/write ram)·in case anyone needs it. It may not be pretty or "best·pratice", but I only received the SX in the mail last week and have never before done any other assembly programming. Fun stuff!
Post Edited (JonathanL) : 1/18/2005 10:03:46 AM GMT
Glad to hear you worked the problem out.
Thanks, PeterM