Shop OBEX P1 Docs P2 Docs Learn Events
TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++ - Page 99 — Parallax Forums

TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++

1969799101102109

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-08-31 02:56
    @D.P. - you can do away with R24,24 as P8 already has resistors for LEDs and R16 is unnecessary since it is only driving the RS485's D pin. SDA already has a pullup internally and the pullup is just never needed at all on SCL since the software always drives it as an output. But obviously you can have or at least allow for these resistors if you wish.

    I take it that you are using a linear regulator direct from 12V down to 3.3V? I much prefer to drop down to 5V via a switching reg and then provide a 3.3V LDO for a faster and cleaner 3.3V. Even so I still never connect the input supply directly to a regulator but much prefer to diode isolate it then add a 100uf after the diode as this both protects against reverse polarity but also allows the reg to have its own reserve that external loads can't "steal" from, so it's like a filter.

    Now to the RS485 question - I hope you aren't actually using that ancient part number btw but as for the pins don't forget to add a pulldown to the DE line so that the RS485 chip stays in receive mode even during reset or reprogramming etc. I avoid reusing P31/30 as I like to keep them totally free for any kind of diagnostics so let's see what other pins could be used for RS485. Since you have connected to the smd pins on the rear of the module maybe you can use a couple of those pins from P8..P13 as it looks like those pins are spare seeing that there are no grounds or power on the header (if you have any headers then add a ground at least).

    Have you seen the boards that I have in these Phoenix housings? Essentially they are designed for this kind of thing plus they have RS485, switching power, puppy module expansion, 12 bicolor LED indicators, DIN rail mount of course, etc.

    If you allow for another 4 pin row behind your serial header to match my standard pinout you can have the I2C pins available, both for direct cloning or programming of the EEPROM or for an external bus.

    Here's a shot of one type of board that's been hacked a little. There is a microSD connector underneath near the front left of the photo.
    29273616061_c210c8c65e_z.jpg

  • @Peter

    Okay right on the P8 LED resistors not necessary. The power supply is a DC-DC 500ma converter from Recom. The 12v is coming from the 120VAC to 12V cabinet din mount supply. And finally the RS485 is not that part but a SP3485 that I asked about on page 86, wow page 86. Thanks for the review and clarifications. This is just a prototype board and it's in a tiny box. Will use your 8 pin header on the next go round when I splurge on more than 1.86x2.88 inches. 3 of these boards for 23.50, shipping included from Osh Park, Portland OR, responsibly made in the USA on fun purple. Now about those Tachyon Inside stickers, gonna work on something.
    112 x 200 - 27K
    112 x 200 - 27K
  • Tachyon Logging, best practices? Tachyon makes it simple to add SD Logging, just wondering about best practices to manage log files, sizes etc. Now I'm gonna have a go at writing a "simple" tail routine.
    pub appendlog    ( -- )
       " RUNTIME.TXT" FOPEN$                        --- open the file that already exists on the SD
       RW                                           --- set it to R/W
       0 APPEND                                     --- find EOF null
       >FILE                                        --- revector emit to this FILE
       .DT CR PRINT" Hello World" CR                --- put stuff in the file
       PRINT" Very important data goes here" CR  
       PRINT" 1 2 + = " 1 2 + . CR                  --- end of very important data
       FCLOSE CON                                   --- close the file and revector to the CONsole
       2DROP                                        --- drop 2 items left from FOPEN$ and APPEND  ?
    ;
    cat RUNTIME.TXT...opened at 0000.40C0 
      ok
    appendlog  ok
    cat RUNTIME.TXT...opened at 0000.40C0 
    2016/08/31 WED 12:47:05
    Hello World
    Very important data goes here
    1 2 + = 3
      ok
    appendlog  ok
    cat RUNTIME.TXT...opened at 0000.40C0 
    2016/08/31 WED 12:47:05
    Hello World
    Very important data goes here
    1 2 + = 3
    2016/08/31 WED 12:47:33
    Hello World
    Very important data goes here
    1 2 + = 3
      ok
    
    
  • MJBMJB Posts: 1,235
    @D.P
    if you work with preallocated files after some (maybe very long) time you need to stop when it's full. so a size check will help.
    Or only have the last file on SD as logfile, which can grow to 4GB.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-08-31 23:43
    FOPEN$ and APPEND both return with success flags (pointers actually) that should be checked for a failure or at least drop them immediately after you call them as it keeps things cleaner that way. You can also open a file and leave it open and just use FLUSH to make sure it is written to the card. If you are using more than one file then select the file channel you are working with using FILE ( n -- ) where n is 0 to 3.

    Appending does not update the FAT file size which would be fine for a HDD but guaranteed to eventually kill Flash based memory. However I could put in the extra code to make it update once you close the file I guess although I would leave the preallocated clusters in place. Once log files have filled they should ideally wrap-around or open a newer log file as I do in some apps. There must always be some practical limit to log file sizes since they also need to be managed when read on a PC but if you logged 64 bytes every second for every day in a year you would fill 2GBs. That's a bit much to display all on one page :) so think about wrapping and tracking or using another file. The time stamp should allow you to find the latest and oldest entries.
  • MJBMJB Posts: 1,235
    FOPEN$ and APPEND both return with success flags (pointers actually) that should be checked for a failure
    so you say APPEND gives FALSE when the file is full?
    Never tried to write so much ... yet ...
    checkig filesize won't help, if it is not written ;-)

    so writing again at start of file will put a $00 after - so APPEND will work again ..

    OR: treating the FALSE as 0 (ZERO) will do the wrap around without additional special measures ??
    Is the pointer relative to file (should be to allow 4GB files)
    or to virtual memory ...
    I am sure I can look it up - but go to bed now ...

  • Is there any chance that two cogs will try to simultaneously add logging information to the file?

    Do you need ALL the logged information, or just the most recent? If just the most recent, you could use two log files ... you could write to one up to some size limit; when it is 'full' you erase the other file and then write to it, back and Forth (so to speak). 1 GB of ASCII log information is a large chunk of data.
  • If the SD card needs to be accessed from more than one cog then it should be run in its own cog as a task. There are methods built-in to handle this although it would probably be a good idea to test these out again. But normally we only need to log from the main application cog.

    @MJB - yes, APPEND returns with FALSE if a file isn't open or it is full. I may be able to add code that checks to see if the next cluster is free such as at the end of the used memory and assign it automatically.
  • D.PD.P Posts: 790
    edited 2016-09-01 02:43
    @PaulRownTree
    Everything now runs from a single cog using keypoll and timers, hat tip Peter.
    I like the idea of ping pong between two log files, swap over at midnight or something.
    These logs are not for posterity but error checking anything that might have happened while away and the system crashed for some reason i.e. last log entry.

    @Peter, yes checking for non-zero ( also consumes the stack item) for sure, just testing the routines and was stepping through it watching the stack. And affirmative on FLUSH while keeping the current log file open as necessary. My Friend Keith who is doing the hardware design/layout and such,(hat tip to his skilz), has the prototype tanks in his living room. We've flooded the place once already and I think he's a little scared from that episode so I want some logging so he can sanity check things once and awhile himself :) I'm slowly luring him into Tachyon and Forth.
    I will use the time stamp as you say to find the latest and oldest entries.

    @MJB good night

  • D.PD.P Posts: 790
    edited 2016-09-01 15:27
    Here's how easy it is to rotate through three log files changing them at 2 am so you always have 48 hrs of logs.
    Use the Forth :) Of course Peter will probably chop this in half in size :)
    { this routine returns the current logfile name string in use }
    pub logfile@  ( -- CurrentLogFileNameString )
       LOGF C@ 
       SWITCH                                 --- select log file name
         0 case  " RUNTIME0.TXT" BREAK
         1 case  " RUNTIME1.TXT" BREAK
         2 case  " RUNTIME2.TXT" BREAK
    ; 
    
    
    { this routine opens the current logfile so CONsole output can be vectored
      make sure you call closelog after output }
    pub appendlog ( -- )
       logfile@                    --- get the current logfile string 
       FOPEN$                      --- open the file 
       IF                          --- file was opened Okay
         RW                        --- set it to R/W
         0 APPEND                  --- find EOF null
         IF                        --- file set to append Okay
           >FILE                   --- revector emit to this FILE, leave file open
         THEN                      --- make sure you call closelog
       THEN
    ;
    
    { call this routine after a call to appendlog }
    pub closelog    ( -- ) 
        CR FCLOSE CON              --- close the file and revector to the CONsole
    ;
    
    { this routine switches the logs files at 2 am, call this routine in the keypoll loop }
    pub ?switchlog
    
    { this routine switches the logs files at 2 am, call this routine in the keypoll loop }
    pub ?switchlog
       TIME@  #2.00.00 =                                               --- is it 2 am ? 
       IF
         LOGF C@ 1+ 3 MOD LOGF C!                                      --- wrap it around from 0 - 2,  hat tip Peter
         logfile@  -FERASE                                             --- erase the now current logfile
         100 ms                                                        --- SDCard needs a rest
         appendlog .DT ."  Log File Change " CR CR closelog            --- write entry in new log
         1 second                                                      --- delay to make sure we only call this once   
       THEN
    ;
    
    

    Updated Source
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-09-01 08:41
    Try LOGF C@ 1+ 3 MOD LOGF C! to increment and wrap it. :)
    Otherwise show em how it's done and keep em coming!

    Alternatively just increment LOGF and do the 3 MOD when you go to use it.
  • D.PD.P Posts: 790
    edited 2016-09-02 17:20
    @Peter,
    Before I release some magic smoke from THIS SN75HVD08P RS485 chip or the P8 module let me review my setup. First time gitters.

    Bus power 3.3V
    TE /RE tied together -> prop pin P2 in my case on both the slave and master
    D R tied together with a 10K pulldown ? -> prop pin P20 in my case on both the slave and master

    A B I know what to do with but what about the value of the terminating resistor for just a simple two node system, 150ohm ?
    20 2 1,000,000 5 PPCFG   --- on the master
    20 2 1,000,000 6 PPCFG   --- on the slave
    
  • TE/RE with 10k pulldown plus 1k in R to D to the I/O or just combine R D then 1k to I/O

    120R is the standard terminator value to use.
  • D.PD.P Posts: 790
    edited 2016-09-03 01:10
    TE/RE with 10k pulldown plus 1k in R to D to the I/O or just combine R D then 1k to I/O

    120R is the standard terminator value to use.

    on one p8 module it works great and and on the other module after I issue a PPCFG it hangs trying to reboot? After a hard restart then I have no serial console and must rebuild again? The units are not yet wired together. Gonna quadruple check wiring, using the same pins etc on both modules. Both modules are using the same source also.
    17:23:39  End of source code, 2645 lines processed and 0000 errors found
    Load time = 0.000us
    MODULES LOADED:
    1800: EXTEND.fth          Primary extensions to TACHYON kernel - 160828-1400
    
    VER:    Propeller .:.:--TACHYON--:.:. Forth V3.0 JUNO 300160819.2230
    PCB:    UNKNOWN (0)
    FREQ:   96MHZ (PLLEN OSCEN XTAL1  PLL16X)
    NAMES:  $5AE4...74DC for 6,648 bytes (+4,007)
    CODE:   $0930...37E5 for 11,957 bytes (+8,165)
    RAM:    8,959 bytes free
    BUILD:  FIRMWARE BUILD DATE 160902:170543   BOOTS:  0   runtime 0
    BOOT:   EXTEND.boot ok
      ok
      ok
    ?BACKUP DATE@ build.date E! TIME@ build.time E!  ok
      ok
    20 2 1,000,000 6 PPCFG  ok
      ok
      ok
      ok
    reboot
    

    Another rebuild attempt and hang after power cycle?
      Propeller .:.:--TACHYON--:.:. Forth V3.0 JUNO 300160819.2230
    
    VER:    Propeller .:.:--TACHYON--:.:. Forth V3.0 JUNO 300160819.2230
    PCB:    UNKNOWN (0)
    FREQ:   96MHZ (PLLEN OSCEN XTAL1  PLL16X)
    NAMES:  $5AE4...74DC for 6,648 bytes (+4,007)
    CODE:   $0930...37E5 for 11,957 bytes (+8,165)
    RAM:    8,959 bytes free
    BUILD:  FIRMWARE BUILD DATE 160902:173526   BOOTS:  3   runtime 37
    BOOT:   EXTEND.boot
    MODULES LOADED:
    1800: EXTEND.fth          Primary extensions to TACHYON kernel - 160828-1400
    ROMS
    0848 VGA32x15
    0236 HSSERIAL
    1648 SIDEMU
    1940 QUADUART
    0196 MONO16
    1900 F32
    ----------------------------------------------------------------
    20 2 1,000,000 23 PPCFG  ok
    .PPCFG #23 @1,000,000 TR/TE=20/2 ok
      ok
      ok
    

    UPDATE: hum if I hold ^C down I get some of this goodness and then the console will at least echo the keyboard.
    Going to try a different chip.
    Ãàààààààààààààààà
    
    chip removed still the same
  • Okay something is not right here.

    On the working module CONNECT is not recognized and I can't find it in EXTEND.FTH or the Kernel, confusion setting in, time for food.
      Propeller .:.:--TACHYON--:.:. Forth V3.0 JUNO 300160819.2230
    
    VER:    Propeller .:.:--TACHYON--:.:. Forth V3.0 JUNO 300160819.2230
    PCB:    P5555 +P8 Only (5555)
    FREQ:   96MHZ (PLLEN OSCEN XTAL1  PLL16X)
    NAMES:  $71B0...74DC for 812 bytes (4,294,961,395)
    CODE:   $0930...4D59 for 17,449 bytes (+5,404)
    RAM:    9,303 bytes free
    BUILD:  FIRMWARE BUILD DATE 160804:180000   BOOTS:  14   runtime 100
    BOOT:
    MODULES LOADED:
    383D: EASYFILE.fth        SD card  + FAT32 Virtual Memory Access File System Layer V1.2 16080711-2300
    1800: EXTEND.fth          Primary extensions to TACHYON kernel - 160828-1400
    37E5: P8Only.fth          P8 Only HARDWARE DEFINITIONS 160823.1800
    ROMS
    0848 VGA32x15
    0236 HSSERIAL
    1648 SIDEMU
    1940 QUADUART
    0196 MONO16
    1900 F32
    ----------------------------------------------------------------
      ok
      ok
      ok
      ok
    .PPCFG #5 @1,000,000 TR/TE=20/2 ok
    6 CONNECT ???
    
  • I haven't written a ping-pong master for the P1 yet as I have been doing all my testing from the P2. That is also one of the reasons I incorporated binary ROMS in Tachyon so that I could task a cog as a master which needs a channel separate from the ping-pong driver as that driver is tied in with the console serial buffers.
  • I haven't written a ping-pong master for the P1 yet as I have been doing all my testing from the P2. That is also one of the reasons I incorporated binary ROMS in Tachyon so that I could task a cog as a master which needs a channel separate from the ping-pong driver as that driver is tied in with the console serial buffers.

    The last line explains my misunderstanding and results. Is there a way to jail break a slave so it is free to respond again on 31/30? Funny that one board works between reboots and the other does not.
  • PPP is designed to mirror the console and uses the same receive buffer in exactly the same manner as well. To run as a master it can't really use what is essentially a slave version of PPP. I just need to repackage that code to run in its own cog as a master. The slave should always respond on the console port pins P31/30 as long as the bus is not is busy but just make sure that your RS485 chips are true fail-safe in that the receive data idles high while the bus is not driven etc.
  • D.PD.P Posts: 790
    edited 2016-09-03 15:52
    PPP is designed to mirror the console and uses the same receive buffer in exactly the same manner as well. To run as a master it can't really use what is essentially a slave version of PPP. I just need to repackage that code to run in its own cog as a master. The slave should always respond on the console port pins P31/30 as long as the bus is not is busy but just make sure that your RS485 chips are true fail-safe in that the receive data idles high while the bus is not driven etc.

    Yes the chips above are true failsafe. And THIS sipex part is the other failsafe chip I have. You need a whole cog? Well my application only has 6 left, what to do what to do :) Okay I can help test... when you cycle around and get to the P1 master stuff. Everything else new in the application ( logging, colored status indication lights ) is peachy. DEADBEEF in DEADBEEF out. Enjoy your Sunday.



  • PaulRowntreePaulRowntree Posts: 150
    edited 2016-09-05 01:20
    I2C troubles with an AdaFruit BNO055 IMU module

    I have hooked up this module to a Tachyon 2.7 board, and using Forth codes that seem to work well with other I2C devices, is giving odd ack results
    %0101001_0  == BNO055_A      \ default I2C address = 0x29
    %0101000_0  == BNO055_B      \ so called 'alternative address'  = 0x28
    BNO055_B == BNO055         \ this is what is actually used as a device address
    \
    pub I2Creg@ ( register base_add -- value )
        DUP 1+ -ROT
        I2CSTART I2C!? . SPACE 1 ms I2C!? . SPACE I2CSTART  1 ms I2C!? . SPACE CR 1 I2C@ I2CSTOP ;
    
    pub BNO055reg@ ( register -- value )
        BNO055 I2Creg@ ;
    
    
    BNO055_B TO BNO055  ok
    BNO055 .BYTE 50 ok
    0 BNO055reg@ . 0 -1 0
    127 ok
    
    The three I2C!? calls give 0 -1 0 respectively 99% of the time, 0 -1 -1 in all other cases; I gather this means that the write of the device address is working [0], but the write of the register index is failing [-1]. I get the same result no matter which register I try to read (reg 0 should give $A0 as chip ID). The 1 ms delay was added to see if timing was the issue, it behaves identically without the delays.

    With the module removed the three I2C!? calls give -1 -1 -1 no matter what address, no matter what register.

    Does anyone have any ideas where this could be going wrong?
    Cheers!
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-09-05 01:19
    I2C troubles with an AdaFruit BNO055 IMU module

    I have hooked up this module to a Tachyon board, and using Forth codes that seem to work well with other I2C devices, is giving odd ack results
    %0101001_0  == BNO055_A      \ default I2C address = 0x29
    %0101000_0  == BNO055_B      \ so called 'alternative address'  = 0x28
    BNO055_B == BNO055         \ this is what is actually used as a device address
    \
    pub I2Creg@ ( register base_add -- value )
        DUP 1+ -ROT
        I2CSTART I2C!? . SPACE 1 ms I2C!? . SPACE I2CSTART  1 ms I2C!? . SPACE CR 1 I2C@ I2CSTOP ;
    

    I2CSTART was changed a few weeks back so that it would automatically check to see if the bus was busy from another process but it would nonetheless time out. If you want to do an I2C restart just use I2CREST instead.

    COM3 actually becomes the sub-address pin A0 so when it is high then the I2C address is $52 (8-bit format) and as COM3 has an internal pull-up then this is actually the default address which is why they refer to $50 as the "alternative" address.

    Everything looks fine in your code though so try this general IMU register fetch code along with the IMU control word for DUMP
    pub IMU@ ( reg -- byte )  I2CSTART $50 I2C! I2C! I2CREST $51 I2C! 1 I2C@ I2CSTOP ;
    pub IMU   ' IMU@ dmm W! ;
    

    Now just do a 0 $80 IMU DUMP to see the contents of the IMU. Use PAGE to select either page:
    pub IMU! ( byte reg -- ) I2CSTART $50 I2C! I2C! I2C! I2CSTOP ;
    pub PAGE ( page -- ) 7 IMU! ;
    
  • Thanks Peter, I will try the new code ... do I need to move to T3.0 for this ?
    The addressing of this module is very poorly documented. THe schematics show COM3 tied to ground by a resistor, which should go to $50 as you say. I tied the pin to ground to be sure ... $28 1 SHL give $50.
    *** there is some discussion on the Adafruit forum of BNO055 problems, and it seems to be related to clock stretching. The manual for the Bosch chip says that the device uses stretching. I have read your comments on Clock stretching elsewhere ... it seems that this device uses it because it is micro based ?

    If clock stretching is required, am I going to have to find a different IMU?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-09-05 03:57
    Table 4.6 of the DS says that COM3 has a 40k pull-up, therefore the default address of $52. I see in section 4.6 that it does confirm that it uses clock stretching and I2C allows for this especially from the early days of I2C in the 80's when micros were slow and had to slow down the bus at times to keep up but I have never seen any chip actually ever implement it, until now..... The Tachyon drivers simply drive the clock line in push-pull without worrying about an aberrant chip but for this chip it would need another version of I2C@ as I guess that would be the only part that needs to worry about stretching as the micro may need time to access the data before being able to respond. In this case you should make sure you have a pull-up on SCL. I will look at this code a little later and update EXTEND as well as posting it here.

    You shouldn't really need V3 but I would always recommend it as there is never any good reason to stay with an older versions especially since EXTEND and other modules are usually upgraded and tested for the latest version.

    btw, The address is only 7-bits but some manufacturers represent this as a right-justified hex byte (%0011000x -> $28) whereas I use the traditional 8-bit format/representation as that is also the byte that is actually used.

  • The address descriptions are odd ... Bosch DS shows the chip ties COM3 to + with 20-60 K, as you say, so that x29 is the default 7-bit address.

    But then Adafruit says ..

    ADR: Set this pin low to change the default I2C address for the BNO055 if you need to connect
    two ICs on the same I2C bus. The default address is 0x28. If this pin is connected to 3V, the
    address will be 0x29

    The Adafruit schematic shows the ADR pin is COM3 via a smaller 10K resistor to ground on their module, so that the Adafruit module'sdefault is x28. Still, the first line of Adafruit's description seems wrong to me, since it is already tied low on their module.

    Anyway, I will bite into V3 tomorrow. I have a Polulu IMU that has the same pinouts as the BNO055, but it needs more code space to do the trig stuff and tilt compensation and another cog... that is why I bought the BNO055. Sigh.
  • Try this in place of the regular I2C@.
    --- clock stretching responsive I2C@
    --- Fetch a byte from the I2C bus - mirror ack signal 0 in = 0 out
    pub XI2C@	( ack -- data  ) \ 36.6us
    	SDA DUP INPUTS 0  ( ack iomask dat )
    	  8 FOR SCL INPUTS BEGIN SCL IN UNTIL SHRINP SCL OUTCLR NEXT
    	ROT 0= IF OVER OUTCLR THEN
     	CLOCK NOP CLOCK SWAP INPUTS
    	BL REV						--- flip 8 msbs of long back into 8 lsbs
     	;
    

    I don't think places like Adafruit RTM properly since the internal pull-up is from 20k to 60k then a 10k pulldown might not be a proper low. It is better to leave it float with its internal pull-up or else just ground the pin just as the DS says.
  • You are jotting out code faster than I can figure out here ... have to see what is going on with more coffee and more daylight ... :)
    But I was getting the NACK error on the second I2C!? call ... doesn't that mean the I2C! needs the stretching detection?

    I agree, it would have been better to leave it as the chip had it ... they messed with the P0/P1 pins too, perhaps to make it easier for the users.
    Thanks Peter, I appreciate you looking into this.
    Cheers!
  • This works for the BNO055 that needs stretching, and another IMU that doesn't .. I have put clock stretching on all bits in/out and the ack/nak, and slightly modded your routine to leave SDA/SCL always driven low ... is this a good idea? Is the INPUTS on third last line of XI2C@ needed ?
    --- clock stretching responsive I2C@  written by Peter J, slight mods by Paul Rowntree
    --- Fetch a byte from the I2C bus - mirror ack signal 0 in = 0 out
    pub XI2C@	( ack -- data  ) \ 36.6us
    	SDA DUP INPUTS 0  ( ack iomask dat )
    	  8 FOR 
                SCL INPUTS BEGIN SCL IN UNTIL 
                SHRINP SCL OUTCLR 
                NEXT
    	ROT 0= IF OVER OUTCLR THEN
     	CLOCK NOP CLOCK SWAP INPUTS
     	SDA OUTCLR SCL OUTCLR
    	BL REV						--- flip 8 msbs of long back into 8 lsbs
     	;
     	
    --- Write a byte to the I2C bus and return with the ack flag :
    --- original written by Peter J, PR modded to include clock stretching
    --- enter and exit with both SDA and SCL  driven low by propeller Master
    --- thanks to TimMoore who wrote clock stretching routines in SPIN used as example
    
    pub XI2C!? ( data -- flg )					--- write a byte to the I2C bus and return with the ack  0=ack	)
    	#24 REV							--- put into lsb first format for SHROUT
    	SDA DUP OUTSET SWAP					--- data masks
    	8 FOR
    	  SHROUT
    	  SCL INPUTS BEGIN SCL IN UNTIL
              SCL OUTCLR
    	  NEXT							--- loop
    	DROP DUP INPUTS						--- Float SDA
    	SCL INPUTS BEGIN SCL IN UNTIL
            IN 0<> SCL OUTCLR  SDA OUTCLR                           --- ack clock
    	;
    
  • @PaulR.
    Congrats it's working.
    I2C usually has a pull up on SDA at least? Does the datasheet say you should leave SDA and SCL low? But heck I've had a couple difficult to understand I2C-ish datasheets recently. Neat SCL streching :)
  • Cluso99Cluso99 Posts: 18,066
    edited 2016-09-06 08:58
    SDA needs to be Tri-stated when idle. A pull-up is mandatory. Suggested values vary between data sheets. I have never had problems with 10K.

    SCL can be driven by the master, rather than Tri-stated. This is how the P1 boot code works and the reason why some boards don't bother having a pull-up on SCL. IMHO a 10K pull-up (or similar) should be on both SCL and SDA as good design practice.

    The original design for I2C was IIRC 400KHz. However, nowadays much faster speeds are usual with some devices specified up to 1MHz or more.
  • I was actually testing some instructions that support I2C better, CLKIN and CLKOUT to handle a data bit with clock stretching and open-drain driving. The standard speed these days is 400kHz for which the driver is optimized for although there are still some older chips around that only work at the original 100kHz. Many EEPROMs work at the 1MHz I2C fast mode and EEPROM routines use these too as the compact dictionary model benefits from being able to access blocks of EEPROM quickly.

Sign In or Register to comment.