# SPDX-License-Identifier: BSD-2-Clause

from torii.build                  import Connector, Resource, Pins, Clock, Attrs
from torii.build.run              import BuildProducts
from torii.platform.vendor.altera import AlteraPlatform
from torii.platform.resources     import LEDResources, ButtonResources, SwitchResources

__all__ = (
	'ArrowDECAPlatform',
)


class ArrowDECAPlatform(AlteraPlatform):
	device      = '10M50DA' # MAX 10
	package     = 'F484'
	speed       = 'C6'
	suffix      = 'GES'
	default_clk = 'clk50'

	resources   = [
		Resource('clk50', 0, Pins('M8',  dir = 'i'), Clock(50e6), Attrs(io_standard = '2.5 V')),
		Resource('clk50', 1, Pins('P11', dir = 'i'), Clock(50e6), Attrs(io_standard = '3.3 V')),
		Resource('clk50', 2, Pins('N15', dir = 'i'), Clock(50e6), Attrs(io_standard = '1.5 V')),
		Resource('clk10', 0, Pins('M9',  dir = 'i'), Clock(10e6), Attrs(io_standard = '2.5 V')),

		*LEDResources(
			pins = 'C7 C8 A6 B7 C4 A5 B4 C5',
			invert = True,
			attrs = Attrs(io_standard = '1.2 V')
		),
		*ButtonResources(
			pins = 'H21 H22',
			invert = True,
			attrs = Attrs(io_standard = '1.5 V')
		),
		*SwitchResources(
			pins = 'J21 J22',
			attrs = Attrs(io_standard = '1.5 V')
		),
	]

	connectors  = [
		Connector('gpio', 0,
			'W18  Y18  Y19  AA17 AA20 AA19 AB21 AB20 AB19 Y16  V16  '
			'AB18 V15  W17  AB17 AA16 AB16 W16  AB15 W15  Y14  AA15 '
			'AB14 AA14 AB13 AA13 AB12 AA12 AB11 AA11 AB10 Y13  Y11  '
			'W13  W12  W11  V12  V11  V13  V14  Y17  W14  U15  R13  '
		),
		Connector('gpio', 1,
			'Y5   Y6   W6   W7   W8   V8   AB8   V7  R11  AB7  AB6  '
			'AA7  AA6  Y7   V10  U7   W9   W5   R9   W4    P9  V17  '
			'W3   -    -    -    -    -    -    -    -     -   -    '
		),
	]

	def toolchain_program(self, products: BuildProducts, name: str) -> None:
		from os         import environ
		from subprocess import check_call

		quartus_pgm = environ.get('QUARTUS_PGM', 'quartus_pgm')
		with products.extract(f'{name}.sof') as bitstream_filename:
			check_call([
				quartus_pgm, '--haltcc', '--mode', 'JTAG',
				'--operation', 'P;' + bitstream_filename
			])

	@property
	def file_templates(self):
		# Configure the voltages of the I/O banks by appending the global
		# assignments to the template. However, we create our own copy of the
		# file templates before modifying them to avoid modifying the original.
		return {
			**super().file_templates,
			'{{name}}.qsf':
				super().file_templates.get('{{name}}.qsf') +
				r'''
				set_global_assignment -name IOBANK_VCCIO 2.5V -section_id 1A
				set_global_assignment -name IOBANK_VCCIO 2.5V -section_id 1B
				set_global_assignment -name IOBANK_VCCIO 2.5V -section_id 2
				set_global_assignment -name IOBANK_VCCIO 3.3V -section_id 3
				set_global_assignment -name IOBANK_VCCIO 3.3V -section_id 4
				set_global_assignment -name IOBANK_VCCIO 1.5V -section_id 5
				set_global_assignment -name IOBANK_VCCIO 1.5V -section_id 6
				set_global_assignment -name IOBANK_VCCIO 1.8V -section_id 7
				set_global_assignment -name IOBANK_VCCIO 1.2V -section_id 8

				set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
				set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF
				set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
				set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
				'''
		}


if __name__ == '__main__':
	from ..test.blinky import Blinky
	ArrowDECAPlatform().build(Blinky(), do_program = True)
