|
@echo off |
|
|
|
REM MIT License |
|
|
|
REM Copyright (c) 2023 Abel Naya |
|
|
|
REM Permission is hereby granted, free of charge, to any person obtaining a copy |
|
REM of this software and associated documentation files (the "Software"), to deal |
|
REM in the Software without restriction, including without limitation the rights |
|
REM to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
REM copies of the Software, and to permit persons to whom the Software is |
|
REM furnished to do so, subject to the following conditions: |
|
|
|
REM The above copyright notice and this permission notice shall be included in all |
|
REM copies or substantial portions of the Software. |
|
|
|
REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
REM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
REM AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
REM LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
REM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
REM SOFTWARE |
|
|
|
START powershell -noprofile -command " Write-Host Asking for admin permissions...; Start-Process Powershell -Verb RunAs -ArgumentList ' cd ''%~dp0''; Invoke-Expression (Get-Content -Path ''%0'' -Delimiter ''START_OF_POWERSHELL_SCRIPT'')[2] ' " |
|
goto:eof |
|
|
|
The text above is bat(ch) that calls powershell to run as admin, the text below is powershell that will be run afterwards |
|
|
|
START_OF_POWERSHELL_SCRIPT |
|
|
|
Write-Host Initializing... |
|
$pwd | Write-Host |
|
|
|
# parameters |
|
$padding = 5 |
|
$height = 25 |
|
$width = 500 |
|
$separation = 0 |
|
|
|
# init form |
|
Add-Type -assembly System.Windows.Forms |
|
$form = New-Object System.Windows.Forms.Form |
|
$form.Text ='Device enabler tool' |
|
$form.FormBorderStyle = 'FixedDialog' |
|
$form.width=0 |
|
|
|
|
|
# init VIVADO |
|
$Vivado = Get-ChildItem -Path "C:/Xilinx/Vivado/" | ForEach-Object { "C:/Xilinx/Vivado/$_/bin/vivado.bat" } | Where-Object { Test-Path $_ } | Select-Object -First 1 |
|
Write-Host "Vivado detected: $Vivado" |
|
|
|
# init picker |
|
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog |
|
$FileBrowser.Title = "Choose bitstream" |
|
$FileBrowser.Filter = 'Bitstream|*.bit|All|*.*' |
|
$FileBrowser.RestoreDirectory = $false |
|
|
|
# init console manager |
|
Add-Type -Name Window -Namespace Console -MemberDefinition ' |
|
[DllImport("Kernel32.dll")] |
|
public static extern IntPtr GetConsoleWindow(); |
|
|
|
[DllImport("user32.dll")] |
|
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); |
|
|
|
[DllImport("user32.dll")] |
|
public static extern bool IsZoomed(IntPtr hWnd); |
|
'; |
|
$PSConsole = [Console.Window]::GetConsoleWindow() |
|
$PSConsole | Add-Member -NotePropertyName Visible -NotePropertyValue $false |
|
$form.Add_Shown({ |
|
[Console.Window]::ShowWindow($PSConsole, 0) |
|
$PSConsole.Visible = $false |
|
}.GetNewClosure()) |
|
|
|
# main function |
|
function UpdateForm { $xUpdateForm = Get-Item function:UpdateForm |
|
# clear |
|
$form.Controls.Clear() |
|
|
|
# define function to add buttons |
|
function AddButton ($text, $listener) { |
|
$button = New-Object System.Windows.Forms.Button |
|
$button.Location = New-Object System.Drawing.Size( |
|
($padding + ($form.Controls.Count % 2)*($width/2+$padding)), |
|
([int][Math]::Floor($form.Controls.Count/2)*($height + $padding)+ $separation) |
|
) |
|
$button.Size = New-Object System.Drawing.Size(($width/2), $height) |
|
$button.Text = $text |
|
$button.Add_Click({& $listener $button}.GetNewClosure()) |
|
$form.Controls.Add($button) |
|
} |
|
|
|
# get devices |
|
$nl = [System.Environment]::NewLine |
|
$ids = ((pnputil /enum-devices /class USB /connected | Out-String) -split $nl + $nl) | Select-Object -Skip 1 | ForEach-Object { |
|
$lines = $_ -split $nl |
|
[pscustomobject] @{ |
|
id = ($lines[0] -split ': *')[1] |
|
deviceDescription = ($lines[1] -split ': *')[1] |
|
status = ($lines[5] -split ': *')[1] |
|
} |
|
} | Where-Object { |
|
$_.deviceDescription -eq 'USB Serial Converter A' #'USB Composite Device' |
|
} | ForEach-Object { |
|
if($_.status -eq 'started'){ $_.status = 'Enabled'} |
|
if($_.status -eq 'Iniciado'){ $_.status = 'Enabled'} |
|
$_ | Add-Member -NotePropertyName name -NotePropertyValue ($_.id -split '\\')[2] |
|
$_ |
|
} |
|
|
|
# define function to enable only a particular device |
|
$enableOnly = { param($id, $button) |
|
# enable that device |
|
$button.Text = "Enabling... (1/$($ids.length))" |
|
Write-Host "Enabling $id" |
|
pnputil /enable-device $id |
|
|
|
# disable the rest |
|
$ids | ForEach-Object { $_.id } | Where-Object { $_ -ne $id } | ForEach-Object {$i=2} { |
|
$button.Text = "Disabling... ($i/$($ids.length))" |
|
Write-Host "Disabling $_" |
|
pnputil /disable-device $_ |
|
|
|
$i++ |
|
} |
|
}.GetNewClosure() |
|
|
|
# define function to enable all devices |
|
$enableAll = { param($button) |
|
$ids | ForEach-Object { $_.id } | ForEach-Object {$i=1} { |
|
$button.Text = "Enabling... ($i/$($ids.length))" |
|
Write-Host "Enabling $_" |
|
pnputil /enable-device $_ |
|
|
|
$i++ |
|
} |
|
}.GetNewClosure() |
|
|
|
##################################### |
|
|
|
# button to refresh ui |
|
AddButton 'Refresh' $xUpdateForm |
|
|
|
|
|
# button to program all devices with bitfile |
|
AddButton "Program bitstream" { param($button) |
|
if($FileBrowser.ShowDialog() -ne "OK") { return } |
|
Write-Host $FileBrowser.FileName |
|
$button.Text = 'Running...' |
|
# program each one |
|
$ids | ForEach-Object { $_.id } | ForEach-Object {$i=1} { |
|
& $enableOnly $_ $button |
|
|
|
$button.Text = "Programming... ($i/$($ids.length))" |
|
Write-Host "Starting FPGA_programmer" |
|
|
|
(Get-Content -Path './FPGA_programmer.bat' -Delimiter 'START_OF_TCL_SCRIPT')[2] | & $Vivado -mode tcl -nolog -nojournal -verbose -tclargs $FileBrowser.FileName -only | ForEach-Object{ " > $_" } | Write-Host |
|
|
|
Write-Host 'Done' |
|
|
|
$i++ |
|
} |
|
& $enableAll $button |
|
& $xUpdateForm |
|
}.GetNewClosure() |
|
|
|
|
|
# add a button to enable all devices |
|
AddButton "Enable all ($($ids.length))" { param($button) |
|
& $enableAll $button |
|
& $xUpdateForm |
|
}.GetNewClosure() |
|
|
|
|
|
# button to toggle console visibility |
|
$GetVisibilityName = { |
|
if ( $PSConsole.Visible ) { |
|
return "Hide console" |
|
} else { |
|
return "Show console" |
|
} |
|
}.GetNewClosure() |
|
AddButton (& $GetVisibilityName) { param($button) |
|
if ( $PSConsole.Visible ) { |
|
[Console.Window]::ShowWindow($PSConsole, 0) |
|
} else { |
|
[Console.Window]::ShowWindow($PSConsole, 5) |
|
} |
|
$PSConsole.Visible = !$PSConsole.Visible |
|
$button.Text = (& $GetVisibilityName) |
|
}.GetNewClosure() |
|
|
|
# divider |
|
$separation += ($padding*4) |
|
|
|
# add a button for each device (to enable that one) |
|
$ids | ForEach-Object { |
|
$id = $_.id |
|
AddButton "[$($_.status)] Enable $($_.name) only" { param($button) |
|
& $enableOnly $id $button |
|
& $xUpdateForm |
|
}.GetNewClosure() |
|
} |
|
|
|
|
|
|
|
$form.height=0 |
|
$form.AutoSize = $true |
|
$Form.StartPosition = 'CenterScreen' |
|
} |
|
UpdateForm |
|
|
|
Write-Host Ready |
|
$form.showdialog() |