EmbeddedNim / picostdlib

Nim wrapper for the raspberry pi stdlib
MIT License
73 stars 11 forks source link

I2c bus #7

Closed Martinix75 closed 3 years ago

Martinix75 commented 3 years ago

hi Jason here I am again. after having fun with usb, i would like to try to connect my I2c display. So I wanted to ask if it was possible to implement the three basic functions for I2c: i2c_init () i2c_write_blocking () i2c_read_blocking ()

I tried, but it's a little too much for me !! thanks from Andrea

https://www.youtube.com/watch?v=092xFEmAS98 here is an example of what I would like to do (about)!!!!!

beef331 commented 3 years ago

99d49c03a39a9dd74095a290f3df7fb7eff07949 added i2c, I do not have a device that uses i2c so please give it a whirl and report back.

Martinix75 commented 3 years ago

great, in these days (or next week) I start to do the tests and it will be my pleasure and honor to send you the results. Thank you

Martinix75 commented 3 years ago

I added this line to i2c (I hope it is correct!!) for now I will only be able to amndare bytes on the bus and analyze them with the oscilloscope! I don't know how long it will take, but in the meantime I work on it!

proc ic2WriteBlock*(i2c: var I2cInst,address:uint8,info:var uint8,nostop:bool) {.importC: "i2c_write_blocking".}

P.S. it would not be better to start the "proc" with the name of the library, because I am afraid that then there may be too many init() and you risk not understanding!! then proc init() --> i2cinit() For example.

Martinix75 commented 3 years ago

I did a first simple test, but while in c "i2c0" is recognized, (says whether to use block 0 or 1 on each "port") on nim is not recognized and returns an error! do I have to declare it in another way, or is something missing from the wrapper?

import picostdlib/[i2c,gpio] import picostdlib

in ...csource/CMakeLists.txt add target_link_libraries(tests pico_stdlib hardware_adc hardware_i2c) (hardware_i2c)

[# in c....

define I2C_PORT i2c0

... ... i2c_init(I2C_PORT, 40000) ]#

const I2C_PORT = i2c0 --> error!!! (my mistake, I try again on Monday )

Martinix75 commented 3 years ago

in i2c.h extern i2c_inst_t i2c0_inst; extern i2c_inst_t i2c0_inst;

define i2c0 (&i2c0_inst) ///< identifier for I"C HW Block 0

define i2c1 (&i2c1_inst) ///< identifier for I"C HW Block 1

but for me is to complex!

Martinix75 commented 3 years ago

I'm sorry, I tried all day but I can not understand things put in "I2cInst" :(( it is as if he were missing something, but out of my reach!

proc init*(i2c: var I2cInst, baudrate: cuint) {.importC: "i2c_init".}

beef331 commented 3 years ago

I wrapped those two variables so now you should be able to do

i2c0.init(yourBaudRate)
i2c0.writeBlock(args)
Martinix75 commented 3 years ago

wow !! i2c seems to work !! attached the photo of the signals on the oscilloscope. it remains only to better implement the "i2c_write_blockingk and i2c_read_blocking" (base functions) functions. I tried to test like this but I don't know how correct it is: proc i2cWriteBlock*(ic2: var I2cInst, adress:uint8, info: var uint8, lung: csize_t, nostop:bool) {.importC: "i2c_write_blocking".} SCR01

for the moment the adress is present (0x27 ok!) but the transmitted byte is missing (I think) but I will work on it again (work permitting) it's probably my proc's fault !!!

beef331 commented 3 years ago

Nice! I've also wrapped those functions for you which you should be able to use now. If you're using a sequence you'll want to do

let wrote = yourI2c.writeblocking(address, yourSeq[0].unsafeAddr, yourSeq.len * sizeof(yourSeq[0]), true)
Martinix75 commented 3 years ago

i tried to write this code (x test only !!!!)

import picostdlib/[i2c,gpio] import picostdlib

var seqx = newSeq[uint8]() seqx.add(0b10101010) #try 0x75 let a = 0x77 stdioInitAll() #is necessary for initializzate i2c const p1 = 4.Gpio const p2 = 5.Gpio const adressx = 0x27

init(i2c0,10000) p1.setFunction(I2C) p2.setFunction(I2C) p1.pullUp() p2.pullUp()

let adx = seqx[0].unsafeAddr let lenn = (seqx.len*sizeof(seqx[0]))

while true: let testI2c = i2c0.writeBlocking(adressx, adx, lenn, true)

but compilation fail, it seems it doesn't recognize the type of "let lenn = (seqx.len * sizeof (seqx [0]))". whit error: andrea@localhost:~/ProgPicoNim/tests> piconim build tests.nim pico-nim : create raspberry pi pico projects using Nim Hint: used config file '/home/andrea/bin/nim/config/nim.cfg' [Conf] Hint: used config file '/home/andrea/bin/nim/config/config.nims' [Conf] ....... /home/andrea/ProgPicoNim/tests/src/tests.nim(20, 23) Error: type mismatch: got <I2cInst, int literal(39), ptr uint8, int, bool> but expected one of: proc writeBlocking(i2c: var I2cInst; address: uint8; data: pointer; len: csize_t; noStop: bool) first type mismatch at position: 4 required type for len: csize_t but expression 'lenn' is of type: int

expression: writeBlocking(i2c0, 0x00000027, adx, lenn, true) oserr.nim(94) raiseOSError Error: unhandled exception: No such file or directory Additional info: "(\"csource/@mtests.nim.c\", \"csource/tests.c\", \"No such file or directory\")" [OSError] andrea@localhost:~/ProgPicoNim/tests>

Martinix75 commented 3 years ago

update: proc writeBlocking*(i2c: var I2cInst, address: uint8, data: pointer, len: csize_t, noStop: bool){.importc: "i2c_write_blockin".} --> "i2c_write_blocking" (G is lost!!!!!)

update2: is trange if i write: writeBlocking(i2c0,adressx, adx, 11, true) run (see the pic) if write: writeBlocking(i2c0,adressx, adx, lenn, true) where : let lenn = (seqx.len*sizeof(seqx[0])) --> return INT NOT work!!!

SCR02

update 3: I solved it by doing this: let lenn = csize_t(seqx.len*sizeof(seqx[0])) to tell the truth I had already done it, but the error on the proc (the G) made me do a thousand tests but since there was that error all the attempts failed! :) now at least the writing seems to work well! now calmly I will try to write something to drive or the display or first the PCF8574 (I / O expander)

update4 : and tonight the sending of bytes doesn't work again! and I don't know why! I'm going to drink ! : (( I'll do it all again tomorrow! now I'm tired!

Martinix75 commented 3 years ago

how scary!! this morning it works again! (when you are tired it is better to watch television !!)

Martinix75 commented 3 years ago

good! to day have make a litle scanner for i2c!! work!!

Martinix75 commented 3 years ago

this is a small example of the output of the PCF8574 (b bit) and how it varies according to the byte I send it. :)

SCR03