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!"

Thursday, November 30, 2023

bit por bit - MISO and MOSI

console show
### spi programmer for ATTINY85    1
#
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 setSCK {value} {
  if {$value == 1} {
    setBit 2
  } else {
    clearBit 2
  }
}

proc setMOSI {value} {
  if {$value == 1} {
    setBit 4
  } else {
    clearBit 4
  }
}

proc setRES {value} {
  if {$value == 1} {
    setBit 1
  } else {
    clearBit 1
  }
}

proc readMISO {} {
  # added
  after 100
  set miso [lpt_rdstat]
  if {$miso == 127} {set y 1}
  if {$miso == 63}  {set y 0}
  return $y
}

proc initialisiere {} {
  global h hh hhh hhhh
  set h    [open /sys/class/gpio/gpio25/value w]
  set hh   [open /sys/class/gpio/gpio24/value w]
  set hhh  [open /sys/class/gpio/gpio23/value w]
  set hhhh [open /sys/class/gpio/gpio22/value r]
  setMOSI 0
  #flush $hh
  setSCK 0
  #flush $hhh
  after 100
  setRES 1
  #flush $h
}

proc start-programming {} {
  global h hh hhh
  setMOSI 0
  setSCK 0
  after 100
  setRES 0
}

proc stop-programming {} {
  global h hh hhh
  setMOSI 0
  setSCK 0
  after 100
  setRES 1
}

proc sende-u-empfange {n} {
  global hh hhh hhhh
  binary scan [binary format H* $n] b* bits
  set y 0

  setSCK 0
  set x [readMISO]
  update
 
  for {set i 7} {$i > -1} {incr i -1} {
      #puts "bit $i = weight [expr int(pow(2,$i))]"
      update
      set weight [expr int(pow(2,$i))]
      if {$x == 1} {incr y $weight}
      setMOSI [string index $bits $i]
      setSCK 1
      after 1
      setSCK 0
      set x [readMISO]
  }
 
  return [format %X $y]
}

after 1000
start-programming

set ein [open 207 r]
set aus [open result w+]

set zzz ""
set nn 0
set zeit1 [clock milliseconds]

while {[eof $ein] != 1 } {
  set zeile [gets $ein]
  puts -nonewline "$zeile - "
 
  if {[lindex $zeile 0] == "FF"} break
  set y ""
 
  set z [sende-u-empfange [lindex $zeile 0] ]
  set y "$y $z"
 
  set z [sende-u-empfange [lindex $zeile 1] ]
  set y "$y $z"
 
  set z [sende-u-empfange [lindex $zeile 2] ]
  set y "$y $z"
 
  set z [sende-u-empfange [lindex $zeile 3] ]
  set y "$y $z"
  puts "$y"
 
  incr nn 4
}

set zeit2 [clock milliseconds]
set diff [expr $zeit2 - $zeit1]
set teiler [expr 1.0*$diff/$nn]

stop-programming

close $ein
close $aus
puts "*** DONE"
puts "$diff Millisekunden $nn Instruktionen $teiler ms pro Instruktion"

 

Sunday, November 26, 2023

ATtiny85 excelente referencia - en aleman

http://www.elektronik-labor.de/AVR/KursAssembler/T13asm13.html

http://www.elektronik-labor.de/AVR/AVR.html

BASCOM-AVR© is the original Windows BASIC COMPILER for the AVR family. 
Compiler: kostenfreie Bascom-Schnupper-Version (www.mcselec.com)

Friday, November 24, 2023

Programacion del ATTiny85 con PICkit Serial Analyzer

Aprendi:
1) La diferencia de usar SPIDATIN o SAPIDATOUT vs SPIDATIO
2) Las pausas mostradas en amarillo son necesarias
 
Script #1
attiny1  SPI SPICSON SPIDATIO 0x02 0xAC 0x53
attiny2  SPI SPICSON SPIDATIO 0x02 0x00 0x00
attiny3  SPI SPICSON SPIDATIO 0x02 0xAC 0x80
attiny4  SPI SPICSON SPIDATIO 0x02 0x00 0x00
attiny5  SPI SPICSON SPIDATIO 0x02 0x40 0x00
attiny6  SPI SPICSON SPIDATIO 0x02 0x00 0xB9
attiny7  SPI SPICSON SPIDATIO 0x02 0x48 0x00
attiny8  SPI SPICSON SPIDATIO 0x02 0x00 0x9A
attiny9  SPI SPICSON SPIDATIO 0x02 0x40 0x00
attiny10 SPI SPICSON SPIDATIO 0x02 0x01 0x00
attiny11 SPI SPICSON SPIDATIO 0x02 0x48 0x00
attiny12 SPI SPICSON SPIDATIO 0x02 0x01 0xE1
attiny13 SPI SPICSON SPIDATIO 0x02 0x40 0x00
attiny14 SPI SPICSON SPIDATIO 0x02 0x02 0x0A
attiny15 SPI SPICSON SPIDATIO 0x02 0x48 0x00
attiny16 SPI SPICSON SPIDATIO 0x02 0x02 0xBD
attiny17 SPI SPICSON SPIDATIO 0x02 0x40 0x00
attiny18 SPI SPICSON SPIDATIO 0x02 0x03 0x05
attiny19 SPI SPICSON SPIDATIO 0x02 0x48 0x00
attiny20 SPI SPICSON SPIDATIO 0x02 0x03 0xE0
attiny21 SPI SPICSON SPIDATIO 0x02 0x40 0x00
attiny22 SPI SPICSON SPIDATIO 0x02 0x04 0x03
attiny23 SPI SPICSON SPIDATIO 0x02 0x48 0x00
attiny24 SPI SPICSON SPIDATIO 0x02 0x04 0xBF
attiny25 SPI SPICSON SPIDATIO 0x02 0x40 0x00
attiny26 SPI SPICSON SPIDATIO 0x02 0x05 0xFF
attiny27 SPI SPICSON SPIDATIO 0x02 0x48 0x00
attiny28 SPI SPICSON SPIDATIO 0x02 0x05 0xCF
attiny29 SPI SPICSON SPIDATIO 0x02 0x4C 0x00
attiny30 SPI SPICSON SPIDATIO 0x02 0x00 0x00 SPICSOFF
 
Script #2
attinyA SPI SPICSON SPIDATIO 4 0xAC 0x53 0x00 0x00 WAIT1 0x1F 0x00 SPIDATIO 4 0xAC 0x80 0x00 0x00 WAIT1 0x1F 0x00 SPIDATIO 12 0x40 0x00 0x00 0xB9 0x48 0x00 0x00 0x9A 0x40 0x00 0x01 0x00
attinyB SPI SPICSON SPIDATIO 20 0x48 0x00 0x01 0xE1 0x40 0x00 0x02 0x0A 0x48 0x00 0x02 0xBD 0x40 0x00 0x03 0x05 0x48 0x00 0x03 0xE0 
attinyC SPI SPICSON SPIDATIO 20 0x40 0x00 0x04 0x03 0x48 0x00 0x04 0xBF 0x40 0x00 0x05 0xFF 0x48 0x00 0x05 0xCF 0x4C 0x00 0x00 0x00 SPICSOFF
 

Tuesday, November 21, 2023

Programacion del ATTiny85 con el puerto paralelo de la PC

Hoy pude hacer funcionar el spidemo (EuroTcl2018) de Uli Ender, haciendo adecuaciones para usar el puerto paralelo de la PC, Tcl y la extension lpttcl.