Quelltext /~heha/enas/Convac-Ätzer/Firmware-190517.zip/Digital.cpp

/* Projekt Convac-Ätzer
   Zugriff auf digitale Ein- und Ausgangskarten
   Henrik Haftmann, 161123
   
   Beim Controller ist angeschlossen, siehe
   http://www.tu-chemnitz.de/~heha/enas/Convac-Ätzer/Eagle.zip/
   
   Die Eingangskarte an Steckplatz 1 ist die ehemalige
   Prozessorplatine mit 32 Eingängen und ebenso vielen Optokopplern.
   Die Anschlusszuordnung ist nun anders als in der Dokumentation:
   e2 c2 e4 c4 e6 c6 usw. bis e32 c32.
   
   Die Ausgangskarten sind an den Steckplätzen 2 und 4.
   Diese fressen, wenn alle Ausgänge aktiv, 500 mA.
   Die Anschlusszuordnung ist gleich geblieben.
   Das Statusbit erscheint als Eingang an Bit 28
 */

#include "Convac.h"
#include <string.h>

// Für Byte 0..3: Eingang lesen
// Für Byte 4..11: Ausgangswert rücklesen (nicht von der Karte möglich)
// Sonderfall: Byte 7 und 11: Statusbit der Ausgabekarten rücklesen
byte DIGITAL::getIo(byte bytenr) {
 byte r=0;
 if (bytenr<4) r=~BUS::ioRead(BUS::BA_INPUT|bytenr);
 else if (!(~bytenr&3))
   r=BUS::ioRead(bytenr&4?BUS::BA_OUTPUT1:BUS::BA_OUTPUT2)>>3&0x10;
 return r^ios[bytenr];
}

bool DIGITAL::getBit(byte bitnr) {
 return shrb(getIo(bitnr>>3),bitnr)&1;
}

// Für Byte 0..3: Togglen des Eingangswertes setzen/löschen (zur Simulation)
// Für Byte 4..12: Ausgang setzen
void DIGITAL::setIo(byte bytenr, byte value) {
 ios[bytenr]=value;
 if (bytenr>=4) {
  byte h=bytenr&4?BUS::BA_OUTPUT1:BUS::BA_OUTPUT2;
  bytenr=(bytenr&3)+1;	// Adresse 0 = Status der 24×BTS412B im Bit 7
  if (bytenr==4) bytenr=7;	// Relais auf dieser Adresse (4 ungenutzte Bits)
  BUS::ioWrite(h|bytenr,~value);
 }
}

void DIGITAL::setBit(byte bitnr,bool bit) {
 byte m=shlb(1,bitnr);
 bitnr>>=3;
 if (bit) m|=ios[bitnr]; else m=~m&ios[bitnr];
 setIo(bitnr,m);
}

// Ausgänge setzen
void DIGITAL::initOutputs() {
 for (byte i=4; i<12; i++) setIo(i,ios[i]);
}

void DIGITAL::getInputs(byte data[12]) {
 for (byte i=0; i<12; i++) data[i]=getIo(i);
}

byte DIGITAL::getDir(byte b) {
 if (byte(b-=4)>=byte(8)) return 0;	// Eingänge
 if (byte(b&=3)!=3) return 0xFF;	// 24 Transistorausgänge
 return 0x0F;				// 4 Relaisausgänge
}

byte DIGITAL::getAvail(byte b) {
 if (b==7 || b==11) return 0x1F;	// obere 3 Bits nicht verfügbar
 return 0xFF;
}

const PROGMEM char eca[] = "eca";
void mkeca(byte start, byte nr) {
 udiv_t q=udiv(nr,3);
 char*p=floatstr(start+(byte(q.quot)<<1));	// 6-8-10-…-20
 p+=strlen(p);
 *p++=pgm_read_byte(eca+q.rem);		// 'e','c' oder 'a' (Funktionsname!)
 *p=0;
}

void DIGITAL::getPin(byte bitnr) {
 char*p=sbuf;
 if (bitnr<32) {
  floatstr(2+(bitnr&0x1E));	// Pinnummer wie im Schaltplan:
  p+=strlen(p);			// Erst Ziffern, dann Buchstabe
  *p++=bitnr&1?'c':'e';
  *p=0;
 }else{
  bitnr&=0x1F;	// beide Analogausgabekarten sind gleich
  if (bitnr<24) mkeca(6,bitnr);
  else if ((bitnr-=24)<4) {
   floatstr(22+(bitnr<<1));
   p+=strlen(p);
   strcpy_P(p,eca);	// alle 3 Buchstaben weil Relaisausgang
  }else{
   *p++='-';		// kein Anschluss für die Treiberüberwachung
   *p=0;
  }
 }
}

byte DIGITAL::ios[12];	// 32 Eingänge (Xor), 64 Ausgänge (Mirror)

/* Digitale Ausgangskarte, Schaltung
IC6 74HC245 Datenbustreiber (Puffer)
	1	!WR(8)
	19	!SEL(9)
IC4 74HC244 (zum Rücklesen der Ausgangsstati?)
IC2,3,5,7 = 74HC373 (Flipflops = Ausgaberegister)
	1	(6)
IC1 74HC138
	A0	A0
	A1	A1
	A2	A2
	!E1	!IOSTB(7)
	!E2	!SEL(9)
	E3	5P
	Y0	IC4-1-19 IC4-17 vom Optokoppler	IC4-3	IC6-3	IC6-17	D7
	Y1	IC7-11
	Y2	IC5-11
	Y3	IC3-11
	Y4	-
	Y5	-
	Y6	-
	Y7	IC2-11	Relais
 */
Vorgefundene Kodierung: UTF-80