Trying to understand code


#1

Hi all
anybody can help me to understand what this code do ?

(defun go ()
  (with-i2c (str #x70)                    ;; slave select for writing operation
    (write-byte #x21 str)                 ;; starting address of writing  
    
    (restart-i2c str)                     ;; Why i restart for writing ? Why i dont write directly ?
    (write-byte #x81 str)                 ;; am choosing a new writing address or im writing the byte #x81
                                          ;; and in this case what is the address of register am writing
  
    (restart-i2c str)                     ;; same as first
    (write-byte #xe1 str)))

;; why the go function code is different from the set function
;; they both write a bunch of reg with some value

(defun set (hr min)                    
  (with-i2c (str #x68)
    (write-byte 0 str)
    (write-byte 0 str)
    (write-byte min str)
    (write-byte hr str)))

and now the big question
if i want to read a register
transform in some way and
write back is this a right approach ?

(with-i2c (str slave-address)
   (write-byte value-address str)
   (restart-i2c str 1)
   (let ((val (read-byte str)))
     (restart-i2c str)
     (write-byte (transform va)l str)

thanks for your time
sdb


#2

Thanks for the questions (I’ve formatted your code a bit).

I assume you’re referring to the code for the I2C clock.

The way you use with-i2c and restart-i2c depends on what your I2C device requires. In your function (go) you’re right that there would usually be no need to call restart-i2c before doing the subsequent writes, so you could just do:

(defun go ()
  (with-i2c (str #x70)
    (write-byte #x21 str)
    (write-byte #x81 str)
    (write-byte #xe1 str)))

The reason I wrote it with the restart-i2c calls is because that’s the way Adafruit do in in the code for their seven-segment display backpack, and if I remember correctly, taking them out didn’t work.

The set function writes to the DS3231 RTC chip. I made it a separate function for convenience, but yes, it’s really doing the same thing as go.

Your final example looks correct, assuming you don’t have to write the register number to the I2C device each time.

David


#3

Ok david

i ve learned that every device has an unique way of programming internal registers
and sometimes the obvious way isnt the right way (function set in clock example -> write sequentially registers )
And that i2c is only a protocol for data exchange so the right thing to do is to find a working C library code
and translate in uLisp code (function go in the same example)
=> datasheet not exhaustive or difficult to understand.

As always
thanks for your willingness

Ps: any chance to add in future version of uLisp instructions for direct manipulations of atmega registers


#4

I’ll think about your suggestion of providing direct manipulation of ATmega registers. But in the meantime you could implement what you need yourself; see:

Adding your own functions