Skip to content

Commit

Permalink
Merge pull request #193 from Jesus89/tinyfpga-support
Browse files Browse the repository at this point in the history
Tinyfpga support
  • Loading branch information
Jesus89 authored Jan 11, 2018
2 parents 9c12e5a + 15e66e2 commit 3fa9528
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 90 deletions.
6 changes: 5 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@
"icon": "resources/images/icestudio-logo.png"
},
"apio": {
"min": "0.3.0b3",
"min": "0.3.0b4",
"max": "0.4.0",
"extras": [
"tinyfpgab"
],
"external": ""
},
"collection": "0.3.0",
"engines": {
"node": ">= 0.10.0"
},
Expand Down
2 changes: 1 addition & 1 deletion app/resources/boards/TinyFPGA-B2/pinout.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"type": "inout", "name": "PIN_1_USB_DP", "value": "A3"}, {"type": "inout", "name": "PIN_2_USB_DN", "value": "A4"}, {"type": "input", "name": "CLK", "value": "B4"}, {"type": "inout", "name": "PIN_4", "value": "B2"}, {"type": "inout", "name": "PIN_5", "value": "A2"}, {"type": "inout", "name": "PIN_6", "value": "A1"}, {"type": "inout", "name": "PIN_7", "value": "B1"}, {"type": "inout", "name": "PIN_8", "value": "C1"}, {"type": "inout", "name": "PIN_9", "value": "D1"}, {"type": "inout", "name": "PIN_10", "value": "E1"}, {"type": "inout", "name": "PIN_11", "value": "G1"}, {"type": "inout", "name": "PIN_12", "value": "H1"}, {"type": "inout", "name": "PIN_13", "value": "J1"}, {"type": "inout", "name": "PIN_14_SDO", "value": "G6"}, {"type": "inout", "name": "PIN_15_SDI", "value": "H7"}, {"type": "inout", "name": "PIN_16_SCK", "value": "G7"}, {"type": "inout", "name": "PIN_17_SS", "value": "F7"}, {"type": "inout", "name": "PIN_18", "value": "D9"}, {"type": "inout", "name": "PIN_19", "value": "C9"}, {"type": "inout", "name": "PIN_20", "value": "E8"}, {"type": "inout", "name": "PIN_21", "value": "A9"}, {"type": "inout", "name": "PIN_22", "value": "A8"}, {"type": "inout", "name": "PIN_23", "value": "A7"}, {"type": "inout", "name": "PIN_24", "value": "A6"}]
[{"type": "inout", "name": "USB_DP", "value": "A3"}, {"type": "inout", "name": "USB_DM", "value": "A4"}, {"type": "input", "name": "CLK", "value": "B4"}, {"type": "inout", "name": "PIN_4", "value": "B2"}, {"type": "inout", "name": "PIN_5", "value": "A2"}, {"type": "inout", "name": "PIN_6", "value": "A1"}, {"type": "inout", "name": "PIN_7", "value": "B1"}, {"type": "inout", "name": "PIN_8", "value": "C1"}, {"type": "inout", "name": "PIN_9", "value": "D1"}, {"type": "inout", "name": "PIN_10", "value": "E1"}, {"type": "inout", "name": "PIN_11", "value": "G1"}, {"type": "inout", "name": "PIN_12", "value": "H1"}, {"type": "inout", "name": "PIN_13", "value": "J1"}, {"type": "inout", "name": "SDO", "value": "G6"}, {"type": "inout", "name": "SDI", "value": "H7"}, {"type": "inout", "name": "SCK", "value": "G7"}, {"type": "inout", "name": "SS", "value": "F7"}, {"type": "inout", "name": "PIN_18", "value": "D9"}, {"type": "inout", "name": "PIN_19", "value": "C9"}, {"type": "inout", "name": "PIN_20", "value": "E8"}, {"type": "inout", "name": "PIN_21", "value": "A9"}, {"type": "inout", "name": "PIN_22", "value": "A8"}, {"type": "inout", "name": "PIN_23", "value": "A7"}, {"type": "inout", "name": "PIN_24", "value": "A6"}]
32 changes: 16 additions & 16 deletions app/resources/boards/TinyFPGA-B2/pinout.pcf
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
# -----------------------------------------------------------------------------
#
# TinyFPGA B-series information: https://github.com/tinyfpga/TinyFPGA-B-Series/
### left side of board
set_io --warn-no-port PIN_1_USB_DP A3
set_io --warn-no-port PIN_2_USB_DN A4
set_io --warn-no-port CLK B4 # input
set_io --warn-no-port PIN_4 B2
set_io --warn-no-port PIN_5 A2
set_io --warn-no-port PIN_6 A1
set_io --warn-no-port PIN_7 B1
set_io --warn-no-port PIN_8 C1
set_io --warn-no-port PIN_9 D1

# -- Left side of board
set_io --warn-no-port USB_DP A3
set_io --warn-no-port USB_DM A4
set_io --warn-no-port CLK B4 # input
set_io --warn-no-port PIN_4 B2
set_io --warn-no-port PIN_5 A2
set_io --warn-no-port PIN_6 A1
set_io --warn-no-port PIN_7 B1
set_io --warn-no-port PIN_8 C1
set_io --warn-no-port PIN_9 D1
set_io --warn-no-port PIN_10 E1
set_io --warn-no-port PIN_11 G1
set_io --warn-no-port PIN_12 H1
set_io --warn-no-port PIN_13 J1

### right side of board
set_io --warn-no-port PIN_14_SDO G6
set_io --warn-no-port PIN_15_SDI H7
set_io --warn-no-port PIN_16_SCK G7
set_io --warn-no-port PIN_17_SS F7
# -- Right side of board
set_io --warn-no-port SDO G6
set_io --warn-no-port SDI H7
set_io --warn-no-port SCK G7
set_io --warn-no-port SS F7
set_io --warn-no-port PIN_18 D9
set_io --warn-no-port PIN_19 C9
set_io --warn-no-port PIN_20 E8
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/services/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ angular.module('icestudio')
}

this.showToolchain = function () {
return this.selectedBoard.info.interface !== 'GPIO';
return (this.selectedBoard && this.selectedBoard.info.interface !== 'GPIO') || false;
};

this.showDrivers = function () {
return this.selectedBoard && (this.selectedBoard.info.interface === 'FTDI' || this.selectedBoard.info.interface === 'Serial');
return (this.selectedBoard && (this.selectedBoard.info.interface === 'FTDI' || this.selectedBoard.info.interface === 'Serial')) || false;
};

});
74 changes: 49 additions & 25 deletions app/scripts/services/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,40 @@ angular.module('icestudio')

if (stdout) {
// - Apio errors
if (stdout.indexOf('[upload] Error') !== -1 ||
stdout.indexOf('Error: board not detected') !== -1) {
resultAlert = alertify.error(gettextCatalog.getString('Board {{name}} not detected', { name: utils.bold(common.selectedBoard.info.label) }), 30);
if (stdout.indexOf('Error: board not connected') !== -1) {
resultAlert = alertify.error(gettextCatalog.getString('Board {{name}} not connected', { name: utils.bold(common.selectedBoard.info.label) }), 30);
}
else if (stdout.indexOf('Error: unkown board') !== -1) {
else if (stdout.indexOf('Error: board not available') !== -1) {
resultAlert = alertify.error(gettextCatalog.getString('Board {{name}} not available', { name: utils.bold(common.selectedBoard.info.label) }), 30);
setupDriversAlert();
}
else if (stdout.indexOf('Error: unknown board') !== -1) {
resultAlert = alertify.error(gettextCatalog.getString('Unknown board'), 30);
}
else if (stdout.indexOf('[upload] Error') !== -1) {
switch (common.selectedBoard.name) {
// TinyFPGA-B2 programmer errors
case 'TinyFPGA-B2':
var match = stdout.match(/Bootloader\snot\sactive/g);
if (match && match.length === 3) {
resultAlert = alertify.error(gettextCatalog.getString('Bootloader not active'), 30);
}
else if (stdout.indexOf('Device or resource busy') !== -1) {
resultAlert = alertify.error(gettextCatalog.getString('Board {{name}} not available', { name: utils.bold(common.selectedBoard.info.label) }), 30);
setupDriversAlert();
}
else if (stdout.indexOf('device disconnected or multiple access on port') !== -1) {
resultAlert = alertify.error(gettextCatalog.getString('Board {{name}} disconnected', { name: utils.bold(common.selectedBoard.info.label) }), 30);
}
else {
resultAlert = alertify.error(gettextCatalog.getString(stdout), 30);
}
break;
default:
resultAlert = alertify.error(gettextCatalog.getString(stdout), 30);
}
console.warn(stdout);
}
// Yosys error (Mac OS)
else if (stdout.indexOf('Library not loaded:') !== -1 &&
stdout.indexOf('libffi') !== -1) {
Expand Down Expand Up @@ -724,7 +751,6 @@ angular.module('icestudio')
apioInstallIcestorm,
apioInstallIverilog,
apioInstallDrivers,
apioInstallScons,
installationCompleted
]);
}
Expand Down Expand Up @@ -782,7 +808,8 @@ angular.module('icestudio')
// Remote installation

function installOnlineApio(callback) {
updateProgress('pip install -U apio', 30);
var extraPackages = _package.apio.extras || [];
updateProgress('pip install -U apio[' + extraPackages.toString() + ']', 30);
utils.installOnlineApio(callback);
}

Expand All @@ -803,19 +830,14 @@ angular.module('icestudio')

function apioInstallDrivers(callback) {
if (common.WIN32) {
updateProgress('apio install drivers', 80);
updateProgress('apio install drivers', 90);
utils.apioInstall('drivers', callback);
}
else {
callback();
}
}

function apioInstallScons(callback) {
updateProgress('apio install scons', 90);
utils.apioInstall('scons', callback);
}

function installationCompleted(callback) {
checkToolchain(function() {
if (toolchain.installed) {
Expand All @@ -834,20 +856,22 @@ angular.module('icestudio')
}

function setupDriversAlert() {
var message = gettextCatalog.getString('Click here to <b>setup the drivers</b>');
if (!infoAlert) {
setTimeout(function() {
infoAlert = alertify.message(message, 30);
infoAlert.callback = function(isClicked) {
infoAlert = null;
if (isClicked) {
if (resultAlert) {
resultAlert.dismiss(false);
if (common.showDrivers()) {
var message = gettextCatalog.getString('Click here to <b>setup the drivers</b>');
if (!infoAlert) {
setTimeout(function() {
infoAlert = alertify.message(message, 30);
infoAlert.callback = function(isClicked) {
infoAlert = null;
if (isClicked) {
if (resultAlert) {
resultAlert.dismiss(false);
}
$rootScope.$broadcast('enableDrivers');
}
$rootScope.$broadcast('enableDrivers');
}
};
}, 1000);
};
}, 1000);
}
}
}

Expand Down
15 changes: 5 additions & 10 deletions app/scripts/services/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,13 @@ angular.module('icestudio')

this.executeCommand = function(command, callback) {
nodeChildProcess.exec(command.join(' '),
function (error, stdout, stderr) {
function (error, stdout/*, stderr*/) {
// console.log(error, stdout, stderr);
if (error) {
this.enableKeyEvents();
this.enableClickEvents();
callback(true);
angular.element('#progress-message')
.text(stderr);
angular.element('#progress-bar')
.addClass('notransition progress-bar-danger')
.removeClass('progress-bar-info progress-bar-striped active')
.text('Error')
.attr('aria-valuenow', 100)
.css('width', '100%');
alertify.error(stdout, 30);
}
else {
callback();
Expand Down Expand Up @@ -178,7 +171,9 @@ angular.module('icestudio')
};

this.installOnlineApio = function(callback) {
this.executeCommand([coverPath(common.ENV_PIP), 'install', '-U', 'apio">=' + _package.apio.min + ',<' + _package.apio.max + '"'], callback);
var versionRange = '">=' + _package.apio.min + ',<' + _package.apio.max + '"';
var extraPackages = _package.apio.extras || [];
this.executeCommand([coverPath(common.ENV_PIP), 'install', '-U', 'apio[' + extraPackages.toString() + ']' + versionRange], callback);
};

this.apioInstall = function(_package, callback) {
Expand Down
3 changes: 2 additions & 1 deletion gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = function(grunt) {
// Project configuration
grunt.initConfig({

pkg: grunt.file.readJSON('package.json'),
pkg: grunt.file.readJSON('app/package.json'),

// Automatically inject Bower components into the app
wiredep: {
Expand Down Expand Up @@ -139,6 +139,7 @@ module.exports = function(grunt) {
apioMin: '<%=pkg.apio.min%>',
apioMax: '<%=pkg.apio.max%>',
buildDir: 'dist/',
extraPackages: '<%=pkg.apio.extras%>',
platforms: platforms
}
},
Expand Down
5 changes: 0 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
"gettext": "grunt gettext",
"postinstall": "npmpd && cd app && npm install && bower install && cd ../tasks && npm install && cd .. && grunt getcollection"
},
"apio": {
"min": "0.3.0b3",
"max": "0.4.0"
},
"collection": "0.3.0",
"devDependencies": {
"bower": "^1.8.0",
"grunt": "^1.0.1",
Expand Down
60 changes: 31 additions & 29 deletions tasks/toolchain_builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ inherits(ToolchainBuilder, EventEmitter);
module.exports = ToolchainBuilder;
function ToolchainBuilder(options) {
var defaults = {
apioMin: '0.1.9',
apioMax: '1.0.0',
apioMin: '',
apioMax: '',
buildDir: './build',
cacheDir: './cache',
extraPackages: [],
platforms: ['linux32', 'linux64', 'win32', 'win64', 'osx32', 'osx64'],
};

Expand Down Expand Up @@ -57,32 +58,32 @@ ToolchainBuilder.prototype.build = function (callback) {
this.emit('log', this.options.venvPip);
// Let's create the standalone toolchains
this.ensurePythonIsAvailable()
.then(this.extractVirtualenv.bind(this))
.then(this.createVirtualenv.bind(this))
.then(this.downloadApio.bind(this))
.then(this.installApio.bind(this))
.then(this.downloadApioPackages.bind(this))
.then(this.packageApio.bind(this))
.then(this.packageApioPackages.bind(this))
.then(this.createDefaultToolchains.bind(this))
.then(function(info) {
var result = info || this;

if(hasCallback) {
callback(false, result);
} else {
done.resolve(result);
}
})
.catch(function(error) {
if(hasCallback) {
callback(error);
} else {
done.reject(error);
}
});
.then(this.extractVirtualenv.bind(this))
.then(this.createVirtualenv.bind(this))
.then(this.downloadApio.bind(this))
.then(this.installApio.bind(this))
.then(this.downloadApioPackages.bind(this))
.then(this.packageApio.bind(this))
.then(this.packageApioPackages.bind(this))
.then(this.createDefaultToolchains.bind(this))
.then(function(info) {
var result = info || this;

if(hasCallback) {
callback(false, result);
} else {
done.resolve(result);
}
})
.catch(function(error) {
if(hasCallback) {
callback(error);
} else {
done.reject(error);
}
});

return hasCallback ? true : done.promise;
return hasCallback ? true : done.promise;
};

ToolchainBuilder.prototype.ensurePythonIsAvailable = function () {
Expand Down Expand Up @@ -132,9 +133,10 @@ ToolchainBuilder.prototype.downloadApio = function () {
var self = this;
self.emit('log', '> Download apio');
return new Promise(function(resolve, reject) {
var versionRange = '">=' + self.options.apioMin + ',<' + self.options.apioMax + '"';
var command = [
self.options.venvPip, 'download', '--dest', self.options.apioDir,
'apio">=' + self.options.apioMin + ',<' + self.options.apioMax + '"'
'apio[' + self.options.extraPackages.toString() + ']' + versionRange
];
childProcess.exec(command.join(' '),
function(error/*, stdout, stderr*/) {
Expand Down Expand Up @@ -171,7 +173,7 @@ ToolchainBuilder.prototype.downloadApioPackages = function () {
self.emit('log', '> Download apio packages');
return new Promise(function(resolve, reject) {
function command(dest, platform) {
var packages = ['system', 'icestorm', 'iverilog', 'scons', (platform.startsWith('windows') ? 'drivers' : '')];
var packages = ['system', 'icestorm', 'iverilog', (platform.startsWith('windows') ? 'drivers' : '')];
return [ (process.platform === 'win32' ? 'set' : 'export'),
'APIO_HOME_DIR=' + dest + (process.platform === 'win32' ? '&' : ';'),
self.options.venvApio, 'install', '--platform', platform ].concat(packages);
Expand Down

0 comments on commit 3fa9528

Please sign in to comment.