DiscreteInput

Purpose: Read the status of a Discrete Input.
Assumes:   Nothing.
Passed: R24   BYTE   bPortAndPin   single Port and Pin specified in the binary format PPPP0ppp
Returns: R24 BYTE bValue status of the selected Discrete Input: 0 when OFF, 1 when ON
Alters: Only R24 and the FLAGs (SREG)
 

DiscreteOutput

Purpose: Turn a Discrete Output OFF or ON.
Assumes:   Nothing.
Passed: R24 BYTE bPortAndPin   single Port and Pin specified in the binary format PPPP0ppp
R22 BYTE bValueToSet   value to set; 0 turns the pin OFF; anything else turns it ON
Returns: R24 BYTE bStata   bitmapped status of all the Discrete I/O points on that PORT
Alters: R24, the FLAGs (SREG) and the COM1 Transmit buffer

Example:  
.ORG 0x1000
DemoDI:
   LDI     R24, ACSZ_DIn & 0xFF   ; Point to the initial string:
   LDI     R25, ACSZ_DIn >> 8     ;  "Discrete Inputs:" and print it
   RCALL   ALocal_Print
   LDI     R26, B00100000         ; Select: B001#xxxx = PORTC; Bxxxx#000 = DO0

DemoDI_Loop:
   MOV     R24, R26               ; Copy the saved Discrete Input selector
   CALL    ADiscreteInput         ; This is the function being tested
   CPI     R24, 0                 ; Set or clear the ZERO flag based on the R24
   LDI     R25, ACSZ_DOff >> 8    ;  returned, then assuming that it was zero
   LDI     R24, ACSZ_DOff & 0xFF  ;  set the pointer to the " OFF" string
   BREQ    AGo                    ; Now check the ZERO flag, unchanged since
   LDI     R24, ACSZ_DOn & 0xFF   ;  the CPI; when BREQ not taken, change R24
Go:RCALL   ALocal_Print           ; Call the routine to print selected string
   INC     R26                    ; Increment the saved Discrete Input selector
   CPI     R26, B00100110         ; If it is still valid, and B000 to B101 in
   BRLO    ADemoDI_Loop           ;  the 3 LSBits are those valid, loop back
   JMP     APrintNewLine          ; Output CR, LF and exit to the caller
   
Local_Print:
   JMP     APrintFLASHASCIIz      ; Provides a single FAR Printing call

CSZ_DIn:  .STRING  "Discrete Inputs:"
CSZ_DOn:  .STRING  " ON"
CSZ_DOff: .STRING  " OFF"
CSZ_DIO:  .STRING  "Discrete I/O:"

.ORG 0x1050                       ; Set second ORG to have a know address
   ADIW    R26, 0                 ; If there is a command line tail, skip past
   BRNE    AOK                    ;  the immediate exit
   RET
OK:MOVW    R24, R26               ; Set the command line tail pointer passed
   CALL    AParseValue            ; Get the first value after "0x1050"
   MOV     R30, R22               ; Save DO selected; no need to check, really
   MOVW    R24, R26               ; Reset the "next string" pointer
   LDI     R22, '='               ; Parse a value after the first equal sign
   CALL    AParseValueAfter         ; The Low Order BYTE is returned in R24
   MOV     R24, R30               ; Restore the Discrete Output index saved
   ANDI    R24, B00000111         ; Limit it to the PINs BITs
   ORI     R24, B00100000         ; Combine in the PORTC specifier
   CALL    ADiscreteOutput        ; Request the Discrete Output be changed
   LDI     R24, ACSZ_DIO & 0xFF   ; Point to the second string's LSByte
   RJMP    ADemoDI + 2            ; Jump to set the MSByte and print all DIOs
Test it:
m>@ 0x1000
Discrete Inputs: OFF OFF OFF OFF OFF ON
m>@ 0x1050 3 = 1
Discrete I/O: OFF OFF OFF ON OFF ON
m>@ 0x1050 2 = 99
Discrete I/O: OFF OFF ON ON OFF ON
m>@ 0x1050 4 =  1
Discrete I/O: OFF OFF ON ON ON ON
m>@ 0x1050 0 = -1
Discrete I/O: ON OFF ON ON ON ON
m>O*=2
m>@ 0x1000
Discrete Inputs: OFF ON OFF OFF OFF OFF
m>o* = 63
m>@ 0x1000
Discrete Inputs: ON ON ON ON ON ON
m>@ 0x1050 0 = 0
Discrete I/O: OFF ON ON ON ON ON
m>@ 0x1050 1 = 0
Discrete I/O: OFF OFF ON ON ON ON
m>@ 0x1050 4 = 0
Discrete I/O: OFF OFF ON ON OFF ON
m>@ 0x1050 6 = 0
Discrete I/O: OFF OFF ON ON OFF OFF
m>@ 0x1050 5  = 0
Discrete I/O: OFF OFF ON ON OFF OFF
m>@ 0x1050 3  =  0
Discrete I/O: OFF OFF ON OFF OFF OFF
m>@ 0x1050 2  =   0
Discrete I/O: OFF OFF OFF OFF OFF OFF
m>@ 0x1000
Discrete Inputs: OFF OFF OFF OFF OFF OFF
m>                                                                                        
Notes:The "PPPP0ppp" means that the high four (4) BITs select the PORT, where PORTB = B0001, PORTC = B0010, PORTD = B0011. The low three (3) BITs select the single PIN to be set or read. B000 selects DIO 0, B001 selects DIO 1, B010 selects DIO 2, etc.
The PORT options above are for the 328P microcontroller. Other PORT options are valid for other processors. The last possible valid PORT is PORTL = B1010.
The EEbWS2812_DefPandP also has this format bit also uses the BIT unused here to use the next byte (EEbWS2812_DefPins) as a bitmask for multiple Discrete Outputs.
Dropin: 
(setup
code)
;   Setup for the DiscreteInput() call:
; Passed:  R24 BYTE bPortandPin single PORT and Pin selected: PPPP0ppp format
; Returns: R24 BYTE bValue      status if the single Discrete Input: 0 or 1
; Alters:  R24 and the FLAGs

;   Setup for the DiscreteOutput() call:
; Passed:  R24 BYTE bPortandPin single PORT and Pin selected: PPPP0ppp format
;          R22 BYTE bValueToSet 0 turns the DO off, any other turns it ON
; Returns: R24 BYTE bStata      status of ALL the Discrete I/O on that PORT
; Alters:  R24 and the FLAGs
Also see: The Discrete Output Update command and the ReadAtoDValue System Functions.