"""
012345678901234567890123456789012345678901234567890123456789
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Raspberry Pi Pico 7-Segment Counter 1 Digit (MicroPython)┃
┃ Project name: 7-Segment_Counter_Parallel_bus.            ┃
┃ (My Wokwi.com project)                                   ┃
┃ Filename: 7-Segment_Counter_v23.py                       ┃
┃                                                          ┃
┃ Purpose: A program to demonstrate the use of a           ┃
┃ seven-segment digit to display a running count and,      ┃
┃ demonstrate blinking digits. While using an 8-bit        ┃
┃ parallel port.                                           ┃
┃                                                          ┃
┃ This is for developing a simple and efficient function   ┃
┃ along with using attribute flag bits to control          ┃
┃ on/off state. Buttons control blink.                     ┃
┃                                                          ┃
┃ Status/ Rev: designing / ver 2.3d                        ┃
┃ Date:        2023-05-22                                  ┃
┃ By:          Phil. N                                     ┃
┃ License: GNU General Public License (GNU GPL).           ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
https://docs.micropython.org/en/latest/library/machine.Pin.html

Notes:
All 8-Segments including DP connects to GPIO 0 to GPIO 7.
GP0 = SegA, GP1 = SegB, GP2 = SegC... GP6 = SegG, GP7 = DP.

V23 Works, the display counts down, and LED stays on, because 
code for the button and interupt has not been written.

Warring - If a varable is undeclared Wokwi will NOT run the program.

"""

from machine import Pin
from utime import sleep
from rp2 import PIO, StateMachine, asm_pio

pins = [
	Pin(0, Pin.OUT),  # A
	Pin(1, Pin.OUT),  # B
	Pin(2, Pin.OUT),  # C
	Pin(3, Pin.OUT),  # D
	Pin(4, Pin.OUT),  # E
	Pin(5, Pin.OUT),  # F
	Pin(6, Pin.OUT),  # G
	Pin(7, Pin.OUT)   # DP
]

ctrlDig = Pin(8, Pin.OUT)   # Controle digit line for digit 1.

'''
 7-segment display layout
		   A
		 -----
	  F |  G  | B
		 -----
	  E |     | C
		 ----- o Dp
		   D

  |    Display Segments:      |
  |     MSN     |     LSN     |
  | 07 06 05 04 | 03 02 01 00 |
  | Dp  G  F  E |  D  C  B  A |


'''

# 7-segment display digit patterns
# Seg-Pattern:      	Character:  Array number:
SegmentPattern = [
	0x3F,			#		0			0
	0x06,			#		1			1
	0x5B,			#		2			2
	0x4F,			#		3			3
	0x66,			#		4			4
	0x6D,			#		5			5
	0x7D,			#		6			6
	0x07,			#		7			7
	0x7F,			#		8			8
	0x6F,			#		9			9
	0x77,			#	    A			10
	0x7C,			#		b			11
	0x39,			#		C			12
	0x5E,			#		d			13
	0x79,			#		E			14
	0x71,			#		F			15
	0x00,			#		Off			16
	0x80,           #       .           17 (Dp)
	0x76,           #       H           18
	0x1E,           #       J           19
	0x38,			#		L			20
	0x5C,           #       o           21
	0x73,           #       P           22
	0x3E,           #       U           23
	0xFF,			#		Test		24 (All on)
	]

maxNum = 24         # Maximum displayable characters.

# Need to implement Digits Memory (digitsMem) into current program.
# Decide whether to store a value or segment pattern. 

# memY = 0
# digX = 0
# aDigit = digitsMem[memY][digX]


en_led = Pin(12, Pin.OUT)   # Enable LED going to future 5801 chip.

# Setup interrupt pin for the 1 button.
# intPin = Pin(14, Pin.IN, Pin.PULL_UP)

# Any button outputs always need to be set to a low value to cause an interrupt.
# Green button.

col0_pb = Pin(14, Pin.OUT)

# greenpbState = 0	# Not yet used, need to get interrupt handler working first. 
# ledValue = 1		# Note this variable does work, and changes LED state.
en_ledValue = 1		# Note this variable does work, and changes LED state.
counter = 0			# For counting through all the displayable digits.

'''
# ****** F U N C T I O N S ***********************************************
# *** Place any functions here!
'''
''' ***********************************************************************
 * Function     : reset()
 * Date / Ver   : 04-18-2023 / V2.1d
 * PreCondition : None
 * Input        : None
 * Output       : None
 * Side Effects : None
 * Note         : Turns off all segments on the 7-segment display.
 *                Then turns off control digit line.
 *                Defaults col0_pb to low for interrupt detection.  
 ********************************************************************** '''
def reset():
	for pin in pins:
		pin.value(1)
	
	ctrlDig.value(0)
	col0_pb.value(0)


''' ***********************************************************************
 * Function     : alert()
 * Date / Ver   : 04-18-2023 / V1.0d
 * PreCondition : None
 * Input        : None
 * Output       : None
 * Side Effects : None
 * Note         : Interrupt handler function.
 ********************************************************************** '''
# interrupt handler function
'''
def alert(intPin):
	global en_ledValue	# Make variable global so it can be changed within function.
	global ledValue
	en_ledValue = 0		# Note: indicates interrupt handler is not being called. 
	#ledValue = 0 		# because these leds stay no, they should go off.


# ******* D E C L A R A T I O N S ***************************************
# ** Declare executable instructions here(!)

# attach the interrupt to the intPin, and will call the function "alert".
# RISING or FALLING
intPin.irq(trigger = Pin.IRQ_FALLING, handler = alert)
'''
reset()

@asm_pio(out_init=(rp2.PIO.OUT_HIGH,) * 8, out_shiftdir=PIO.SHIFT_RIGHT, 
 autopull=True, pull_thresh=16)
def paral_prog():
	pull()  
	out(pins, 8)  

parallelPort = StateMachine(0, paral_prog, freq=10000000, out_base=Pin(0))
parallelPort.active(1)

ctrlDig.value(1)							# Turn on controle digit line.
en_ledValue = 1

# ******** Main Processing Loop *************
# *** Round and around the Mobius loop...

while True:
	if counter > maxNum:
		counter = 0

	ctrlDig.value(1)							# Turn on controle digit line.
	
	# digitSeg = SegmentPattern[counter]    # Use this for common cathode 7-segment display. 
	digitSeg = ~SegmentPattern[counter]     # Use this for common anode 7-segment display. 

	portWrt = digitSeg
	parallelPort.put(digitSeg)        

	counter += 1

	sleep(0.75)

	en_ledValue = 1
	en_led.value(en_ledValue)

# End of program.
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT
pico:GP0
pico:GP1
pico:GND.1
pico:GP2
pico:GP3
pico:GP4
pico:GP5
pico:GND.2
pico:GP6
pico:GP7
pico:GP8
pico:GP9
pico:GND.3
pico:GP10
pico:GP11
pico:GP12
pico:GP13
pico:GND.4
pico:GP14
pico:GP15
pico:GP16
pico:GP17
pico:GND.5
pico:GP18
pico:GP19
pico:GP20
pico:GP21
pico:GND.6
pico:GP22
pico:RUN
pico:GP26
pico:GP27
pico:GND.7
pico:GP28
pico:ADC_VREF
pico:3V3
pico:3V3_EN
pico:GND.8
pico:VSYS
pico:VBUS
sevseg1:COM.1
sevseg1:COM.2
sevseg1:A
sevseg1:B
sevseg1:C
sevseg1:D
sevseg1:E
sevseg1:F
sevseg1:G
sevseg1:DP
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
r1:1
r1:2
led1:A
led1:C