March 28, 2024, 11:16:39 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


I2C for EBasic & IWBasic (part 1)

Started by Techno, March 14, 2011, 03:27:57 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Techno

March 14, 2011, 03:27:57 AM Last Edit: March 14, 2011, 03:12:37 PM by LarryMc
Hi all

This code can you free use. Please send me tips, improvements or testcode.

i2c_lpt (i2c via the parallelport) not 100% tested



$USE "inpout32.lib"
$INCLUDE "i2c_lpt.inc"
'
'12.0 De I2C - bus
'------------------
' - De I2C bus is een 2-draads dataverbinding tussen ÃÆ'Ã,©ÃÆ'Ã,©n of meer processoren (masters) en speciale periferie
'   componenten (slaves)
' - Al deze componenten zijn op dezelfde bus aangesloten en hebben elk hun eigen UNIEK ADRES.
' - Deze bus maakt een eenvoudige verbinding mogelijk tussen vele IC's, waarbij uitbreidingen kunnen worden
'   gerealiseerd
' - Op de I2C bus kunnen alle IC's worden aangesloten die het I2C busprotocol beheersen
' - Voorbeelden : RAM -, EEPROM -, I/O -, ADC -, DAC -, Timers -, Displaydrivers -, IC Televisie.
'   Al deze IC's kunnen zonder meer via 2 aansluitingen van de parallelle poort van de PC worden aangestuurd
' - We kunnen ook deze IC's aansturen met de RS232 interface
' - De bus maakt gebruik van de seriÃÆ'Ã,«le datalijn (SDA) en het kloksignaal (SCL).
' - DATA en ADRESSEN worden, net als bij een schuifregister, samen met het kloksignaal verzonden.
' - Beide lijnen kunnen in BEIDE RICHTINGEN worden gebruikt
' - Ze zijn van een pullup weerstand voorzien en kunnen door elk aangesloten IC met behulp van open - collector
'   of open - drain uitgangen naar massa worden getrokken
'
' - Figuur 12.1
'   ===========
'   * Niet actieve buselementen zijn HOOGOHMIG, maar houden (uiteraard) wel de bussignalen in de gaten
'   * Wanneer een systeem 1 MASTER wordt gebruikt : levert deze als enige het kloksignaal
'     De data kunnen echter zowel van de MASTER als ÃÆ'Ã,©ÃÆ'Ã,©n van de SLAVES afkomstig zijn
'   * Hoe kunnen we herkennen als elke busdeelnemer het begin en einde van een bericht + adressering.
'
' STAP 1 : RUSTTOESTAND
' =====================
' - SDA en SCL = HOOG
'
' STAP 2 : START CONDITIE (SDA : H -> L)
' ======================================
' - SDA wordt door de MASTER LAAG gemaakt
' - SCL = HOOG
'
' STAP 3 : STOP CONDITIE (SDA : L -> H)
' =====================================
' - SDA gaat van LAAG naar HOOG
' - SCL = HOOG
'
' STAP 4 : DATA OVERDRACHT
'   ========================
' - De TRANSMITTER zet 1 byte op de datalijn (SDA), die door de klokpulsen van de MASTER op de kloklijn
'     SCL verder worden geschoven
'   - Overdracht begint steeds met het MSB bit
'
' STAP 5 : BEVESTIGING (ACK)
' ==========================
' - De RECEIVER bevestigt de ontvangst van een byte door de SDA lijn LAAG te maken tot de MASTER
'     de 9 klokpuls op de SCL heeft gezet.
'   - Deze bevestiging houdt meteen in dat een volgend byte ontvangen kan worden.
'   - Wannneer de communicatie moet worden stopgezet wordt dit kenbaar gemaakt door het uitblijven van ACK
'   - Met de STOP conditie wordt de communicatie gestopt
'
' - ADRESSEN worden op exact DEZELFDE manier verzonden als DATA, en de ontvangst wordt net zo bevestigd met de ACK
'   In het eenvoudigste geval van DATA - overdracht van MASTER naar SLAVE : bvb : een I/O IC vinden de onderstaande
'   processen plaats:
'
' STAP 1
'   ======
' * De MASTER geeft het STARTSIGNAAL en verzendt dan in bits 7...1 het UNIEKE ADRES van het I/0 IC
'
' STAP 2
' ======
' * In bit 0 de richting van het dataverkeer R/W :
' W = 0 : schrijven
' R = 1 : lezen
' * De ontvangst van het ADRES wordt door de betreffende SLAVE bevestigd met een ACK bit
'
' STAP 3
'   ======
' * Vervolgens verzendt de MASTER het DATABYTE, waarvan de ontvangst eveneens wordt ACK.
' * Nu kan de MASTER de verbinding verbreken door middel van een STOPSIGNAAL, of nog meer bytes naar de SLAVE
'  te sturen
'
' STAP 4
' ======
' * Wanneer DATA uit de SLAVE moet worden uitgelezen, moet het richtingsbit R = 1 gemaakt worden.
' * De MASTER zet dan 8 klokpulsen op de kloklijn SCL.
' * en kan 8 databits in ontvangst nemen.
' * Zolang hij de ontvangst daarvan bij de 9 klokpuls door een ACK, kan hij bytes blijven ontvangen.
'   * De overdracht wordt uiteindelijk door de MASTER stopgezet door het niet meer versturen van een ACK en door
'     vervolgens een STOPSIGNAAL te verzenden
'
' - Elke I2C component heeft een VAST UNIEK ADRES dat deels door type component wordt bepaald en deels via extern
'   toegankelijke adreslijnen kan worden beÃÆ'Ã,¯nvloed.
' - De maximale klokfrequentie voor de I2C bus bedraagt 100 kHz
'==================================================================================================================
'
'
'12.1 Aansturing via de LPT port
'-------------------------------
'
' - De I2C bus kan bijzonder gemakkelijk aan de parallelle poort (LPT - port) worden gekoppeld, omdat de
'   bi-directionele aansluitingen STROBE en AUTO FEED direct als SDA en SCL kunnen worden gebruikt
' - Alle procedures die klokpulsen genereren zijn voorzien van delay loops.
' - In de praktijk is een waarde van 5 voor de delay loops optimaal gebleken bij een AT-386 met een klok
'   frequentie van 25 MHz.
' - Voor snellere PC's moet deze waarde worden verhoogd, zodat de klokfrequentie op de SCL lijn ONDER de
'   maximale waarde van 100 kHz blijft.
'============================================================================================================'

'============================================================================================================'
' ImpOut32.dll '
DECLARE IMPORT, Inp32(PortAddr : WORD), WORD         '
DECLARE IMPORT, Out32(PortAddr : WORD, PortData : WORD) '
'============================================================================================================'

'============================================================================================================'
' MSVC70.dll                                                                       '
DECLARE EXTERN _sscanf(STRING buf, STRING format,...),INT '
DECLARE EXTERN sprintf(POINTER p, POINTER p, ...), INT '
DECLARE EXTERN ReadKey alias __getch(),INT '
DECLARE EXTERN KeyPressed alias __kbhit(),INT '
'============================================================================================================'

'============================================================================================================'
' kernel32.dll '
DECLARE IMPORT, Sleep(int time) '
'============================================================================================================'

EXPORT i2c_Init
EXPORT i2c_Start
EXPORT i2c_Stop
EXPORT i2c_Ack
EXPORT i2c_NoAck
EXPORT i2c_Write
EXPORT i2c_Read

SUB i2c_Init()
   Out32 ((LPT1 + 0x02), 0x00)                           'SCL = 1, SDA = 1   (0000 0000)
RETURN
ENDSUB

SUB i2c_Start()
   Out32 ((LPT1 + 0x02), 0x01)                        'SCL = 1, SDA = 0   (0000 0001)
   Out32 ((LPT1 + 0x02), 0x03)                           'SCL = 0, SDA = 0   (0000 0011)
RETURN
ENDSUB

SUB i2c_Stop()
   Out32 ((LPT1 + 0x02), 0x03)                             'SCL = 0, SDA = 0   (0000 0011)
   Out32 ((LPT1 + 0x02), 0x01)                             'SCL = 1, SDA = 0   (0000 0001)
   Out32 ((LPT1 + 0x02), 0x00)                             'SDA = 1, SDA = 1   (0000 0000)
RETURN
ENDSUB

SUB i2c_Ack()
   
Out32 ((LPT1 + 0x02), 0x03)                             'SCL = 0, SDA = 0   (0000 0011)
   Out32 ((LPT1 + 0x02), 0x01)                             'SCL = 1, SDA = 0   (0000 0001)

   'FOR m = 1 TO 5 : NEXT m
   Sleep(5)
Out32 ((LPT1 + 0x02), 0x03)                             'SCL = 0, SDA = 0   (0000 0011)
RETURN
ENDSUB

SUB i2c_NoAck()

Out32 ((LPT1 + 0x02), 0x02)                            'SCL = 0, SDA = 1   (0000 0010)
   Out32 ((LPT1 + 0x02), 0x00)                        'SCL = 1, SDA = 1   (0000 0000)

   'FOR m = 1 TO 5 : NEXT m
   Sleep(5)
Out32 ((LPT1 + 0x02), 0x02)                             'SCL = 0, SDA = 1   (0000 0010)
RETURN
END SUB

SUB i2c_Write(DataWoord AS CHAR)
   DEF BitWoord : CHAR
DEF PortWoord : CHAR
DEF n     : CHAR

   BitWoord = 0x80

   FOR n = 1 TO 8
       IF (DataWoord & BitWoord) = BitWoord THEN
           PortWoord = 0x02    '(0000 0010)
       ELSE
           PortWoord = 0x03    '(0000 0011)
       END IF

       Out32 ((LPT1 + 0x02), PortWoord)                 ' SDA = setten
       Out32 ((LPT1 + 0x02), PortWoord - 0x02)           ' SCL = HOOG
       Sleep(5)
'FOR m = 1 TO 5 : NEXT m                             ' delay loop

       Out32 ((LPT1 + 0x02), PortWoord)                    ' SCL = reset
       Out32 ((LPT1 + 0x02), BitWoord >> 0x01)             '
   NEXT n

   Out32 ((LPT1 + &H02), 0x02)                             'SCL = 0, SDA = 1    (0000 0010)
   Out32 ((LPT1 + &H02), 0x00)                             'SCL = 1, SDA = read (0000 0000)

Sleep(5)
   'FOR m = 1 TO 5 : NEXT m                                 ' delay loop

   IF (Inp32(LPT1 + 0x02) & 0x01) = 0 THEN PRINT "IC Antwoord niet"
   Out32 ((LPT1 + &H02), 0x02)                             'SCL = 0, SDA = 1    (0000 0010)
RETURN
END SUB

SUB i2c_Read(), CHAR
   DEF BitWoord : CHAR
DEF DataWoord : CHAR
DEF n   : CHAR

   Out32 ((LPT1 + 0x02), 0x02)                             'SCL = 0, SDA = 1    (0000 0010)
   BitWoord = 0x80
   DataWoord = 0x00

   FOR n = 1 TO 8

       Out32 ((LPT1 + 0x02), 0x00)                         'SCL = 1, SDA = 1    (0000 0000)

Sleep(5)
       'FOR m = 1 TO 5 : NEXT m                             ' delay loop

       IF (Inp32(LPT1 + 0x02) & 0x01) = 0 THEN
           DataWoord += BitWoord
       END IF

       Out32 ((LPT1 + 0x02), 0x02)                         'SCL = 0, SDA = 1    (0000 0010)
       BitWoord = BitWoord >> 0x01
   NEXT n
   RETURN DataWoord
ENDSUB


include file
DECLARE IMPORT, i2c_Init()
DECLARE IMPORT, i2c_Start()
DECLARE IMPORT, i2c_Stop()
DECLARE IMPORT, i2c_Ack()
DECLARE IMPORT, i2c_NoAck()
DECLARE IMPORT, i2c_Write(DataWoord AS CHAR)
DECLARE IMPORT, i2c_Read(), CHAR

CONST LPT1      = 0x378
CONST LPT2      = 0x278
CONST LPT3      = 0x3BC

CONST STROBE    = 0x01
CONST AUTO_FEED = 0x02
CONST INIT      = 0x04
CONST SLCTIN    = 0x08

CONST ERROR     = 0x08
CONST SELECTS   = 0x10
CONST PE        = 0x20
CONST ACK       = 0x40
CONST BUSY      = 0x80