2018-08-02 15:46:58 -06:00
|
|
|
import {
|
|
|
|
PinBindingType,
|
|
|
|
PinBindingSpecialAction
|
|
|
|
} from "farmbot/dist/resources/api_resources";
|
2018-07-17 23:08:27 -06:00
|
|
|
import { DropDownItem } from "../../ui";
|
|
|
|
import { gpio } from "./rpi_gpio_diagram";
|
|
|
|
import { flattenDeep, isNumber } from "lodash";
|
2018-07-20 19:52:41 -06:00
|
|
|
import { sysBtnBindings } from "./tagged_pin_binding_init";
|
2019-04-02 13:59:37 -06:00
|
|
|
import { t } from "../../i18next_wrapper";
|
2018-07-17 23:08:27 -06:00
|
|
|
|
|
|
|
export const bindingTypeLabelLookup: { [x: string]: string } = {
|
|
|
|
[PinBindingType.standard]: t("Sequence"),
|
|
|
|
[PinBindingType.special]: t("Action"),
|
|
|
|
"": t("Sequence"),
|
|
|
|
};
|
|
|
|
|
2019-01-28 17:04:27 -07:00
|
|
|
export const bindingTypeList = (): DropDownItem[] =>
|
2018-07-18 19:35:01 -06:00
|
|
|
Object.entries(bindingTypeLabelLookup)
|
|
|
|
.filter(([value, _]) => !(value == ""))
|
|
|
|
.map(([value, label]) => ({ label, value }));
|
|
|
|
|
2018-07-17 23:08:27 -06:00
|
|
|
export const specialActionLabelLookup: { [x: string]: string } = {
|
|
|
|
[PinBindingSpecialAction.emergency_lock]: t("E-STOP"),
|
|
|
|
[PinBindingSpecialAction.emergency_unlock]: t("UNLOCK"),
|
|
|
|
[PinBindingSpecialAction.power_off]: t("Shutdown"),
|
|
|
|
[PinBindingSpecialAction.reboot]: t("Reboot"),
|
|
|
|
[PinBindingSpecialAction.sync]: t("Sync"),
|
|
|
|
[PinBindingSpecialAction.read_status]: t("Read Status"),
|
|
|
|
[PinBindingSpecialAction.take_photo]: t("Take Photo"),
|
|
|
|
"": t("None")
|
|
|
|
};
|
|
|
|
|
|
|
|
export const specialActionList: DropDownItem[] =
|
|
|
|
Object.values(PinBindingSpecialAction)
|
|
|
|
.map((action: PinBindingSpecialAction) =>
|
|
|
|
({ label: specialActionLabelLookup[action], value: action }));
|
|
|
|
|
2018-07-18 19:35:01 -06:00
|
|
|
/** Pin numbers for standard buttons. */
|
2018-07-18 19:36:41 -06:00
|
|
|
export enum ButtonPin {
|
2018-07-18 12:14:10 -06:00
|
|
|
estop = 16,
|
|
|
|
unlock = 22,
|
|
|
|
btn3 = 26,
|
|
|
|
btn4 = 5,
|
|
|
|
btn5 = 20,
|
|
|
|
}
|
|
|
|
|
2018-07-18 19:35:01 -06:00
|
|
|
/** Pin numbers used for LED control; cannot be used in a pin binding. */
|
2018-07-18 12:14:10 -06:00
|
|
|
enum LEDPin {
|
|
|
|
sync = 24,
|
|
|
|
connection = 25,
|
|
|
|
led3 = 12,
|
|
|
|
led4 = 13,
|
|
|
|
estop = 17,
|
|
|
|
unlock = 23,
|
|
|
|
btn3 = 27,
|
|
|
|
btn4 = 6,
|
|
|
|
btn5 = 21,
|
|
|
|
}
|
|
|
|
|
2019-01-28 17:04:27 -07:00
|
|
|
/** Other pins used by FarmBot OS that cannot be used in pin bindings. */
|
|
|
|
enum SystemPins {
|
2019-09-16 15:21:55 -06:00
|
|
|
i2c1_sda = 2,
|
|
|
|
i2c1_scl = 3,
|
|
|
|
spi0_ce1 = 7,
|
|
|
|
spi0_ce0 = 8,
|
|
|
|
spi0_miso = 9,
|
|
|
|
spi0_mosi = 10,
|
|
|
|
spi0_sclk = 11,
|
|
|
|
uart_tx = 14,
|
|
|
|
uart_rx = 15,
|
|
|
|
reset_2560 = 19,
|
2019-01-28 17:04:27 -07:00
|
|
|
}
|
|
|
|
|
2019-09-09 10:09:48 -06:00
|
|
|
const toPinNum = (n: string) => parseInt(n);
|
|
|
|
|
|
|
|
const sysLedBindings: number[] = Object.values(LEDPin).map(toPinNum);
|
|
|
|
const otherSysBindings: number[] = Object.values(SystemPins).map(toPinNum);
|
2018-07-18 19:35:01 -06:00
|
|
|
/** All pin numbers used by FarmBot OS that cannot be used in pin bindings. */
|
2019-01-28 17:04:27 -07:00
|
|
|
export const sysBindings = sysLedBindings.concat(sysBtnBindings, otherSysBindings);
|
2018-07-17 23:08:27 -06:00
|
|
|
|
2019-09-16 15:21:55 -06:00
|
|
|
const piI2c0Pins = [0, 1];
|
|
|
|
export const piSpi0Pins = [7, 8, 9, 10, 11];
|
|
|
|
export const piSpi1Pins = [16, 17, 18, 19, 20, 21];
|
2018-07-18 19:35:01 -06:00
|
|
|
/** Pin numbers used for special purposes by the RPi. (internal pullup, etc.) */
|
2019-09-16 15:21:55 -06:00
|
|
|
export const reservedPiGPIO = piI2c0Pins;
|
2018-07-17 23:08:27 -06:00
|
|
|
|
|
|
|
const LabeledGpioPins: { [x: number]: string } = {
|
2018-07-18 12:14:10 -06:00
|
|
|
[ButtonPin.estop]: "Button 1: E-STOP",
|
|
|
|
[ButtonPin.unlock]: "Button 2: UNLOCK",
|
|
|
|
[ButtonPin.btn3]: "Button 3",
|
|
|
|
[ButtonPin.btn4]: "Button 4",
|
|
|
|
[ButtonPin.btn5]: "Button 5",
|
2018-07-17 23:08:27 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
export const generatePinLabel = (pin: number) =>
|
|
|
|
LabeledGpioPins[pin]
|
|
|
|
? `${LabeledGpioPins[pin]} (Pi ${pin})`
|
|
|
|
: `Pi GPIO ${pin}`;
|
|
|
|
|
2018-07-18 19:35:01 -06:00
|
|
|
/** Raspberry Pi GPIO pin numbers. */
|
2018-07-17 23:08:27 -06:00
|
|
|
export const validGpioPins: number[] =
|
|
|
|
flattenDeep(gpio)
|
|
|
|
.filter(x => isNumber(x))
|
|
|
|
.map((x: number) => x);
|
|
|
|
|
2018-07-18 19:35:01 -06:00
|
|
|
/** Sort fn for pin numbers using their labels. */
|
2018-07-17 23:08:27 -06:00
|
|
|
export const sortByNameAndPin = (a: number, b: number) => {
|
|
|
|
const aLabel = generatePinLabel(a).slice(0, 8);
|
|
|
|
const bLabel = generatePinLabel(b).slice(0, 8);
|
|
|
|
// Sort "Button 1", "Button 2", etc.
|
|
|
|
if (aLabel < bLabel) { return -1; }
|
|
|
|
if (aLabel > bLabel) { return 1; }
|
|
|
|
// Sort "GPIO Pi 4", "GPIO Pi 10", etc.
|
|
|
|
if (a < b) { return -1; }
|
|
|
|
if (a > b) { return 1; }
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
2018-07-18 19:35:01 -06:00
|
|
|
/** Given a list of bound pins, return a list of available pins (DDIs). */
|
2018-07-17 23:08:27 -06:00
|
|
|
export const RpiPinList = (taken: number[]): DropDownItem[] =>
|
|
|
|
validGpioPins
|
|
|
|
.filter(n => !sysBindings.includes(n))
|
|
|
|
.filter(n => !taken.includes(n))
|
|
|
|
.filter(n => !reservedPiGPIO.includes(n))
|
|
|
|
.sort(sortByNameAndPin)
|
|
|
|
.map(n => ({ label: generatePinLabel(n), value: n }));
|
|
|
|
|
2018-07-20 19:52:41 -06:00
|
|
|
/** FarmBot OS default pin binding data used by Pin Bindings widget. */
|
|
|
|
export const stockPinBindings = [
|
2018-07-17 23:08:27 -06:00
|
|
|
{
|
2018-07-20 19:52:41 -06:00
|
|
|
pin_num: ButtonPin.estop,
|
2018-07-17 23:08:27 -06:00
|
|
|
special_action: PinBindingSpecialAction.emergency_lock,
|
|
|
|
binding_type: PinBindingType.special,
|
|
|
|
},
|
|
|
|
{
|
2018-07-20 19:52:41 -06:00
|
|
|
pin_num: ButtonPin.unlock,
|
2018-07-17 23:08:27 -06:00
|
|
|
special_action: PinBindingSpecialAction.emergency_unlock,
|
|
|
|
binding_type: PinBindingType.special,
|
|
|
|
},
|
|
|
|
];
|