Test

Dependencies:   mbed-dev-OS5_10_4

MySources/Dio.cpp

Committer:
kevman
Date:
2020-08-07
Revision:
0:014fad4dfb9d

File content as of revision 0:014fad4dfb9d:

/*
-------------------------------------------------------------------------------
Programm Name: Dio.CPP
Version:       1.0
Sprache:       C
Compiler:      MBED
Autor:         PS
Copyright:     PS
                 

Funktion:      Digital In/Out auf LPC1768

Modified: 

2016-06  UFa: Aenderungen aufgrund HW-Revision:
               a) Anpassungen in Fkt "SetIRange"
               b) Neue Funktionen (ersetzen z.T. entsp. Macros)
                - SetWe()
                - GeIstGe()
                - ClearWeSchirm()
                - SquareOffsetDown()
                                    
-------------------------------------------------------------------------------
*/
#include "Headers.h"

//#define Spi0IsMisoUp()  (LPC_GPIOA->FIOPIN & 0x00020000)
//#define Spi0IsMisoDown()  (LPC_GPIOA->FIOPIN & ~0x00020000)

BYTE Port; 
#ifdef PGU_EDUCATION
DigitalOut SwPot(PTB20);
DigitalOut SwGal(PTC10);
DigitalOut SwGe(PTC11);
#endif
DigitalOut DoStatusLed(PTA1);


/*-------------------------------------------------------------------------------
Initialisieren der Schaltkontakte
-------------------------------------------------------------------------------*/
int InitDio(void)
{
    
    
#ifdef TOUCH_DISPLAY    
    TftDisp.nTagVWriteCounter = 0; 
    TftDisp.nTagVReadCounter = 0; 
    g_fInCalibrationMode = false;
#endif    

#ifndef PGU_RPA
    g_fCheckSpecial = false;
    g_fSpzFktSwitchIRange = false;
    g_fSpzFktSwitchNoiseGain = false;
    
    Setk(4,0);
    Setk(5,0);
    
	printf("Now SwitchRanges.\n");

	SwitchRangesOnStart();
	printf("Now SetIRange.\n");
	SetIRange(0,0);
#endif
#ifdef PGU_TOUCH
    SetWe(0x00);    //PS 10.12.16  ClearWe entfällt, es wird einfach der Bereich 0 für die WE gesetzt, damit ist die WE1 aktiv
    SetGe(0);
    SetWeSchirm(1); // auf 1 damit die Leitung offen ist und keinen Fehler verursacht
    
    SetSinGainDefault();  // setzt die Verstärker auf Defaultwerte
    SetNoiseGainDefault(); // damit werden auch die Cs Signale auf Default gesetzt

    SetSquareOffset(0);  // Setzt den Offset für Sinuns und Dreieck
    
    SinGenOff();  // Setzt den AD9833 auf Reset und den Cs auf high
#endif

	printf("Now Return.\n");
     return(true);
}
/****************************************************************
 * SetNoiseGainDefault:
 *
 * Setzt die Rauschverstärker Defaultwert. Default ist hier der 
   größte Wert, damit wird das Signal am Ausgang minimal. Je größer der 
   Wert vom X9C103, desto kleiner die Amplitude vom Sinus. 
   Die Position vom X9C103 ist 100, der Index von den Verstärkungsfaktoren
   ist 0
 ****************************************************************/
int SetNoiseGainDefault()
{
    int i;
    
#ifdef ECN
    SwHpZero = true;  // erst mal kurzschließen, damit der nicht so ausschlägt
    CsUNoiseGain = false;
    CsINoiseGain = false;
    DpUpDown = true;
    short_delay(50);        // !!! die short_delay auf keinem Fall entfernen. Es hat sich bei einer 
    
    for(i=0;i<=100;i++)
    {
        DpIncrement = false;
        short_delay(20);        // !!! die short_delay auf keinem Fall entfernen. Es hat sich bei einer 
        DpIncrement = true;
        short_delay(20);        // !!! die short_delay auf keinem Fall entfernen. Es hat sich bei einer 
    }
    GCount.nUNoisePos = 100;
    GCount.nINoisePos = 100;
    GCount.nUnGainItem = 0;
    GCount.nInGainItem = 0;
    
    CsUNoiseGain = true;
    CsINoiseGain = true;
#endif	
    return(true);
}
/****************************************************************
 * SetSinGainDefault:
 *
 * Setzt den Signalverstärker für Sinus auf Default. Default ist hier der 
   kleinste Wert, damit wird das Signal am Ausgang minimal. Je kleiner der 
   Wert vom X9C103, desto kleiner die Amplitude vom Sinus. 
   Die Position vom X9C103 ist 1, der Index von den Verstärkungsfaktoren
   ist 4
 ****************************************************************/
int SetSinGainDefault()
{
    int i;
    
#ifdef SINE_GEN
    CsSinGain = false;
    DpUpDown = false;
    short_delay(50);        // !!! die short_delay auf keinem Fall entfernen. Es hat sich bei einer 
    
    for(i=0;i<=100;i++)
    {
        DpIncrement = false;
        short_delay(20);        // !!! die short_delay auf keinem Fall entfernen. Es hat sich bei einer 
        DpIncrement = true;
        short_delay(20);        // !!! die short_delay auf keinem Fall entfernen. Es hat sich bei einer 
    }
    GCount.nSinGainPos = 1;
    GCount.nSinGainItem = 4;
    
    CsSinGain = true;
#endif	
    return(true);
}

/****************************************************************
 * ReadInput
 *
 * Liest das Inputbit des Tasters
 ****************************************************************/
int ReadInput()
{
/*     if(Spi0IsMisoUp())
    if(ExtStart)
        return true;  // 
    else */
        return false;
}
/****************************************************************
 * SetBaVariablen:
 * Wird von SetK aufgerufen und setzt die Variablen Mv[i].Circuit und Mv[i].BetriebsArt
 * damit andeer Programmstellen wissen in welchem Mode die Kiste ist. 
 ****************************************************************/
int SetBaVariablen(int Nr, bool Level)
{

    if(Nr == MVars.SwitchChn[0])  // 0=1. IZelle, 1= 1. PotGal, 2=2. IZelle, 3=2. PotGal
    {
        if(Level == HIGH)
            Mv[0].Circuit = 1;
        else
            Mv[0].Circuit = 0;
    }
    if(Nr == MVars.SwitchChn[1])  // 0=1. IZelle, 1= 1. PotGal, 2=2. IZelle, 3=2. PotGal
    {
        if(Level == HIGH)
            Mv[0].BetriebsArt = 1;
        else
            Mv[0].BetriebsArt = 0;
    }
    return(true);
}


/****************************************************************
 * Setk
 *
 * Setzten eines Kontaktes. Die Betriebsart und Circuit wird hier auch gesetzt
 ****************************************************************/
int Setk(int Nr, bool Level)
{
//    uint8_t mask = 0x80;

#ifdef PGU_EDUCATION
//    uint8_t mask = 0x80;
    SetBaVariablen(Nr, Level);
    if(Nr == 4) // I-Zelle
        SwGe = Level;
    else if(Nr == 5)
    {
        if(Level == false)
        {
            SwPot = true;
            SwGal = false;
        }
        else // if(Level == false)
        {
            SwPot = false;
            SwGal = true;
        }
    }
#endif
#ifdef PGU_POTI		// wenn ein Potentiostat angeschlossen ist
    if(Nr == MVars.SwitchChn[0])  // 0=1. IZelle, 1= 1. PotGal, 2=2. IZelle, 3=2. PotGal
    {
        if(Level == HIGH)
        {
            g_nSendDisableTimer = 1000;
            SetSwitchHpZero(0);
            Mv[0].Circuit = 1;
            SkIzUp();
            if(IRange.AutoRange[0] < 2) 
            {
                    IRange.m_fCheckRange = true;
            }
            nSwitchDownCount[0] = EcmIni.DelayAfterSwitchUp;  // beim Rauschen deutlich laenger
        }
        else
        {
            IRange.m_fCheckRange = false;
            Mv[0].Circuit = 0;
            SkIzDown();
        }
    }
    if(Nr == MVars.SwitchChn[1])  // 0=1. IZelle, 1= 1. PotGal, 2=2. IZelle, 3=2. PotGal
    {
        
        if(Level == HIGH)
        {
            Mv[0].BetriebsArt = 1;
            PotGalUp();
        }
        else
        {
            Mv[0].BetriebsArt = 0;
            PotGalDown();
        }
    }
#endif	
    return(true);

}
/****************************************************************
SetSwHpZero

Schaltet die Eingänge der Rauschverstärker auf Null, damit eine 
Impuls durch das Umschalten eines Bereiches nicht den Hochpass 
ausstuert
****************************************************************/
void SetSwitchHpZero(int nType)
{
#ifdef ECN
    g_fCheckSpecial = true;
    if(nType == 0)  // IRange Umschaltung
    {
        SwHpZero = true;    
        g_nSpzFktSwitchIRange = 2;  // 2 steht für 500ms 
        g_fSpzFktSwitchIRange = true;
        g_nSpzFktSwitchNoiseGain = 10;  // 1/2Sekunde
        g_fSpzFktSwitchNoiseGain = true;
    }
    else if(nType == 1)  // Noise Gain Umschaltung
    {
//        g_nSpzFktSwitchNoiseGain = 50;  // 1.5 Sekunde
//        g_fSpzFktSwitchNoiseGain = true;
    }
#endif	
}

/****************************************************************
 * WriteToRefPort
 *
 Schreibt SPI Daten an das Schieberegister über CsRef
****************************************************************/
void WriteToSpiPort(unsigned char Pt)
{
    uint8_t mask = 0x80;
    uint8_t i;
    Port = Pt;
    
    for(i=0;i<8;i++)
    {
        DaSckDown();
        g_nDelayCounter = 1;
        g_nDelayCounter = 2;
        g_nDelayCounter = 3;
        g_nDelayCounter = 4;
        if((Port & mask) == mask)
        	DaMosiUp();
        else
        	DaMosiDown();
        g_nDelayCounter = 1;
        g_nDelayCounter = 2;
        g_nDelayCounter = 3;
        g_nDelayCounter = 4;
        DaSckUp();
        g_nDelayCounter = 1;
        g_nDelayCounter = 2;
        g_nDelayCounter = 5;    
        g_nDelayCounter = 6;
        mask = (mask >> 1);
    }
}

/*-------------------------------------------------------------------------------
ChangeMittelValue: Ändert den Mittelwert und alles drumherum
-------------------------------------------------------------------------------*/
int ChangeMittelValue()
{
    m_fChangeMittelValue = false;
    MVars.nMwMittelVal = MVars.m_nStoreMwIntervall; // nimmt jetzt das voreingstellte Intervall
    MVars.nMwPerBlock = NsRate.nNewSendeRate / 2;
//    printf("Neuer Mittelwert: %d Neuer Blockwert: %d\n",MVars.nMwMittelVal,MVars.nMwPerBlock);
    m_fFallBack = NsRate.fFallBack;
    nFallBackCounter = 0;
#ifdef PGU_POTI    
    if(NsRate.nNewAutoRange < 3)
    {
        if(NsRate.nNewAutoRange != IRange.AutoRange[0])
        {
            NsRate.nOldAutoRange = IRange.AutoRange[0];
            IRange.AutoRange[0] = NsRate.nNewAutoRange;
        }
    }
    if(NsRate.nNewRange != -1)
    {
        IRange.AktRange[0] = NsRate.nNewRange;
        SetIRange(0,IRange.AktRange[0]);
    }
#endif    
    return(true);
}
/****************************************************************
 * SetWe
 *
 * Setzen verschied. WorkingElektroden
 *
 *   WeSelect wäre  & 0xE7 löscht die beiden Eingänge des Multiplexers und
 setzt damit die WE 1  und | 0x18 setzt beide Eingänge auf high, das wäre die WE 4 
***************************************************************/

void SetWe(UINT8 WeRange)
{
#ifdef PGU_TOUCH
    UINT8 Range;
    Range = WeRange;

    ReInitPtc16_17();
    CsCurrentDown();  // low aktiv
#if defined REV_1B || defined REV_1D
    MVars.nCurrentPort &= 0xE7;
#else
    MVars.nCurrentPort &= 0xCF; // ist jetzt auf Bit 4 und Bit 5
#endif
    MVars.nCurrentPort |= Range;
    WriteToSpiPort(MVars.nCurrentPort);
    CsCurrentUp();  // low aktiv
#endif
}



/****************************************************************
 * GeIstGe
 *
 * 
***************************************************************/

void SetGe(UINT8 State)
{
    UINT8 Value;
/*  Schaltet den Ausgang GE auf den Schirm der WE. Das Signal WeSchirm hat nun den 
 Ausgang Gegenelektrode. Solange wie SwWeSchirm auf Low, hat das keinen Effekt
 ist WeSchirm auf High, dann wird die Klemme, welche den WeSchirm nach aussen bringt, 
 auf die Ge geschaltet. 
 D.h. LPR mit CoulCount Sensor bedeutet: 
 SetGe(1); (SwGeWeSchirm auf high)
 SwWeSchirm(1)   (SwWeSchirm auf high)
 Für CoulCount muss SwWeSchirm(0) gesetzt werden, sonst liegt der Schirm nicht auf GND
 
 */
#ifdef PGU_TOUCH
     
    ReInitPtc16_17();
    CsCurrentDown();  // low aktiv
	#if defined REV_1B || defined REV_1D
		MVars.nCurrentPort &= 0xBF;
	#else
		MVars.nCurrentPort &= 0x7F;
	#endif
		if(State == 1)  
		{
	#if defined REV_1B || defined REV_1D
			Value = 0x40;
	#else
			Value = 0x80;
	#endif
        MVars.nCurrentPort |= Value;
    }    
     WriteToSpiPort(MVars.nCurrentPort);
    CsCurrentUp();  // low aktiv
#endif	
}

/****************************************************************
 * ClearWeSchirm
 * Um den Ausgang des Summierverstärkers über IZelle auf die Gegenelektrode zu schalten, 
 muss SwGeWeSchirm auf Low sein. 
 Der Anschluss WeSchirm (Klemme K4 nach aussen) liegt auf GND, wenn SwWeSchirm auf Low ist. Damit 
 wirkt der Anschluss entweder als zusätzlicher Schirm oder er kann für die zweite Elektrode zur Strommessung verwendet
 werden. Soll eine außenstromlose Messung mit zwei WE durchgeführt werden, dann ist SwWeSchirm vor der Messung auf high zu halten.
 Entsprechend ist SwGeWeSchirm auf low zu halten, da sonst der Anschluss auf die Gegenelektrode gehen könnte (aber nur, wenn 
 SwIZelle = high, sonst hängt der Eingang in der Luft (soll er auch damit kein Strom fließt).
 
 Ist SwWeSchirm auf High, dann ist der Eingang der WE-S zunächt offen, es sei denn, SwGeWeSchirm ist auch high. Dann ist die zweite 
 WE als GE geschaltet. 
 1. Die Gegenelektrode ist ganz normal an dem Ausgang des Summierverstärkers: SwGeWeSchirm ist auf low, SwWeSchirm auch low. 
    WeSchirm liegt auf GND. Ist eine Elektrode angeschlossen und eingetaucht, dann fließt sofort ein Kurzschlussstrom.
2.  Die zweite WE ist offen (SwWeSchirm = high). Dann kann sie als Gegenelektrode genutzt werden, wenn SwGeWeSchirm auch auf high ist,
    muss aber nicht. 
Einstellungen für CoulCount: 
- Vor Beginn der Messung muss SwWeSchirm auf high sein, damit der Anschluss offen ist. SwGeWeSchirm ist low, damit die Gegenelektrode da nicht
  dran kann.
  Wird die Messung gestartet, dann wird SwWeSchirm auf Low geschaltet. Damit wird der Strommesskreis kurzgeschlossen. 
Einstellungen für LPR: 
- Wird der gleiche Sensor wie für CoulCount auch für LPR genommen, dann ist SwWeSchirm und SwGeWeSchirm auf high zu schalten. 
  Mit Beginn des Polarisierens wird IZelle auf high gesetzt, damit wird die zweite WE des Sensors als GE geschaltet. 
  
 * 
***************************************************************/
void SetWeSchirm(UINT8 State)
{
#ifdef PGU_TOUCH
    UINT8 Value;
//  if State == low     ZRA Messung, SwWeSchirm auf low    

    ReInitPtc16_17();
    CsCurrentDown();  // low aktiv
	#if defined REV_1B || defined REV_1D
    MVars.nCurrentPort &= 0xDF;
	#else
    MVars.nCurrentPort &= 0xBF;
	#endif
    if(State == 1)  // wird auf GE geschaltet, WE ist GE / 
    {
	#if defined REV_1B || defined REV_1D
        Value = 0x20;
	#else
        Value = 0x40;
	#endif
        MVars.nCurrentPort |= Value;
    }    

    WriteToSpiPort(MVars.nCurrentPort);
    CsCurrentUp();  // low aktiv
#endif	
}

/****************************************************************
 * SquareOffsetDown
 * 0 setzt den Offset des Sinusgenerators auf Sinus und Dreieck. 
 um den Generator auf Recheck zusetzen, ist SwitchWaveForm auf true 
 zu setzen. Damit wird der Offset verschoben und an das Rechtecksignal 
 angepasst. 
 * 
***************************************************************/
void SetSquareOffset(int State)
{
#ifdef PGU_TOUCH
    SwitchWaveForm = State;
#endif	
}