Sunday, December 10, 2023

Driving LCD with parallel port with Tcl

DB25        LCD

pin bit  signal pin 

2    0   RS     4
3    1   RW     5
4    2   EN     6
5    3  
6    4   DB4    11
7    5   DB5    12
8    6   DB6    13
9    7   DB7    14
18       GND    1
         +5V    2
         INT    3 pulldown

 

###
console show

load lpttcl
set ver [package require lpttcl]

lpt_wrdata 0x00
puts [lpt_rdstat]
set val 0
lpt_rdstat


 # to LCD 4-bit mode
 #

 proc sendX {hexString} {
  foreach byte $hexString {
      lpt_wrdata $byte
      puts $byte
  }
 }

 proc send_data {byte} {
   global addr
   set byte [string range $byte end-1 end]
   puts "byte: $byte"
   foreach {n1 n2} [split $byte ""] break
   sendX [list 0x${n1}5 0x${n1}1 0x${n2}5 0x${n2}1]
 }

 proc send_cmd {byte} {
   global addr
   set byte [string range $byte end-1 end]
   puts "byte: $byte"
   foreach {n1 n2} [split $byte ""] break
   sendX [list 0x${n1}4 0x${n1}0 0x${n2}4 0x${n2}0]
 }


 #set addr 0x27
 set addr 0x4e
 
 # LCD Initialization for 4-BIT bus
 sendX [list 0x34 0x30]
 
 after 50

 # LCD Initialization for 4-BIT bus
 sendX [list 0x34 0x30 0x34 0x30 0x24 0x20 0x24 0x20]
 
 # 2 Line LCD, 5x10 character
 sendX [list 0xc4 0xc0]
 
 # 01 = Clear Display
 # sendX [list 0x04 0x00 0x14 0x10]
 send_cmd 01
 #                   ^    ^    ^    ^
 
 # 0C = Display Control,Display ON
 # sendX [list 0x04 0x00 0xc4 0xc0]
 send_cmd 0C
 
 
 # 06 = Entry Mode Set, Auto Increment of cursor position
 # sendX [list 0x04 0x00 0x64 0x60]
 send_cmd 06
 #send_cmd 1C; # 07+1C se queda en el mismo lugar siempre ocupando un solo espacio

 #
 foreach letter [split "01234567" ""] {
   binary scan $letter "H2" valor
   send_data $valor
   after 1000
 }

 send_cmd C0
 
 foreach letter [split "89ABCDEF" ""] {
   binary scan $letter "H2" valor
   send_data $valor
   after 1000
 }
 
 for {set i 1} {$i<8} {incr i} {
 send_cmd 18
 after 500
 }
 
 puts "*** DONE!"

Friday, December 8, 2023

Tcl procedures for I2C

 

Based on:

###
console show

set pin_state 0
load lpttcl
set ver [package require lpttcl]

lpt_wrdata 0x00
puts [lpt_rdstat]
set val 0
lpt_rdstat

proc clearBit {n} {
global val
set val [expr $val & [expr ~$n]]
lpt_wrdata $val
}

proc setBit {n} {
global val
set val [expr $val | $n]
lpt_wrdata $val
}

proc SDA_ON {} {
# bit 0 (DB25 pin 2) weight 1
set pinSDA 1
#set pin_state [expr $pin_state|(1<<$pinSDA)]
setBit $pinSDA
puts -nonewline "1"
update
}

proc SDA_OFF {} {
# bit 0 (DB25 pin 2) weight 1
set pinSDA 1
#set pin_state [expr $pin_state&~(1<<$pinSDA)]
puts -nonewline "0"
clearBit $pinSDA
update
}

proc SCL_ON {} {
# bit 1 (DB25 pin 3) weight 2
set pinSCL 2
#set pin_state [expr $pin_state|(1<<$pinSCL)]
#puts -nonewline "_"
#puts ">>>HIGH"
setBit $pinSCL
update
}

proc SCL_OFF {} {
# bit 1 (DB25 pin 3) weight 2
set pinSCL 2
#set pin_state [expr $pin_state&~(1<<$pinSCL)]
#puts -nonewline "."
#puts "<<<LOW"
clearBit $pinSCL
update
}

proc DLY {} {
    after 1
}

proc start {} {
    SDA_ON
    DLY
    SCL_ON
    DLY
    SDA_OFF
    DLY
    SCL_OFF
    DLY
}

proc stop {} {
    SDA_OFF
    DLY
    SCL_ON
    DLY
    SDA_ON
    DLY
}

proc TX {dat} {

    for {set i 8} {$i > 0} {incr i -1} {
        # (dat & 0x80) ? SDA_ON : SDA_OFF; //Mask for the eigth bit
        set mask8 [expr $dat & 0x80]
        if $mask8 {
            #puts "$i = SDA_ON"
            SDA_ON
        } else {
            #puts "$i = SDA_OFF"
            SDA_OFF
        }
        
        # dat<<=1;  //Move
        set dat [expr $dat <<1]
         
        DLY
        SCL_ON
        DLY
        SCL_OFF
        DLY
    }
    
    SDA_ON;
    #puts "extra SDA_ON"
    SCL_ON;
    DLY
    # bool ack = !SDA_READ;    // Acknowledge bit
    # tk_messageBox -message "ACK bit"
    SCL_OFF
    puts "="
    #return ack;
}

 # to LCD with I2C module
 #

 proc sendX {hexString} {
  start
  puts ">"
  foreach byte $hexString {
    TX $byte
  }
  stop
  puts "<"
 }

 proc send_data {byte} {
   global addr
   set byte [string range $byte end-1 end]
   puts "byte: $byte"
   foreach {n1 n2} [split $byte ""] break
   sendX [list $addr 0x${n1}5 0x${n1}1 0x${n2}5 0x${n2}1]
 }

 #set addr 0x27
 set addr 0x4e
 
 # LCD Initialization for 4-BIT bus
 sendX [list $addr 0x34 0x30]
 
 after 50

 # LCD Initialization for 4-BIT bus
 sendX [list $addr 0x34 0x30 0x34 0x30 0x24 0x20 0x24 0x20]
 
 # 2 Line LCD, 5x10 character
 sendX [list $addr 0xc4 0xc0]
 
 # 01 = Clear Display
 sendX [list $addr 0x04 0x00 0x14 0x10]
 #                   ^    ^    ^    ^
 
 # 0C = Display Control,Display ON
 sendX [list $addr 0x04 0x00 0xc4 0xc0]
 # 06 = Entry Mode Set, Auto Increment of cursor position
 sendX [list $addr 0x04 0x00 0x64 0x60]

 #
 foreach letter [split "Tcl/Tk lptt I2C" ""] {
   binary scan $letter "H2" valor
   send_data $valor
 }
 puts "*** DONE!"