File indexing completed on 2024-05-05 05:46:08
0001 /*************************************************************************** 0002 * Copyright (C) 2005 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "parallelportcomponent.h" 0012 #include "port.h" 0013 0014 #include "ecnode.h" 0015 #include "itemdocument.h" 0016 #include "libraryitem.h" 0017 #include "pin.h" 0018 #include "resistance.h" 0019 0020 #include <KLocalizedString> 0021 0022 #include <QDebug> 0023 #include <QPainter> 0024 0025 #include <cmath> 0026 0027 void ParallelPortComponent_dataCallback(void *objV, bool state) { 0028 ParallelPortComponent *objT = static_cast<ParallelPortComponent*>(objV); 0029 objT->dataCallback(state); 0030 } 0031 void ParallelPortComponent_controlCallback(void *objV, bool state) { 0032 ParallelPortComponent *objT = static_cast<ParallelPortComponent*>(objV); 0033 objT->controlCallback(state); 0034 } 0035 0036 Item *ParallelPortComponent::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0037 { 0038 return new ParallelPortComponent(static_cast<ICNDocument *>(itemDocument), newItem, id); 0039 } 0040 0041 LibraryItem *ParallelPortComponent::libraryItem() 0042 { 0043 return new LibraryItem(QStringList(QString("ec/parallel_port")), i18n("Parallel Port"), i18n("Connections"), "ic1.png", LibraryItem::lit_component, ParallelPortComponent::construct); 0044 } 0045 0046 ParallelPortComponent::ParallelPortComponent(ICNDocument *icnDocument, bool newItem, const char *id) 0047 : Component(icnDocument, newItem, id ? id : "parallel_port") 0048 { 0049 m_name = i18n("Parallel Port"); 0050 0051 QPolygon pa(4); 0052 pa[0] = QPoint(-32, -112); 0053 pa[1] = QPoint(32, -104); 0054 pa[2] = QPoint(32, 104); 0055 pa[3] = QPoint(-32, 112); 0056 setItemPoints(pa); 0057 0058 m_pParallelPort = new ParallelPort(); 0059 0060 for (unsigned i = 0; i < 24; ++i) 0061 m_pLogic[i] = nullptr; 0062 0063 ECNode *pin = nullptr; 0064 0065 // BEGIN Data register 0066 for (int i = 0; i < 8; ++i) { 0067 QString id = QString("D%1").arg(i); 0068 QString name = id; 0069 0070 pin = createPin(-40, -80 + 16 * i, 0, id); 0071 addDisplayText(id, QRect(-28, -88 + 16 * i, 28, 16), name, true, Qt::AlignLeft | Qt::AlignVCenter); 0072 0073 m_pLogic[i] = createLogicOut(pin, false); 0074 //m_pLogic[i]->setCallback(this, (CallbackPtr)(&ParallelPortComponent::dataCallback)); 0075 m_pLogic[i]->setCallback2(ParallelPortComponent_dataCallback, this); 0076 } 0077 // END Data register 0078 0079 // BEGIN Status register 0080 QString statusNames[] = {"ERR", "ON", "PE", "ACK", "BUSY"}; 0081 0082 // The statusIDs are referenced in the save file and must not change 0083 QString statusIDs[] = {"ERROR", "ONLINE", "PE", "ACK", "BUSY"}; 0084 0085 // Bits 0...2 in the Status register are not used 0086 for (int i = 3; i < 8; ++i) { 0087 QString id = statusIDs[i - 3]; 0088 QString name = statusNames[i - 3]; 0089 0090 // Bit 3 (pin 15) doesn't not follow the same positioning pattern as 0091 // the other pins in the Status register. 0092 if (i == 3) { 0093 pin = createPin(40, -72, 180, id); 0094 addDisplayText(id, QRect(0, -80, 28, 16), name, true, Qt::AlignRight | Qt::AlignVCenter); 0095 } else { 0096 pin = createPin(-40, -16 + 16 * i, 0, id); 0097 addDisplayText(id, QRect(-28, -24 + 16 * i, 28, 16), name, true, Qt::AlignLeft | Qt::AlignVCenter); 0098 } 0099 0100 m_pLogic[i + 8] = createLogicOut(pin, false); 0101 } 0102 // END Status register 0103 0104 // BEGIN Control register 0105 QString controlNames[] = {"STR", "AUT", "INIT", "SEL"}; 0106 0107 // The controlIDs are referenced in the save file and must not change 0108 QString controlIDs[] = {"STROBE", "AUTO", "INIT", "SELECT"}; 0109 0110 // Bits 4..7 are not used (well; bit 5 is, but not as a pin) 0111 for (int i = 0; i < 4; ++i) { 0112 QString id = controlIDs[i]; 0113 QString name = controlNames[i]; 0114 0115 if (i == 0) { 0116 pin = createPin(-40, -96, 0, id); 0117 addDisplayText(id, QRect(-28, -104, 28, 16), name, true, Qt::AlignLeft | Qt::AlignVCenter); 0118 } else if (i == 1) { 0119 pin = createPin(40, -88, 180, id); 0120 addDisplayText(id, QRect(0, -96, 28, 16), name, true, Qt::AlignRight | Qt::AlignVCenter); 0121 } else { 0122 pin = createPin(40, -88 + i * 16, 180, id); 0123 addDisplayText(id, QRect(0, -96 + i * 16, 28, 16), name, true, Qt::AlignRight | Qt::AlignVCenter); 0124 } 0125 0126 m_pLogic[i + 16] = createLogicOut(pin, false); 0127 //m_pLogic[i + 16]->setCallback(this, (CallbackPtr)(&ParallelPortComponent::controlCallback)); 0128 m_pLogic[i + 16]->setCallback2(ParallelPortComponent_controlCallback, this); 0129 } 0130 // END Control register 0131 0132 #if 0 0133 // And make the rest of the pins ground 0134 for ( int i = 0; i < 8; ++i ) 0135 { 0136 pin = createPin( 40, -24 + i*16, 180, QString("GND%1").arg( i ) ); 0137 pin->pin()->setGroundType( Pin::gt_always ); 0138 } 0139 #endif 0140 0141 Variant *v = createProperty("port", Variant::Type::Combo); 0142 v->setAllowed(ParallelPort::ports()); 0143 v->setCaption(i18n("Port")); 0144 } 0145 0146 ParallelPortComponent::~ParallelPortComponent() 0147 { 0148 for (int i = 0; i < 24; i++) { 0149 if (m_pLogic[i]) { 0150 // m_pLogic[i]->setCallback(nullptr, nullptr); 0151 m_pLogic[i]->setCallback2(nullptr, nullptr); 0152 } 0153 } 0154 delete m_pParallelPort; 0155 } 0156 0157 void ParallelPortComponent::dataChanged() 0158 { 0159 initPort(dataString("port")); 0160 } 0161 0162 void ParallelPortComponent::initPort(const QString &port) 0163 { 0164 if (port.isEmpty()) { 0165 m_pParallelPort->closePort(); 0166 return; 0167 } 0168 0169 if (!m_pParallelPort->openPort(port)) { 0170 p_itemDocument->canvas()->setMessage(i18n("Could not open port %1", port)); 0171 return; 0172 } 0173 } 0174 0175 void ParallelPortComponent::dataCallback(bool) 0176 { 0177 uchar value = 0; 0178 for (unsigned i = 0; i < 8; ++i) 0179 value |= m_pLogic[i + 0]->isHigh() ? 0 : (1 << i); 0180 0181 m_pParallelPort->writeToData(value); 0182 } 0183 0184 void ParallelPortComponent::controlCallback(bool) 0185 { 0186 uchar value = 0; 0187 for (unsigned i = 0; i < 4; ++i) 0188 value |= m_pLogic[i + 16]->isHigh() ? 0 : (1 << i); 0189 0190 m_pParallelPort->writeToControl(value); 0191 } 0192 0193 void ParallelPortComponent::stepNonLogic() 0194 { 0195 uchar status = m_pParallelPort->readFromRegister(ParallelPort::Status); 0196 // Bits 0...2 in the Status register are not used 0197 for (int i = 3; i < 8; ++i) 0198 m_pLogic[i + 8]->setHigh(status | (1 << i)); 0199 } 0200 0201 void ParallelPortComponent::drawShape(QPainter &p) 0202 { 0203 drawPortShape(p); 0204 }