Skip to content
Snippets Groups Projects
Commit 234922ec authored by RobertPatzke's avatar RobertPatzke
Browse files

Update 20221107-2

parent 05cd96d2
No related branches found
No related tags found
No related merge requests found
//-----------------------------------------------------------------------------
// Thema: Social Manufacturing Network / Development Environment
// Datei: nRF52840Gpio.cpp
// Editor: Robert Patzke
// URI/URL: www.mfp-portal.de
//-----------------------------------------------------------------------------
// Lizenz: CC-BY-SA (wikipedia: Creative Commons)
// Datum: 29. Juni 2021
//
#include "nRF52840Adc.h"
// --------------------------------------------------------------------------
// Konstruktoren
// --------------------------------------------------------------------------
//
nRF52840Adc::nRF52840Adc()
{
#ifdef nrfClockTASKS_HFCLKSTART
if((*nrfClock_HFCLKSTAT & nrfClock_HFCLKisRunning) == 0)
*nrfClockTASKS_HFCLKSTART = 1;
#endif
}
// --------------------------------------------------------------------------
// Unterklasse Channels
// --------------------------------------------------------------------------
//
void nRF52840Adc::Channels::clrLists()
{
for(int i = 0; i < 8; i++)
{
unsList[i] = 0;
srtList[i] = 0;
nrOfChannels = 0;
}
}
int nRF52840Adc::Channels::add(int chnNr)
{
for(int i = 0; i < 8; i++)
{
if(unsList[i] == 0)
{
unsList[i] = chnNr;
nrOfChannels++;
return(i);
}
}
return(-1);
}
void nRF52840Adc::Channels::sort()
{
int minPos;
int cnt;
int tmp;
for(cnt = 0; cnt < 8; cnt++)
{
if(unsList[cnt] == 0) break;
srtList[cnt] = unsList[cnt];
}
for(int i = 0; i < cnt; i++)
{
minPos = i; // Position des kleinsten Elementes auf Durchgang
// Position minPos des kleinsten Elementes bestimmen
for(int j = i+1; j < cnt; j++)
if(srtList[j] < srtList[minPos])
minPos = j;
// minPos zeigt jetzt auf das kleinste Element im unsortierten Bereich
if(minPos != i) // Wenn ein späteres Element kleiner ist
{ // Vertauschen der Felder von i und minPos
tmp = srtList[i];
srtList[i] = srtList[minPos];
srtList[minPos] = tmp;
}
}
}
// --------------------------------------------------------------------------
// Konfigurationen
// --------------------------------------------------------------------------
//
// Einstellen der Kanalparameter (CH[].CONFIG)
//
dword nRF52840Adc::cnfChn(int chnIdx, ChnConf conf, AcqTime acqt, PreGain pg)
{
dword confVal = 0;
if(conf.inpResistorP) // Beschaltung am Pluseingang
{
if(conf.inpPullUpP)
confVal |= ChnConfPullUpInP;
else
confVal |= ChnConfPullDownInP;
}
else if(conf.inpVoltP)
confVal |= ChnConfV1_2InpP;
if(conf.inpResistorN) // Beschaltung am Minuseingang
{
if(conf.inpPullUpN)
confVal |= ChnConfPullUpInN;
else
confVal |= ChnConfPullDownInN;
}
else if(conf.inpVoltN)
confVal |= ChnConfV1_2InpN;
// Einstellen des Vorverstärkers
//
if(pg == pg1_5)
confVal |= ChnConfGain1_5;
else if(pg == pg1_4)
confVal |= ChnConfGain1_4;
else if(pg == pg1_3)
confVal |= ChnConfGain1_3;
else if(pg == pg1_2)
confVal |= ChnConfGain1_2;
else if(pg == pg1)
confVal |= ChnConfGain1;
else if(pg == pg2)
confVal |= ChnConfGain2;
else if(pg == pg4)
confVal |= ChnConfGain4;
// Auswahl der Referenzspannung
//
if(conf.externRef)
confVal |= ChnConfRefV1_4;
// Einstellen der Wartezeit vor Wandlung (Ladezeit, Erfassungszeit)
//
if(acqt == acqt5us)
confVal |= ChnConfAcqT5;
else if (acqt == acqt10us)
confVal |= ChnConfAcqT10;
else if (acqt == acqt15us)
confVal |= ChnConfAcqT15;
else if (acqt == acqt20us)
confVal |= ChnConfAcqT20;
else if (acqt == acqt40us)
confVal |= ChnConfAcqT40;
// Differenzmessung einstellen
//
if(conf.diffMode)
confVal |= ChnConfDiffMode;
// Burst (Oversampling) aktivieren
//
if(conf.burst)
confVal |= ChnConfBurst;
return(confVal);
}
// Zuordnen der Eingänge
//
dword nRF52840Adc::cnfPin(PinNr pinNr)
{
if(pinNr < aInpSp1)
return((dword) pinNr);
if(pinNr == aInpSp1)
return(9);
if(pinNr == aInpSp2)
return(0x0D);
return(0);
}
void nRF52840Adc::config(PinNr pinNrP, PinNr pinNrN, ChnNr chnNr,
ChnConf conf, AcqTime acqt, PreGain pg)
{
int chnIdx;
volatile ChnConfigs *chnCfgPtr;
if(chnNr < dc1) // Single-Ended Kanäle
{
// Zeiger auf die Konfigurationsregister festlegen
chnIdx = chnNr;
chnCfgPtr = &(NrfAdcPtr->CH[chnIdx]);
// Konfigurationsdaten (vom Anwender) eintragen
conf.diffMode = false; // Mögliche Fehler vermeiden
chnCfgPtr->CONFIG = cnfChn(chnIdx,conf,acqt,pg);
// Eingänge zuordnen
chnCfgPtr->PSELP = cnfPin(pinNrP);
chnCfgPtr->PSELN = 0; // Negativeingang nicht benutzt
// Vorerst Einzelabtastungen über Task-Anweisung
NrfAdcPtr->RESULT_MAXCNT = 1;
NrfAdcPtr->SAMPLERATE = 0;
// Speicher zuweisen
NrfAdcPtr->RESULT_PTR = (dword) &channels.seResult;
// Kanalliste aufbauen
channels.add(chnIdx+1);
}
}
// ----------------------------------------------------------------------------
// Anwendungsfunktionen
// ----------------------------------------------------------------------------
//
void nRF52840Adc::begin()
{
// Auflösung vorerst fest eingestellt
NrfAdcPtr->RESOLUTION = 2; // 12 Bit
// Einschalten des ADC
NrfAdcPtr->ENABLE = 1;
// Temperatur-Kalibrierung wird später gemacht
//
// Kanäle sortieren in der Liste
//
channels.sort();
// Interrupt-Handling
// ----------------------------------------------------------------------
//
NrfAdcPtr->INTENCLR = 0xFFFFFFFF; // Vorsichtshalber keine Interrupts
instPtr0 = this; // Statischen Zeiger auf diese Instanz setzen
// Interruptvektor setzen
//
__NVIC_SetVector((IRQn_Type) 7, (dword) nRF52840Adc::irqHandler0);
__NVIC_SetPriority((IRQn_Type) 7, 1);
__NVIC_EnableIRQ((IRQn_Type) 7);
}
// ----------------------------------------------------------------------------
// Ereignisbearbeitung und Interrupts
// ----------------------------------------------------------------------------
//
nRF52840Adc *nRF52840Adc::instPtr0 = NULL;
void nRF52840Adc::irqHandler0()
{
if(instPtr0 == NULL) return;
instPtr0->irqHandler();
}
void nRF52840Adc::irqHandler()
{
statistic.interrupts++;
}
//-----------------------------------------------------------------------------
// Thema: Social Manufacturing Network / Development Environment
// Datei: nRF52840Adc.h
// Editor: Robert Patzke
// URI/URL: www.mfp-portal.de
//-----------------------------------------------------------------------------
// Lizenz: CC-BY-SA (wikipedia: Creative Commons)
// Datum: 03. Oktober 2022
//
#ifndef NRF52840ADC_H
#define NRF52840ADC_H
#include <stdio.h>
#include "arduinoDefs.h"
#include "IntrfAdc.h"
#include "nrf52840.h"
#ifndef nrfAdcDef
// ----------------------------------------------------------------------------
typedef struct _ChnLimits
{
dword Low;
dword High;
} ChnLimits;
typedef struct _ChnConfigs
{
dword PSELP;
dword PSELN;
dword CONFIG;
dword LIMIT;
} ChnConfigs;
#define ChnConfPullDownInP 0x00000001
#define ChnConfPullUpInP 0x00000002
#define ChnConfV1_2InpP 0x00000003
#define ChnConfPullDownInN 0x00000010
#define ChnConfPullUpInN 0x00000020
#define ChnConfV1_2InpN 0x00000030
#define ChnConfGain1_6 0x00000000
#define ChnConfGain1_5 0x00000100
#define ChnConfGain1_4 0x00000200
#define ChnConfGain1_3 0x00000300
#define ChnConfGain1_2 0x00000400
#define ChnConfGain1 0x00000500
#define ChnConfGain2 0x00000600
#define ChnConfGain4 0x00000700
#define ChnConfRefV1_4 0x00001000
#define ChnConfAcqT3 0x00000000
#define ChnConfAcqT5 0x00010000
#define ChnConfAcqT10 0x00020000
#define ChnConfAcqT15 0x00030000
#define ChnConfAcqT20 0x00040000
#define ChnConfAcqT40 0x00050000
#define ChnConfDiffMode 0x00100000
#define ChnConfBurst 0x01000000
typedef struct _nrfAdc
{
volatile dword TASKS_START; // 000
volatile dword TASKS_SAMPLE; // 004
volatile dword TASKS_STOP; // 008
volatile dword TASKS_CALIBRATEOFFSET; // 00C
volatile dword Reserve01[60]; // 010
volatile dword EVENTS_STARTED; // 100
volatile dword EVENTS_END; // 104
volatile dword EVENTS_DONE; // 108
volatile dword EVENTS_RESULTDONE; // 10C
volatile dword EVENTS_CALIBRATEDONE; // 110
volatile dword EVENTS_STOPPED; // 114
volatile ChnLimits EVENTS_CHNLIMIT[8]; // 118
volatile dword Reserve02[106]; // 158
volatile dword INTEN; // 300
volatile dword INTENSET; // 304
volatile dword INTENCLR; // 308
volatile dword Reserve03[61]; // 30C
volatile dword STATUS; // 400
volatile dword Reserve04[63]; // 404
volatile dword ENABLE; // 500
volatile dword Reserve05[03]; // 504
volatile ChnConfigs CH[8]; // 510
volatile dword Reserve06[24]; // 590
volatile dword RESOLUTION; // 5F0
volatile dword OVERSAMPLE; // 5F4
volatile dword SAMPLERATE; // 5F8
volatile dword Reserve07[12]; // 5FC
volatile dword RESULT_PTR; // 62C
volatile dword RESULT_MAXCNT; // 630
volatile dword RESULT_AMOUNT; // 634
} nrfAdc, *nrfAdcPtr;
#define NrfAdcBase 0x40007000
#define NrfAdcPtr ((nrfAdcPtr) NrfAdcBase)
// Falls noch kein Zugriff auf die Taktfestlegung erfolgte
//
#ifndef NrfClockBase
#define NrfClockBase 0x40000000
#endif
#ifndef nrfClockTASKS_HFCLKSTART
#define nrfClockTASKS_HFCLKSTART ((dword *) 0x40000000)
#endif
#ifndef nrfClock_HFCLKSTAT
#define nrfClock_HFCLKSTAT ((dword *) 0x4000040C)
#endif
#ifndef nrfClock_HFCLKisRunning
#define nrfClock_HFCLKisRunning 0x00010000
#endif
#define nrfAdcDef
// ----------------------------------------------------------------------------
#endif
#define P0(x) (x)
#define P1(x) (32+x)
#ifdef smnNANOBLE33
// ----------------------------------------------------------------------------
#define ArdA0Bit 4
#define ArdA1Bit 5
#define ArdA2Bit 30
#define ArdA3Bit 29
#define ArdA4Bit 31
#define ArdA5Bit 2
#define ArdA6Bit 28
#define ArdA7Bit 3
#define ArdA0 P0(4)
#define ArdA1 P0(5)
#define ArdA2 P0(30)
#define ArdA3 P0(29)
#define ArdA4 P0(31)
#define ArdA5 P0(2)
#define ArdA6 P0(28)
#define ArdA7 P0(3)
#define ArdA0Mask (1 << 4)
#define ArdA1Mask (1 << 5)
#define ArdA2Mask (1 << 30)
#define ArdA3Mask (1 << 29)
#define ArdA4Mask (1 << 31)
#define ArdA5Mask (1 << 2)
#define ArdA6Mask (1 << 28)
#define ArdA7Mask (1 << 3)
enum AdcChnPin
{
seC1P = 4,
seC2P = 5,
seC3P = 30,
seC4P = 29,
seC5P = 31,
seC6P = 2,
seC7P = 28,
seC8P = 3
};
// ----------------------------------------------------------------------------
#endif
class nRF52840Adc : IntrfAdc
{
// --------------------------------------------------------------------------
// Spezifische Datentypen
// --------------------------------------------------------------------------
//
class Channels
{
public:
int unsList[8];
int srtList[8];
int nrOfChannels;
short seResult[8];
short diResult[4];
void clrLists();
int add(int chnNr);
void sort();
};
private:
// --------------------------------------------------------------------------
// lokale Variablen
// --------------------------------------------------------------------------
//
Channels channels;
Statistic statistic;
// --------------------------------------------------------------------------
// lokale Funktionen
// --------------------------------------------------------------------------
//
dword cnfChn(int chnIdx, ChnConf conf, AcqTime acqt, PreGain pg);
dword cnfPin(PinNr pinNr);
public:
// --------------------------------------------------------------------------
// Konstruktoren
// --------------------------------------------------------------------------
//
nRF52840Adc();
// --------------------------------------------------------------------------
// Konfigurationen
// --------------------------------------------------------------------------
//
void config(PinNr pinNrP, PinNr pinNrN, ChnNr chnNr, ChnConf conf, AcqTime acqt, PreGain pg);
void begin();
// --------------------------------------------------------------------------
// Anwendungsfunktionen
// --------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------
// Ereignisbearbeitung und Interrupts
// ----------------------------------------------------------------------------
//
static nRF52840Adc *instPtr0;
static void irqHandler0();
void irqHandler();
// --------------------------------------------------------------------------
// Debugging und globale Variablen
// --------------------------------------------------------------------------
//
};
#endif //NRF52840ADC_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment