I2c Routines (in Assembly)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2c Routines (in Assembly)

7,369 Views
UtopiaTim
Contributor III
Hi Folks,
 
I'm using a QG8, and need to do some data transfer to one of Maxim's
digital pots via I2c.
 
Was wondering if anybody has some master routines for the QG8 written
in assembly.  I saw the ap note, but was done in C.
 
(just trying to save some time).

Thanks!
 
Tim
Labels (1)
0 Kudos
Reply
17 Replies

2,238 Views
Curt
Contributor IV
If you are needing to bit-bang the interface, try app note AN3304 and its companion for the RS08.
0 Kudos
Reply

2,238 Views
UtopiaTim
Contributor III
Hi Curt,
 
Well, I really didn't want to bit-bang the interface, just figured
somebody had some 'get byte - put byte' routines in their
bag of tricks.
 
Looks like most of the Freescale Apnotes are written in C.
 
Thanks,

Tim
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Tim,
 
Specifically what C code functions do you refer?  I suspect it shouldn't be too difficult to convert these to assembly routines, since most of the code is likely to involve writing and reading IIC registers.
 
If you use full chip simulation of the C code in the CW debugger, and examine each C instruction step by step, this will also show what assembly steps the compiler uses.  This may help if you are not familiar with C code.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
mke_et
Contributor IV
I have some '12' code that bit-bangs the I2C port. When I did a project, I was unsure if I'd use a chip variant that had the I2C hardware or not, so I hooked it up so that I could do it either way and wrote my routines in 12 assembly. Should be pretty easy to convert to 08 if you still need them.
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Tim,
 
Application note AN3291 provides C code for the use of the IIC module for a range of different MCUs, specifically to communicate with an IIC EEPROM device.  The C functions are shown in the attached file IIC_EEPROM.c.  The file IIC_EEPROM.asm is an attempt to do a similar thing in assembly.
 
Of course, the code would need to be altered to suit the digital pot device.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
RogerSchaefer
Contributor III
Hello Mac,
 
I've been struggling with trying to convert the C code from AN3291 and then I found your post.  You program worked fine, first try
 
Thank you.
 
I don't mean to seem greedy but did you also convert the read_block and write_block functions (Example 13) ?
 
Roger
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Roger,
 
The attached code attempts to implement block write and read sub-routines based on AN3291, but not using interrupts.  The code has not so far been tested.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
RogerSchaefer
Contributor III
Hello Mac,
 
Thanks for sending the IIC block read and write; I'll test them.
 
Although I said in an eariler post that the IIC_write_byte worked, I find the program hangs if it is called more than once in quick succession.  The problem is the EEPROM will not respond to anything until a write is complete.  On the second write attempt your subroutine then hangs waiting for an ACK that never comes.  I can work around the problem by putting a wait loop greater than the EEPROM "Write Cycle Time" at the end of your subroutine.  However, the EEPROM data sheet says the proper way to handle this is with "Acknowledge Polling".  I haven't worked out how to do that with 9S08 IIC module.
 
Roger
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Roger,
 
The application note AN3291 does not appear to implement acknowledge polling - but perhaps I missed it.  I agree that you will need to wait until the write process is complete before commencing a further EEPROM read or write.
 
Personally, I might consider generating a 5ms timeout period perhaps using TPM overflow interrupt, or possibly a TPM channel.  If the TPM overflow period is greater than 5ms, it may be possible to simply read the TPM count to determine whether timeout has occurred.  By using the TPM it should be possible to do other tasks (within the main loop), while waiting for the EEPROM to become ready.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
RogerSchaefer
Contributor III
Hi Mac,
 
No there was not anything in AN3291 about acknowledge polling.
 
And I did set up a TPM based wait period at the end of the write routine and I suppose that is good enough.  A polling approach would be more stylish but I can't quite see how to do it.
 
Roger
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Roger,
 
If there is any potential for code to hang during normal operation, perhaps this needs to be specifically handled, in a more general sense, prior to COP timeout occurring.  For the case if the IIC, this would involve an error exit condition should the flag not become set within a few microseconds.
 
For example, the instruction -
     BRCLR  IICIF,IICS,*      ; Wait until flag is set
 
might be replaced by the following code -
     JSR    WAIT_IICIF        ; Wait for IICF flag
     BCC    TIMEOUT           ; Error exit if timeout occurred
     ...
 
 
; WAIT FOR IICIF FLAG OR TIMEOUT
; On exit CF = 0 if timeout occurred
 
WAIT_IICF:
     LDA    #20              ; Timeout 180 cycles
WLOOP1:
     BRSET  IICIF,IICS,WEXIT ; Branch if flag is set (CF = 1)
     DBNZA  WLOOP1           ; 9-cycle loop
WEXIT:
     RTS
 
You might do a similar sub-routine for the RXACK flag, if necessary, and the result would probably be quite similar to the acknowledge polling process.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
CarlFST60L_3rd
Contributor I
For anyone actually trying to use the C code in AN3291, the application note doesn't spell out that you actually have to setup IIC_SLAVE with the required control byte. If only using one device and you have the external address tied low, just change the line of code to

const byte IIC_SLAVE = 0xA0;

If the application note had have bothered to say this, it would have certainly saved me a couple of hours of fault finding, hooking up the DSO etc. As always, I post in the hope this saves someone else wasting time due to inadequate or poor documentation. Why they didn't put an actual working example in is beyond me, or just a line that explains what IIC_SLAVE is, or maybe call it IIC_SLAVE_ADDRESS so its remotely obvious.

Also, not sure why, but I couldnt work out how to use the internal pullups on the IIC lines on the S08SH8 processor (not sure about others). Seems a bit pointless to me. Oh, and if you write to the port after setting up IIC, it seems to disable IIC or stop it from working. Didnt bother wasting time trying to find out what it was, I just init the IIC after writing to the ports.


Message Edited by CarlFST60L_3rd on 2008-10-21 08:29 AM
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Carl,


CarlFST60L_3rd wrote:

Also, not sure why, but I couldnt work out how to use the internal pullups on the IIC lines on the S08SH8 processor (not sure about others). Seems a bit pointless to me. Oh, and if you write to the port after setting up IIC, it seems to disable IIC or stop it from working. Didnt bother wasting time trying to find out what it was, I just init the IIC after writing to the ports.

The enabling or disabling of the internal pullups is applicable when the port pins are used as GPIO.  In most cases, when a peripheral such as the IIC module is enabled, the normal pin functions will be over-ridden by the module.
 
Anyway, for correct IIC operation, the external pullup resistors will need to be of substantially lower value than provided by an internal pullup.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
UtopiaTim
Contributor III
Thanks BigMac!
 
I'll give em a try. 
 
As it ends up, I have found an even cheaper part for the project, and
- darn the bad luck - it uses an SPI interface.:smileyhappy:
 
Thanks again to all!!
 
 
Tim
0 Kudos
Reply

2,238 Views
bigmac
Specialist III
Hello Tim,
 
I don't call that bad luck!  The SPI (as a master) should be faster and much simpler to use than IIC.  Well, that's my opinion . . . perhaps others will differ.
 
Regards,
Mac
 
0 Kudos
Reply

2,238 Views
Alban
Senior Contributor II
Hello,

I do agree that a SPI is far less troublesome.
It's easy to use does not have a complicated protocol: you send, you receive !

Alban.
0 Kudos
Reply

2,238 Views
UtopiaTim
Contributor III
Thanks Bigmac, 
 
I'll try that. - didn't know the CW debugger would also show the assembly equivalents.
 
Tim
 
 
 
0 Kudos
Reply