OK, I'm about half-way through coding some comms routines for the 2014. Unfortunately, I'm having trouble with the data reception aspect of things. Occasionally (like, once every ten command sequences), my receive routine desynchronizes and locks up while waiting for a start (low) pulse. The protocol is shown in the datasheet as follows: Write-1: DQ ----\ /-/----------------------------\ (1) \_________/_/ | | |\ | | | | | | DQ ----\| | | |/-/-/-/----------\ (0) \_________|_|___________/_/_/_/| |\ |< Tstrb >| | | | | |< Tdsu >|< Tdh >| | | |< Tssu >|< Tsh >| Symbol Parameter Min Typ Max Unit Tstrb Start hold, bq2014 to host 500 - - Microseconds Tdsu Data setup - - 750 Microseconds Tdh Data hold 750 - - Microseconds Tsh Stop hold 700 - - Microseconds Tssu Stop setup - - 2.25 Milliseconds (more comprehensive timing diagram on page 18 of the Bq2014 datasheet from www.ti.com) And here's my receive code: ; Read a byte from the Bq2014 BQ2014_READ: MOVLW .8 ; 8 data bits, LSB to MSB MOVWF BQLOOP CLRF BQSHIFT ; Clear the shift buffer BCF BQFLAG_TMOUT ; Clear the timeout flag BQ2014_DQ_HI ; Make sure DQ is in input mode CLRF BQTMOUTCTR ; Clear the timeout counter _BQ2014_READ_LOOP: DECFSZ BQTMOUTCTR, F ; Decrement timeout counter GOTO _BQ2014_READ_NOTMOUT ; If no timeout, keep waiting BSF BQFLAG_TMOUT ; Timeout - set flag... RETURN ; ... and exit _BQ2014_READ_NOTMOUT: ; no timeout ; * wait for start pulse CALL _BQ2014_50US_DELAY BTFSC BQ2014_DQ ; DQ high? GOTO _BQ2014_READ_LOOP ; If so, keep waiting CALL _BQ2014_1125US_DELAY ; Sample the bit at midpoint BSF STATUS, C ; Assume data bit is high BTFSS BQ2014_DQ ; Check state of DQ line BCF STATUS, C ; If low, clear carry RRF BQSHIFT, F ; Shift data in CLRF BQTMOUTCTR ; Clear the timeout counter _BQ2014_READ_WAITSTOP: ; * wait for stop pulse DECFSZ BQTMOUTCTR, F ; Decrement timeout counter GOTO _BQ2014_READ_NOSTOPTMOUT ; If no timeout, keep waiting BSF BQFLAG_TMOUT ; Timeout - set flag... RETURN ; ... and exit _BQ2014_READ_NOSTOPTMOUT: BTFSS BQ2014_DQ ; DQ high (stop)? GOTO _BQ2014_READ_WAITSTOP ; No, wait for it to go high DECFSZ BQLOOP, F ; Decrement loopvar, skip if =0 GOTO _BQ2014_WRITE_LOOP ; Keep looping MOVF BQSHIFT, W ; Copy data byte into W and exit. RETURN Can anyone see anything that I'm doing wrong or that could be done better? I added the timeouts to try and stop the code locking up completely. In the main loop, I've got a chunk of code that sends the command 0x01 ("read FLAG1 register"), reads a byte then turns an LED on if there was a time out and waits 250mS before repeating the loop. BTW, _BQ2014_50US_DELAY is a 50uS delay routine and _BQ2014_1125US_DELAY is a 1.125mS delay routine. Thanks. -- Phil. | Acorn Risc PC600 Mk3, SA202, 64MB, 6GB, philpem@dsl.pipex.com | ViewFinder, 10BaseT Ethernet, 2-slice, http://www.philpem.dsl.pipex.com/ | 48xCD, ARCINv6c IDE, SCSI ... Law of Insurance and Taxes - Whatever goes up, stays up. -- http://www.piclist.com#nomail Going offline? Don't AutoReply us! email listserv@mitvma.mit.edu with SET PICList DIGEST in the body