Skip to content

Commit

Permalink
Add 1W & I2C commands for playing with 1-wire & I²C devices
Browse files Browse the repository at this point in the history
- optimize code size a bit
- ensure flag_timer is cleared before use (to avoid effects of potential
  race if previous timeout occurred right after expected condition)
  • Loading branch information
OlekMazur committed Jul 17, 2024
1 parent c69b4f7 commit 105188a
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 137 deletions.
68 changes: 53 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ Commands
| W P3 | \<byte\> | Sets output of port P3, except P3.0 (RXD) and P3.1 (TXD) |
| W PG | \<byte\> | Sets mask of adresses inside the same page of I²C EEPROM |
| W RF | \<byte\> | Sets code of operation performed by D and V commands |
| 1WR | \<send\> \<recv\> | Reset 1-wire device, send some bytes and receive some bytes from it |
| 1W1 | | Restore 1-wire mode (exit thermostate mode) of DS1821 |
| 1W | \<desc\> | Reset 1-wire device and transfer raw data |
| I2C | \<desc\> | Transfer raw data to/from an I²C device |
| D | \[\<begin\> \[\<end\>\]\] | Dumps memory of W79EX051 |
| V | | Verifies memory of W79EX051 against given Intel HEX data |
| LB | | Loads memory of W79EX051 from given Intel HEX data |
| K | \[\<code\>\] | Clears selected memory of W79EX051 |
| NR | | Resets W79EX051 |
| NT | \<desc\> | Performs raw transfer to/from W79EX051 |
| NT | \<desc\> | Transfer raw data to/from W79EX051 |
| DX | \[\<begin\> \[\<end\>\]\] | Dumps contents of I²C EEPROM |
| VX | | Verifies contents of I²C EEPROM against given Intel HEX data |
| LX | | Loads contents of I²C EEPROM from given Intel HEX data |
Expand All @@ -90,26 +91,26 @@ Prints all supported commands along with short description.
W79EX051/AVR PROGRAMMER VERSION 1.1 Copyright (c) 2022-2024 Aleksander Mazur
> H
H Print this help
R Read registers & configuration
R Read regs & show config
W P1 Write to P1
W P3 Write to P3
W PG Set PaGe mask: 7 for AT24C01/2, F for AT24C04 and bigger
W RF Set Read Flash code used by D&V commands
DX Dump AT24CXX EEPROM (I2C)
DY Dump 93XXY6Z EEPROM (SPI)
DX Dump AT24CXX
DY Dump 93XXY6Z
DAE Dump AVR EEPROM
DA Dump AVR flash
DR Dump internal RAM
DP Dump internal flash
D Dump W79EX051 memory
VX Verify AT24CXX EEPROM (I2C)
VY Verify 93XXY6Z EEPROM (SPI)
VX Verify AT24CXX
VY Verify 93XXY6Z
VAE Verify AVR EEPROM
VA Verify AVR flash
VR Verify internal RAM
V Verify W79EX051 memory
LX Load AT24CXX EEPROM (I2C)
LY Load 93XXY6Z EEPROM (SPI)
LX Load AT24CXX
LY Load 93XXY6Z
LAE Load AVR EEPROM
LA Load AVR flash
LR Load internal RAM
Expand All @@ -118,8 +119,9 @@ KA Klear AVR (Chip Erase)
K Klear W79EX051: 26=erase all, 22=AP flash (default), 62=NVM
NR Reset W79EX051 & enter ICP mode
NT Transfer to/from W79EX051 (no reset): NT 0000S0BRJ FB00S0CRZ RJ
1WR Transfer to/from 1-wire: 1WR 33 8
1W1 Exit thermostat mode of DS1821
1W Transfer to/from 1-wire: 33RRRRRRRR
I2C Transfer to/from I2C: A000SA1RKRN
```

### Command R
Expand Down Expand Up @@ -157,13 +159,49 @@ In case of AT24C04 and bigger it can be set to 0F = 16 bytes per page.
P1:FE P3:BF PG:0F RF:00
```

### Command 1WR
### Command 1W

Syntax of \<desc\>:

| Input | Description |
| ----- | ----------- |
| space | Reset, echo space |
| XX (hex byte) | Send given byte |
| R | Receive one byte |
| W | Receive bits in a loop until 1 arrives |

Examples:
- `1W 33RRRRRRRR` - reset, read ROM code
- `1W CC44W CCBERRRRRRRRR` - reset, initiate temperature conversion,
wait for completion, reset, read 9 bytes of scratchpad (DS18B20)
- `1W CC4E12341F CCBERRRRRRRRR` - reset, write 3 bytes to scratchpad,
reset, read 9 bytes of scratchpad (DS18B20)
- `1W CCF08000RRRRRRRRRRRRRRRR` - reset, read 16 bytes @80h (DS2431)

### Command I2C

Syntax of \<desc\>:

| Input | Description |
| ----- | ----------- |
| space | STOP (only if preceded by START); START |
| XX (hex byte) | Send given byte |
| R | Receive one byte |
| S | START |
| K | ACK |
| N | NAK |

STOP is also implicitly sent at the end of the command if there was
START before.

Reset, send 1 or 2 bytes, then receive given number of bytes.
Examples:
- `1WR 33 8` - Read ROM
- `1WR CC44 0` - Skip ROM, Convert T (DS18B20)
- `1WR CCBE 9` - Skip ROM, Read Scratchpad (DS18B20)
- `I2C A000SA1RKRN` - read 2 bytes from AT24C04
- `I2C 86000CD077 C2080C8819A0` - setup TDA9887 & FM1216ME for FM
stereo reception, tune to 92.3 MHz
- `I2C 86000C3077 C2080C8859A0` - setup TDA9887 & FM1216ME for FM
mono reception, tune to 92.3 MHz
- `I2C 86S87RKRKRKRKRKRKRKRKRKRKRN` - read status of TDA9887
- `I2C C2SC3RN` - read status of FM1216ME

### Commands D* (dump)

Expand Down
87 changes: 50 additions & 37 deletions command_1W.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,51 +13,65 @@
; You should have received a copy of the GNU General Public License
; along with Programator. If not, see <https://www.gnu.org/licenses/>.
;
; Copyright (c) 2022 Aleksander Mazur
; Copyright (c) 2022, 2024 Aleksander Mazur
;
; Procedura obsługi poleceń 1-wire (1W*)

;-----------------------------------------------------------
; Obsługuje komendę 1WR - wyślij/odbierz surowe dane do/z 1-wire
; Obsługuje komendę 1W - wyślij/odbierz surowe dane do/z 1-wire
if USE_HELP_DESC
dw s_help_1WR
dw s_help_1W
endif
command_1wire_rw:
command_1wire_transfer:
mov P1, #11111011b ; OW_GND do masy, jedynki gdzie indziej
; domyślnie 1WR 33 8 = wyślij 33h (READ ROM) i czytaj 8 bajtów
; przykład: 1WR CC44 0 = mierz temperaturę na DS18B20
; przykład: 1WR CCBE 9 = wyślij CC,BE (SKIP ROM + READ SCRATCHPAD) i czytaj 9 bajtów z DS18B20
clr A
mov R2, A
mov R3, #33h ; READ ROM
mov R4, A
mov R5, #8 ; 64 bity = 8 bajtów
bcall get_2_hex_numbers
; wysyłamy R4 (jeśli nie zero), R5
; potem jeśli R2 nie jest zerem, to wysyłamy jeszcze R2 i R3
; a jeśli R2 jest zerem, to czytamy R3 bajtów
command_1wire_transfer_loop:
acall get_hex_or_char
jnc command_1wire_send_byte
jnz command_1wire_handle_char
; C=1, A=0 -> koniec
ret_1wire:
ret

command_1wire_send_byte:
; C=0, A=bajt do wysłania
bcall ow_write
sjmp command_1wire_transfer_loop

command_1wire_handle_char:
; C=1, A=znak
cjne A, #' ', command_1wire_transfer_not_space
; spacja = reset 1-wire
bcall ow_reset
jc error_1w_err
mov A, R4
jz command_1wire_rw_skip
bcall ow_write
command_1wire_rw_skip:
mov A, R5
bcall ow_write
mov A, R2
jnz command_1wire_rw_write
; czytamy R3 bajtów
command_1wire_rw_loop:
bcall uart_send_char ; echo
sjmp command_1wire_transfer

command_1wire_transfer_not_space:
cjne A, #'R', command_1wire_transfer_not_R
; odbieramy bajt
bcall ow_read
bcall uart_send_hex_byte
djnz R3, command_1wire_rw_loop
ret
command_1wire_rw_write:
; wysyłamy jeszcze R2 i R3
mov A, R2
bcall ow_write
mov A, R3
bjmp ow_write
sjmp command_1wire_transfer_loop

command_1wire_transfer_not_R:
cjne A, #'W', command_1wire_transfer_not_W
; czytamy bity, dopóki jest zero (trwa pomiar)
clr A ; max.65536*ow_read_bit, ok.5s
mov R6, A
mov R5, A
command_1wire_wait_loop:
; "the master can issue read time slots after the Convert T command ..."
bcall ow_read_bit
; "... and the DS18B20 will respond by transmitting a 0 while the temperature conversion is in progress and a 1 when the conversion is done"
jc command_1wire_transfer_loop
djnz R6, command_1wire_wait_loop
djnz R5, command_1wire_wait_loop
mov DPTR, #s_error_1w_timeout
bcall uart_send_rom
sjmp command_1wire_transfer_loop

command_1wire_transfer_not_W:
bjmp error_illopt

;-----------------------------------------------------------
; Obsługuje komendę 1W1 - przywróć tryb 1-wire czujnikowi DS1821
Expand All @@ -82,9 +96,8 @@ command_1wire_ds1821_loop: ; "toggling the DQ line low 16 times"
nop
setb OW_PWR
bcall ow_reset
jc error_1w_err
ret

jnc ret_1wire
;jc error_1w_err
;-----------------------------------------------------------
error_1w_err:
mov DPTR, #s_error_1w_err
Expand Down
4 changes: 3 additions & 1 deletion command_DAE_VAE_LAE_DA_VA_LA_KA.asm
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ command_dump_avr_eeprom:
acall get_address_range
; mamy zakres zrzutu: R2:R3 bajtów poczynając od R4:R5
mov A, R2
jnz error_illopt
jz command_dump_avr_eeprom_ok
ajmp error_illopt_fwd
command_dump_avr_eeprom_ok:
mov DPTR, #cb_dump_avr_eeprom
ajmp dump_hex_file

Expand Down
11 changes: 4 additions & 7 deletions command_DY_VY_LY.asm
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,10 @@ command_dump_spi_eeprom_shl:
; 6, 7 bitów -> 2^7=128 bajtów
; 8, 9 bitów -> 2^9=512 bajtów
; 10, 11 bitów -> 2^11=2048 bajtów
clr C
mov A, R5
subb A, #1
mov R5, A
mov A, R4
subb A, #0
mov R4, A
dec R5
cjne R5, #-1, command_dump_spi_no_carry
dec R4
command_dump_spi_no_carry:
bcall get_address_range
; mamy zakres zrzutu: R2:R3 bajtów poczynając od R4:R5
mov DPTR, #cb_dump_spi_eeprom
Expand Down
6 changes: 4 additions & 2 deletions command_D_V_L_K.asm
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ cb_load_at89cx051_loop2:
acall wait_10us ; t_GHSL: min.10µs
setb AT89C_VPP ; opuszczenie RST/VPP z 12V spowrotem do 5V
acall at89cx051_init_read_flash ; poza wystawieniem jedynek na P1 równoważne clr AT89C_ENABLE
clr flag_timer
; t_WC - czas programowania bajtu to max.2ms
mov TH0, #-8
mov TL0, #-52
Expand All @@ -156,8 +157,9 @@ cb_load_at89cx051_loop2:
cb_load_at89cx051_wait:
; czekamy max.2ms na podniesienie linii /BUSY
jb AT89C_RDY_BSY, cb_load_at89cx051_loop4
jnb flag_timer, cb_load_at89cx051_wait
; timeout
jbc flag_timer, cb_load_at89cx051_timeout
sjmp cb_load_at89cx051_wait
cb_load_at89cx051_timeout:
clr TR0
cb_load_at89cx051_code_F:
mov A, #'F'
Expand Down
83 changes: 83 additions & 0 deletions command_I2C.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
; This file is part of Programator.
;
; Programator is free software: you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation, either version 3 of the
; License, or (at your option) any later version.
;
; Programator is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Programator. If not, see <https://www.gnu.org/licenses/>.
;
; Copyright (c) 2024 Aleksander Mazur
;
; Procedura obsługi polecenia I2C

;-----------------------------------------------------------
; Obsługuje komendę I2C - wyślij/odbierz surowe dane do/z I2C
if USE_HELP_DESC
dw s_help_I2C
endif
command_i2c_transfer:
mov P1, #P1WR_I2C_EEPROM
clr F0 ; czy był START
command_i2c_transfer_loop:
bcall get_hex_or_char
jnc command_i2c_send_byte
jnz command_i2c_handle_char
; C=1, A=0 -> koniec
command_i2c_maybe_stop:
jnb F0, command_i2c_transfer_ret
clr F0
bjmp i2c_stop
command_i2c_transfer_ret:
ret

command_i2c_send_byte:
; C=0, A=bajt do wysłania
bcall i2c_shout
jnc command_i2c_transfer_loop
command_i2c_KO:
mov DPTR, #s_error_i2cerr
bjmp print_error_then_prompt

command_i2c_handle_char:
; C=1, A=znak
cjne A, #' ', command_i2c_transfer_not_space
; spacja = [STOP] START
bcall command_i2c_maybe_stop
bcall uart_send_char ; echo
sjmp command_i2c_start_and_cont

command_i2c_transfer_not_space:
cjne A, #'R', command_i2c_transfer_not_R
; odbieramy bajt
bcall i2c_shin
jc command_i2c_KO
bcall uart_send_hex_byte
sjmp command_i2c_transfer_loop

command_i2c_transfer_not_R:
cjne A, #'S', command_i2c_transfer_not_S
command_i2c_start_and_cont:
bcall i2c_start
jc command_i2c_KO
setb F0
sjmp command_i2c_transfer_loop

command_i2c_transfer_not_S:
cjne A, #'K', command_i2c_transfer_not_K
bcall i2c_ACK
sjmp command_i2c_transfer_loop

command_i2c_transfer_not_K:
cjne A, #'N', command_i2c_transfer_not_N
bcall i2c_NAK
sjmp command_i2c_transfer_loop

command_i2c_transfer_not_N:
bjmp error_illopt
Loading

0 comments on commit 105188a

Please sign in to comment.