diff options
Diffstat (limited to 'ldmicro/iolist.cpp')
-rw-r--r-- | ldmicro/iolist.cpp | 885 |
1 files changed, 885 insertions, 0 deletions
diff --git a/ldmicro/iolist.cpp b/ldmicro/iolist.cpp new file mode 100644 index 0000000..e2fc032 --- /dev/null +++ b/ldmicro/iolist.cpp @@ -0,0 +1,885 @@ +//----------------------------------------------------------------------------- +// Copyright 2007 Jonathan Westhues +// +// This file is part of LDmicro. +// +// LDmicro is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// LDmicro is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with LDmicro. If not, see <http://www.gnu.org/licenses/>. +//------ +// +// Routines to maintain the processor I/O list. Whenever the user changes the +// name of an element, rebuild the I/O list from the PLC program, so that new +// assigned names are automatically reflected in the I/O list. Also keep a +// list of old I/Os that have been deleted, so that if the user deletes a +// a name and then recreates it the associated settings (e.g. pin number) +// will not be forgotten. Also the dialog box for assigning I/O pins. +// Jonathan Westhues, Oct 2004 +//----------------------------------------------------------------------------- +#include "linuxUI.h" +//#include <commctrl.h> +#include <stdio.h> +#include <stdlib.h> + +#include "ldmicro.h" + +// I/O that we have seen recently, so that we don't forget pin assignments +// when we re-extract the list +#define MAX_IO_SEEN_PREVIOUSLY 512 +static struct { + char name[MAX_NAME_LEN]; + int type; + int pin; +} IoSeenPreviously[MAX_IO_SEEN_PREVIOUSLY]; +static int IoSeenPreviouslyCount; + +// // stuff for the dialog box that lets you choose pin assignments +// static BOOL DialogDone; +// static BOOL DialogCancel; + +// static HWND IoDialog; + +// static HWND PinList; +// static HWND OkButton; +// static HWND CancelButton; + +// // stuff for the popup that lets you set the simulated value of an analog in +// static HWND AnalogSliderMain; +// static HWND AnalogSliderTrackbar; +// static BOOL AnalogSliderDone; +// static BOOL AnalogSliderCancel; + + +//----------------------------------------------------------------------------- +// Append an I/O to the I/O list if it is not in there already. +//----------------------------------------------------------------------------- +static void AppendIo(char *name, int type) +{ + int i; + for(i = 0; i < Prog.io.count; i++) { + if(strcmp(Prog.io.assignment[i].name, name)==0) { + if(type != IO_TYPE_GENERAL && Prog.io.assignment[i].type == + IO_TYPE_GENERAL) + { + Prog.io.assignment[i].type = type; + } + // already in there + return; + } + } + if(i < MAX_IO) { + Prog.io.assignment[i].type = type; + Prog.io.assignment[i].pin = NO_PIN_ASSIGNED; + strcpy(Prog.io.assignment[i].name, name); + (Prog.io.count)++; + } +} + +//----------------------------------------------------------------------------- +// Move an I/O pin into the `seen previously' list. This means that if the +// user creates input Xasd, assigns it a pin, deletes, and then recreates it, +// then it will come back with the correct pin assigned. +//----------------------------------------------------------------------------- +static void AppendIoSeenPreviously(char *name, int type, int pin) +{ + if(strcmp(name+1, "new")==0) return; + + int i; + for(i = 0; i < IoSeenPreviouslyCount; i++) { + if(strcmp(name, IoSeenPreviously[i].name)==0 && + type == IoSeenPreviously[i].type) + { + if(pin != NO_PIN_ASSIGNED) { + IoSeenPreviously[i].pin = pin; + } + return; + } + } + if(IoSeenPreviouslyCount >= MAX_IO_SEEN_PREVIOUSLY) { + // maybe improve later; just throw away all our old information, and + // the user might have to reenter the pin if they delete and recreate + // things + IoSeenPreviouslyCount = 0; + } + + i = IoSeenPreviouslyCount; + IoSeenPreviously[i].type = type; + IoSeenPreviously[i].pin = pin; + strcpy(IoSeenPreviously[i].name, name); + IoSeenPreviouslyCount++; +} + +//----------------------------------------------------------------------------- +// Walk a subcircuit, calling ourselves recursively and extracting all the +// I/O names out of it. +//----------------------------------------------------------------------------- +static void ExtractNamesFromCircuit(int which, void *any) +{ + ElemLeaf *l = (ElemLeaf *)any; + + switch(which) { + case ELEM_PARALLEL_SUBCKT: { + ElemSubcktParallel *p = (ElemSubcktParallel *)any; + int i; + for(i = 0; i < p->count; i++) { + ExtractNamesFromCircuit(p->contents[i].which, + p->contents[i].d.any); + } + break; + } + case ELEM_SERIES_SUBCKT: { + ElemSubcktSeries *s = (ElemSubcktSeries *)any; + int i; + for(i = 0; i < s->count; i++) { + ExtractNamesFromCircuit(s->contents[i].which, + s->contents[i].d.any); + } + break; + } + case ELEM_CONTACTS: + switch(l->d.contacts.name[0]) { + case 'R': + AppendIo(l->d.contacts.name, IO_TYPE_INTERNAL_RELAY); + break; + + case 'Y': + AppendIo(l->d.contacts.name, IO_TYPE_DIG_OUTPUT); + break; + + case 'X': + AppendIo(l->d.contacts.name, IO_TYPE_DIG_INPUT); + break; + + default: + oops(); + break; + } + break; + + case ELEM_COIL: + AppendIo(l->d.coil.name, l->d.coil.name[0] == 'R' ? + IO_TYPE_INTERNAL_RELAY : IO_TYPE_DIG_OUTPUT); + break; + + case ELEM_TON: + case ELEM_TOF: + AppendIo(l->d.timer.name, which == ELEM_TON ? IO_TYPE_TON : + IO_TYPE_TOF); + break; + + case ELEM_RTO: + AppendIo(l->d.timer.name, IO_TYPE_RTO); + break; + + case ELEM_MOVE: + AppendIo(l->d.move.dest, IO_TYPE_GENERAL); + break; + + case ELEM_ADD: + case ELEM_SUB: + case ELEM_MUL: + case ELEM_DIV: + AppendIo(l->d.math.dest, IO_TYPE_GENERAL); + break; + + case ELEM_FORMATTED_STRING: + if(strlen(l->d.fmtdStr.var) > 0) { + AppendIo(l->d.fmtdStr.var, IO_TYPE_UART_TX); + } + break; + + case ELEM_UART_SEND: + AppendIo(l->d.uart.name, IO_TYPE_UART_TX); + break; + + case ELEM_UART_RECV: + AppendIo(l->d.uart.name, IO_TYPE_UART_RX); + break; + + case ELEM_SET_PWM: + AppendIo(l->d.setPwm.name, IO_TYPE_PWM_OUTPUT); + break; + + case ELEM_CTU: + case ELEM_CTD: + case ELEM_CTC: + AppendIo(l->d.counter.name, IO_TYPE_COUNTER); + break; + + case ELEM_READ_ADC: + AppendIo(l->d.readAdc.name, IO_TYPE_READ_ADC); + break; + + case ELEM_SHIFT_REGISTER: { + int i; + for(i = 0; i < l->d.shiftRegister.stages; i++) { + char str[MAX_NAME_LEN+10]; + sprintf(str, "%s%d", l->d.shiftRegister.name, i); + AppendIo(str, IO_TYPE_GENERAL); + } + break; + } + + case ELEM_LOOK_UP_TABLE: + AppendIo(l->d.lookUpTable.dest, IO_TYPE_GENERAL); + break; + + case ELEM_PIECEWISE_LINEAR: + AppendIo(l->d.piecewiseLinear.dest, IO_TYPE_GENERAL); + break; + + case ELEM_PLACEHOLDER: + case ELEM_COMMENT: + case ELEM_SHORT: + case ELEM_OPEN: + case ELEM_MASTER_RELAY: + case ELEM_ONE_SHOT_RISING: + case ELEM_ONE_SHOT_FALLING: + case ELEM_EQU: + case ELEM_NEQ: + case ELEM_GRT: + case ELEM_GEQ: + case ELEM_LES: + case ELEM_LEQ: + case ELEM_RES: + case ELEM_PERSIST: + break; + + default: + oops(); + } +} + +//----------------------------------------------------------------------------- +// Compare function to qsort() the I/O list. Group by type, then +// alphabetically within each section. +//----------------------------------------------------------------------------- +static int CompareIo(const void *av, const void *bv) +{ + PlcProgramSingleIo *a = (PlcProgramSingleIo *)av; + PlcProgramSingleIo *b = (PlcProgramSingleIo *)bv; + + if(a->type != b->type) { + return a->type - b->type; + } + + if(a->pin == NO_PIN_ASSIGNED && b->pin != NO_PIN_ASSIGNED) return 1; + if(b->pin == NO_PIN_ASSIGNED && a->pin != NO_PIN_ASSIGNED) return -1; + + return strcmp(a->name, b->name); +} + +//----------------------------------------------------------------------------- +// Wipe the I/O list and then re-extract it from the PLC program, taking +// care not to forget the pin assignments. Gets passed the selected item +// as an index into the list; modifies the list, so returns the new selected +// item as an index into the new list. +//----------------------------------------------------------------------------- +int GenerateIoList(int prevSel) +{ + int i, j; + + char selName[MAX_NAME_LEN]; + if(prevSel >= 0) { + strcpy(selName, Prog.io.assignment[prevSel].name); + } + + if(IoSeenPreviouslyCount > MAX_IO_SEEN_PREVIOUSLY/2) { + // flush it so there's lots of room, and we don't run out and + // forget important things + IoSeenPreviouslyCount = 0; + } + + // remember the pin assignments + for(i = 0; i < Prog.io.count; i++) { + AppendIoSeenPreviously(Prog.io.assignment[i].name, + Prog.io.assignment[i].type, Prog.io.assignment[i].pin); + } + // wipe the list + Prog.io.count = 0; + // extract the new list so that it must be up to date + for(i = 0; i < Prog.numRungs; i++) { + ExtractNamesFromCircuit(ELEM_SERIES_SUBCKT, Prog.rungs[i]); + } + + for(i = 0; i < Prog.io.count; i++) { + if(Prog.io.assignment[i].type == IO_TYPE_DIG_INPUT || + Prog.io.assignment[i].type == IO_TYPE_DIG_OUTPUT || + Prog.io.assignment[i].type == IO_TYPE_READ_ADC) + { + for(j = 0; j < IoSeenPreviouslyCount; j++) { + if(strcmp(Prog.io.assignment[i].name, + IoSeenPreviously[j].name)==0) + { + Prog.io.assignment[i].pin = IoSeenPreviously[j].pin; + break; + } + } + } + } + + qsort(Prog.io.assignment, Prog.io.count, sizeof(PlcProgramSingleIo), + CompareIo); + + if(prevSel >= 0) { + for(i = 0; i < Prog.io.count; i++) { + if(strcmp(Prog.io.assignment[i].name, selName)==0) + break; + } + if(i < Prog.io.count) + return i; + } + // no previous, or selected was deleted + return -1; +} + +//----------------------------------------------------------------------------- +// Load the I/O list from a file. Since we are just loading pin assignments, +// put it into IoSeenPreviously so that it will get used on the next +// extraction. +//----------------------------------------------------------------------------- +BOOL LoadIoListFromFile(FILE *f) +{ + char line[80]; + char name[MAX_NAME_LEN]; + int pin; + while(fgets(line, sizeof(line), f)) { + if(strcmp(line, "END\n")==0) { + return TRUE; + } + // Don't internationalize this! It's the file format, not UI. + if(sscanf(line, " %s at %d", name, &pin)==2) { + int type; + switch(name[0]) { + case 'X': type = IO_TYPE_DIG_INPUT; break; + case 'Y': type = IO_TYPE_DIG_OUTPUT; break; + case 'A': type = IO_TYPE_READ_ADC; break; + default: oops(); + } + AppendIoSeenPreviously(name, type, pin); + } + } + return FALSE; +} + +//----------------------------------------------------------------------------- +// Write the I/O list to a file. Since everything except the pin assignment +// can be extracted from the schematic, just write the Xs and Ys. +//----------------------------------------------------------------------------- +void SaveIoListToFile(FILE *f) +{ + int i; + for(i = 0; i < Prog.io.count; i++) { + if(Prog.io.assignment[i].type == IO_TYPE_DIG_INPUT || + Prog.io.assignment[i].type == IO_TYPE_DIG_OUTPUT || + Prog.io.assignment[i].type == IO_TYPE_READ_ADC) + { + // Don't internationalize this! It's the file format, not UI. + fprintf(f, " %s at %d\n", Prog.io.assignment[i].name, + Prog.io.assignment[i].pin); + } + } +} + +//----------------------------------------------------------------------------- +// Dialog proc for the popup that lets you set the value of an analog input for +// simulation. +//----------------------------------------------------------------------------- +// static LRESULT CALLBACK AnalogSliderDialogProc(HWND hwnd, UINT msg, +// WPARAM wParam, LPARAM lParam) +// { +// switch (msg) { +// case WM_CLOSE: +// case WM_DESTROY: +// AnalogSliderDone = TRUE; +// AnalogSliderCancel = TRUE; +// return 1; + +// default: +// return DefWindowProc(hwnd, msg, wParam, lParam); +// } +// } + +//----------------------------------------------------------------------------- +// A little toolbar-style window that pops up to allow the user to set the +// simulated value of an ADC pin. +//----------------------------------------------------------------------------- +// void ShowAnalogSliderPopup(char *name) +// { +// WNDCLASSEX wc; +// memset(&wc, 0, sizeof(wc)); +// wc.cbSize = sizeof(wc); + +// wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC | +// CS_DBLCLKS; +// wc.lpfnWndProc = (WNDPROC)AnalogSliderDialogProc; +// wc.hInstance = Instance; +// wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; +// wc.lpszClassName = "LDmicroAnalogSlider"; +// wc.lpszMenuName = NULL; +// wc.hCursor = LoadCursor(NULL, IDC_ARROW); + +// RegisterClassEx(&wc); + +// POINT pt; +// GetCursorPos(&pt); + +// SWORD currentVal = GetAdcShadow(name); + +// SWORD maxVal; +// if(Prog.mcu) { +// maxVal = Prog.mcu->adcMax; +// } else { +// maxVal = 1023; +// } +// if(maxVal == 0) { +// Error(_("No ADC or ADC not supported for selected micro.")); +// return; +// } + +// int left = pt.x - 10; +// // try to put the slider directly under the cursor (though later we might +// // realize that that would put the popup off the screen) +// int top = pt.y - (15 + (73*currentVal)/maxVal); + +// RECT r; +// SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + +// if(top + 110 >= r.bottom) { +// top = r.bottom - 110; +// } +// if(top < 0) top = 0; + +// AnalogSliderMain = CreateWindowClient(0, "LDmicroAnalogSlider", "I/O Pin", +// WS_VISIBLE | WS_POPUP | WS_DLGFRAME, +// left, top, 30, 100, NULL, NULL, Instance, NULL); + +// AnalogSliderTrackbar = CreateWindowEx(0, TRACKBAR_CLASS, "", WS_CHILD | +// TBS_AUTOTICKS | TBS_VERT | TBS_TOOLTIPS | WS_CLIPSIBLINGS | WS_VISIBLE, +// 0, 0, 30, 100, AnalogSliderMain, NULL, Instance, NULL); +// SendMessage(AnalogSliderTrackbar, TBM_SETRANGE, FALSE, +// MAKELONG(0, maxVal)); +// SendMessage(AnalogSliderTrackbar, TBM_SETTICFREQ, (maxVal + 1)/8, 0); +// SendMessage(AnalogSliderTrackbar, TBM_SETPOS, TRUE, currentVal); + +// EnableWindow(MainWindow, FALSE); +// ShowWindow(AnalogSliderMain, TRUE); +// SetFocus(AnalogSliderTrackbar); + +// DWORD ret; +// MSG msg; +// AnalogSliderDone = FALSE; +// AnalogSliderCancel = FALSE; + +// SWORD orig = GetAdcShadow(name); + +// while(!AnalogSliderDone && (ret = GetMessage(&msg, NULL, 0, 0))) { +// SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0); + +// if(msg.message == WM_KEYDOWN) { +// if(msg.wParam == VK_RETURN) { +// AnalogSliderDone = TRUE; +// break; +// } else if(msg.wParam == VK_ESCAPE) { +// AnalogSliderDone = TRUE; +// AnalogSliderCancel = TRUE; +// break; +// } +// } else if(msg.message == WM_LBUTTONUP) { +// if(v != orig) { +// AnalogSliderDone = TRUE; +// } +// } +// SetAdcShadow(name, v); + +// TranslateMessage(&msg); +// DispatchMessage(&msg); +// } + +// if(!AnalogSliderCancel) { +// SWORD v = (SWORD)SendMessage(AnalogSliderTrackbar, TBM_GETPOS, 0, 0); +// SetAdcShadow(name, v); +// } + +// EnableWindow(MainWindow, TRUE); +// DestroyWindow(AnalogSliderMain); +// ListView_RedrawItems(IoList, 0, Prog.io.count - 1); +// } + +//----------------------------------------------------------------------------- +// Window proc for the contacts dialog box +//----------------------------------------------------------------------------- +// static LRESULT CALLBACK IoDialogProc(HWND hwnd, UINT msg, WPARAM wParam, +// LPARAM lParam) +// { +// switch (msg) { +// case WM_COMMAND: { +// HWND h = (HWND)lParam; +// if(h == OkButton && wParam == BN_CLICKED) { +// DialogDone = TRUE; +// } else if(h == CancelButton && wParam == BN_CLICKED) { +// DialogDone = TRUE; +// DialogCancel = TRUE; +// } else if(h == PinList && HIWORD(wParam) == LBN_DBLCLK) { +// DialogDone = TRUE; +// } +// break; +// } + +// case WM_CLOSE: +// case WM_DESTROY: +// DialogDone = TRUE; +// DialogCancel = TRUE; +// return 1; + +// default: +// return DefWindowProc(hwnd, msg, wParam, lParam); +// } + +// return 1; +// } + +//----------------------------------------------------------------------------- +// Create our window class; nothing exciting. +//----------------------------------------------------------------------------- +// static BOOL MakeWindowClass() +// { +// WNDCLASSEX wc; +// memset(&wc, 0, sizeof(wc)); +// wc.cbSize = sizeof(wc); + +// wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC | +// CS_DBLCLKS; +// wc.lpfnWndProc = (WNDPROC)IoDialogProc; +// wc.hInstance = Instance; +// wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; +// wc.lpszClassName = "LDmicroIo"; +// wc.lpszMenuName = NULL; +// wc.hCursor = LoadCursor(NULL, IDC_ARROW); +// wc.hIcon = (HICON)LoadImage(Instance, MAKEINTRESOURCE(4000), +// IMAGE_ICON, 32, 32, 0); +// wc.hIconSm = (HICON)LoadImage(Instance, MAKEINTRESOURCE(4000), +// IMAGE_ICON, 16, 16, 0); + +// return RegisterClassEx(&wc); +// } + +// static void MakeControls(void) +// { +// HWND textLabel = CreateWindowEx(0, WC_STATIC, _("Assign:"), +// WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, +// 6, 1, 80, 17, IoDialog, NULL, Instance, NULL); +// NiceFont(textLabel); + +// PinList = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTBOX, "", +// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | WS_VSCROLL | +// LBS_NOTIFY, 6, 18, 95, 320, IoDialog, NULL, Instance, NULL); +// FixedFont(PinList); + +// OkButton = CreateWindowEx(0, WC_BUTTON, _("OK"), +// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON, +// 6, 325, 95, 23, IoDialog, NULL, Instance, NULL); +// NiceFont(OkButton); + +// CancelButton = CreateWindowEx(0, WC_BUTTON, _("Cancel"), +// WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE, +// 6, 356, 95, 23, IoDialog, NULL, Instance, NULL); +// NiceFont(CancelButton); +// } + +// void ShowIoDialog(int item) +// { +// if(!Prog.mcu) { +// MessageBox(MainWindow, +// _("No microcontroller has been selected. You must select a " +// "microcontroller before you can assign I/O pins.\r\n\r\n" +// "Select a microcontroller under the Settings menu and try " +// "again."), _("I/O Pin Assignment"), MB_OK | MB_ICONWARNING); +// return; +// } + +// if(Prog.mcu->whichIsa == ISA_ANSIC) { +// Error(_("Can't specify I/O assignment for ANSI C target; compile and " +// "see comments in generated source code.")); +// return; +// } + +// if(Prog.mcu->whichIsa == ISA_INTERPRETED) { +// Error(_("Can't specify I/O assignment for interpretable target; see " +// "comments in reference implementation of interpreter.")); +// return; +// } + +// if(Prog.io.assignment[item].name[0] != 'X' && +// Prog.io.assignment[item].name[0] != 'Y' && +// Prog.io.assignment[item].name[0] != 'A') +// { +// Error(_("Can only assign pin number to input/output pins (Xname or " +// "Yname or Aname).")); +// return; +// } + +// if(Prog.io.assignment[item].name[0] == 'A' && Prog.mcu->adcCount == 0) { +// Error(_("No ADC or ADC not supported for this micro.")); +// return; +// } + +// if(strcmp(Prog.io.assignment[item].name+1, "new")==0) { +// Error(_("Rename I/O from default name ('%s') before assigning " +// "MCU pin."), Prog.io.assignment[item].name); +// return; +// } + +// MakeWindowClass(); + +// // We need the TOOLWINDOW style, or else the window will be forced to +// // a minimum width greater than our current width. And without the +// // APPWINDOW style, it becomes impossible to get the window back (by +// // Alt+Tab or taskbar). +// IoDialog = CreateWindowClient(WS_EX_TOOLWINDOW | WS_EX_APPWINDOW, +// "LDmicroIo", _("I/O Pin"), +// WS_OVERLAPPED | WS_SYSMENU, +// 100, 100, 107, 387, NULL, NULL, Instance, NULL); + +// MakeControls(); + +// SendMessage(PinList, LB_ADDSTRING, 0, (LPARAM)_("(no pin)")); +// int i; +// for(i = 0; i < Prog.mcu->pinCount; i++) { +// int j; +// for(j = 0; j < Prog.io.count; j++) { +// if(j == item) continue; +// if(Prog.io.assignment[j].pin == Prog.mcu->pinInfo[i].pin) { +// goto cant_use_this_io; +// } +// } + +// if(UartFunctionUsed() && Prog.mcu && +// ((Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.rxPin) || +// (Prog.mcu->pinInfo[i].pin == Prog.mcu->uartNeeds.txPin))) +// { +// goto cant_use_this_io; +// } + +// if(PwmFunctionUsed() && +// Prog.mcu->pinInfo[i].pin == Prog.mcu->pwmNeedsPin) +// { +// goto cant_use_this_io; +// } + +// if(Prog.io.assignment[item].name[0] == 'A') { +// for(j = 0; j < Prog.mcu->adcCount; j++) { +// if(Prog.mcu->adcInfo[j].pin == Prog.mcu->pinInfo[i].pin) { +// // okay; we know how to connect it up to the ADC +// break; +// } +// } +// if(j == Prog.mcu->adcCount) { +// goto cant_use_this_io; +// } +// } + +// char buf[40]; +// if(Prog.mcu->pinCount <= 21) { +// sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin, +// Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port, +// Prog.mcu->pinInfo[i].bit); +// } else { +// sprintf(buf, "%3d %c%c%d", Prog.mcu->pinInfo[i].pin, +// Prog.mcu->portPrefix, Prog.mcu->pinInfo[i].port, +// Prog.mcu->pinInfo[i].bit); +// } +// SendMessage(PinList, LB_ADDSTRING, 0, (LPARAM)buf); +// cant_use_this_io:; +// } + +// EnableWindow(MainWindow, FALSE); +// ShowWindow(IoDialog, TRUE); +// SetFocus(PinList); + +// MSG msg; +// DWORD ret; +// DialogDone = FALSE; +// DialogCancel = FALSE; +// while((ret = GetMessage(&msg, NULL, 0, 0)) && !DialogDone) { +// if(msg.message == WM_KEYDOWN) { +// if(msg.wParam == VK_RETURN) { +// DialogDone = TRUE; +// break; +// } else if(msg.wParam == VK_ESCAPE) { +// DialogDone = TRUE; +// DialogCancel = TRUE; +// break; +// } +// } + +// if(IsDialogMessage(IoDialog, &msg)) continue; +// TranslateMessage(&msg); +// DispatchMessage(&msg); +// } + +// if(!DialogCancel) { +// int sel = SendMessage(PinList, LB_GETCURSEL, 0, 0); +// char pin[16]; +// SendMessage(PinList, LB_GETTEXT, (WPARAM)sel, (LPARAM)pin); +// if(strcmp(pin, _("(no pin)"))==0) { +// int i; +// for(i = 0; i < IoSeenPreviouslyCount; i++) { +// if(strcmp(IoSeenPreviously[i].name, +// Prog.io.assignment[item].name)==0) +// { +// IoSeenPreviously[i].pin = NO_PIN_ASSIGNED; +// } +// } +// Prog.io.assignment[item].pin = NO_PIN_ASSIGNED; +// } else { +// Prog.io.assignment[item].pin = atoi(pin); +// // Only one name can be bound to each pin; make sure that there's +// // not another entry for this pin in the IoSeenPreviously list, +// // that might get used if the user creates a new pin with that +// // name. +// int i; +// for(i = 0; i < IoSeenPreviouslyCount; i++) { +// if(IoSeenPreviously[i].pin == atoi(pin)) { +// IoSeenPreviously[i].pin = NO_PIN_ASSIGNED; +// } +// } +// } +// } + +// EnableWindow(MainWindow, TRUE); +// DestroyWindow(IoDialog); +// return; +// } + +//----------------------------------------------------------------------------- +// Called in response to a notify for the listview. Handles click, text-edit +// operations etc., but also gets called to find out what text to display +// where (LPSTR_TEXTCALLBACK); that way we don't have two parallel copies of +// the I/O list to keep in sync. +//----------------------------------------------------------------------------- +// void IoListProc(NMHDR *h) +// { +// switch(h->code) { +// case LVN_GETDISPINFO: { +// NMLVDISPINFO *i = (NMLVDISPINFO *)h; +// int item = i->item.iItem; +// switch(i->item.iSubItem) { +// case LV_IO_PIN: +// // Don't confuse people by displaying bogus pin assignments +// // for the C target. +// if(Prog.mcu && (Prog.mcu->whichIsa == ISA_ANSIC || +// Prog.mcu->whichIsa == ISA_INTERPRETED) ) +// { +// strcpy(i->item.pszText, ""); +// break; +// } + +// PinNumberForIo(i->item.pszText, +// &(Prog.io.assignment[item])); +// break; + +// case LV_IO_TYPE: { +// char *s = IoTypeToString(Prog.io.assignment[item].type); +// strcpy(i->item.pszText, s); +// break; +// } +// case LV_IO_NAME: +// strcpy(i->item.pszText, Prog.io.assignment[item].name); +// break; + +// case LV_IO_PORT: { +// // Don't confuse people by displaying bogus pin assignments +// // for the C target. +// if(Prog.mcu && Prog.mcu->whichIsa == ISA_ANSIC) { +// strcpy(i->item.pszText, ""); +// break; +// } + +// int type = Prog.io.assignment[item].type; +// if(type != IO_TYPE_DIG_INPUT && type != IO_TYPE_DIG_OUTPUT +// && type != IO_TYPE_READ_ADC) +// { +// strcpy(i->item.pszText, ""); +// break; +// } + +// int pin = Prog.io.assignment[item].pin; +// if(pin == NO_PIN_ASSIGNED || !Prog.mcu) { +// strcpy(i->item.pszText, ""); +// break; +// } + +// if(UartFunctionUsed() && Prog.mcu) { +// if((Prog.mcu->uartNeeds.rxPin == pin) || +// (Prog.mcu->uartNeeds.txPin == pin)) +// { +// strcpy(i->item.pszText, _("<UART needs!>")); +// break; +// } +// } + +// if(PwmFunctionUsed() && Prog.mcu) { +// if(Prog.mcu->pwmNeedsPin == pin) { +// strcpy(i->item.pszText, _("<PWM needs!>")); +// break; +// } +// } + +// int j; +// for(j = 0; j < Prog.mcu->pinCount; j++) { +// if(Prog.mcu->pinInfo[j].pin == pin) { +// sprintf(i->item.pszText, "%c%c%d", +// Prog.mcu->portPrefix, +// Prog.mcu->pinInfo[j].port, +// Prog.mcu->pinInfo[j].bit); +// break; +// } +// } +// if(j == Prog.mcu->pinCount) { +// sprintf(i->item.pszText, _("<not an I/O!>")); +// } +// break; +// } + +// case LV_IO_STATE: { +// if(InSimulationMode) { +// char *name = Prog.io.assignment[item].name; +// DescribeForIoList(name, i->item.pszText); +// } else { +// strcpy(i->item.pszText, ""); +// } +// break; +// } + +// } +// break; +// } +// case LVN_ITEMACTIVATE: { +// NMITEMACTIVATE *i = (NMITEMACTIVATE *)h; +// if(InSimulationMode) { +// char *name = Prog.io.assignment[i->iItem].name; +// if(name[0] == 'X') { +// SimulationToggleContact(name); +// } else if(name[0] == 'A') { +// ShowAnalogSliderPopup(name); +// } +// } else { +// UndoRemember(); +// ShowIoDialog(i->iItem); +// ProgramChanged(); +// InvalidateRect(MainWindow, NULL, FALSE); +// } +// break; +// } +// } +// } |