aufgeräumt

This commit is contained in:
Tristan Krause 2019-06-27 16:19:27 +02:00
parent 571558ece1
commit e8ee9c6cd7
5 changed files with 94 additions and 46 deletions

View file

@ -17,5 +17,6 @@ Die Projekt-Dokumentation befindet sich unter [github pages](https://devfix.gith
- [x] Servo ansteuert - [x] Servo ansteuert
- [x] Interrupt Counter - [x] Interrupt Counter
- [x] mem16 testen - [x] mem16 testen
- [ ] autocheck request size - [x] autocheck request size
- [ ] Raspberry Pi test

View file

@ -1,7 +1,7 @@
#include <b15f/b15f.h> #include <b15f/b15f.h>
/* /*
* Dieses Beispiel steuert einen Servo an PB3 an. * Dieses Beispiel steuert einen Servo an PB2 an.
* *
*/ */
int main() int main()

View file

@ -84,7 +84,6 @@ void init()
std::cout << std::endl << "Starte in 3s ..." << std::endl; std::cout << std::endl << "Starte in 3s ..." << std::endl;
sleep(3); sleep(3);
#endif #endif
B15F::setAbortHandler(&abort_handler);
// init all ncurses stuff // init all ncurses stuff
initscr(); initscr();
@ -101,6 +100,9 @@ void init()
// set view context // set view context
View::setWinContext(newwin(WIN_HEIGHT, WIN_WIDTH, 0, 0)); View::setWinContext(newwin(WIN_HEIGHT, WIN_WIDTH, 0, 0));
// set graphical error handler
B15F::setAbortHandler(&abort_handler);
} }

View file

@ -171,7 +171,6 @@ void B15F::abort(std::exception &ex)
errorhandler(ex); errorhandler(ex);
else else
{ {
std::cerr << "NOTICE: B15F::errorhandler not set" << std::endl;
std::cout << ex.what() << std::endl; std::cout << ex.what() << std::endl;
throw DriverException(ex.what()); throw DriverException(ex.what());
} }
@ -190,45 +189,51 @@ void B15F::setAbortHandler(errorhandler_t func)
* Steuerbefehle für B15 * * Steuerbefehle für B15 *
*************************/ *************************/
bool B15F::activateSelfTestMode() void B15F::activateSelfTestMode()
{ {
uint8_t rq[] = uint8_t rq[] =
{ {
RQ_SELF_TEST RQ_SELF_TEST
}; };
assertRequestLength(rq, RQ_SELF_TEST);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == MSG_OK; assertCode(aw, MSG_OK);
} }
bool B15F::digitalWrite0(uint8_t port) void B15F::digitalWrite0(uint8_t port)
{ {
uint8_t rq[] = uint8_t rq[] =
{ {
RQ_DIGITAL_WRITE_0, RQ_DIGITAL_WRITE_0,
port port
}; };
assertRequestLength(rq, RQ_DIGITAL_WRITE_0);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == MSG_OK; assertCode(aw, MSG_OK);
} }
bool B15F::digitalWrite1(uint8_t port) void B15F::digitalWrite1(uint8_t port)
{ {
uint8_t rq[] = uint8_t rq[] =
{ {
RQ_DIGITAL_WRITE_1, RQ_DIGITAL_WRITE_1,
port port
}; };
assertRequestLength(rq, RQ_DIGITAL_WRITE_1);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == MSG_OK; assertCode(aw, MSG_OK);
} }
uint8_t B15F::digitalRead0() uint8_t B15F::digitalRead0()
@ -238,6 +243,8 @@ uint8_t B15F::digitalRead0()
{ {
RQ_DIGITAL_READ_0 RQ_DIGITAL_READ_0
}; };
assertRequestLength(rq, RQ_DIGITAL_READ_0);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -252,6 +259,8 @@ uint8_t B15F::digitalRead1()
{ {
RQ_DIGITAL_READ_1 RQ_DIGITAL_READ_1
}; };
assertRequestLength(rq, RQ_DIGITAL_READ_1);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -266,6 +275,8 @@ uint8_t B15F::readDipSwitch()
{ {
RQ_READ_DIP_SWITCH RQ_READ_DIP_SWITCH
}; };
assertRequestLength(rq, RQ_READ_DIP_SWITCH);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -276,7 +287,7 @@ uint8_t B15F::readDipSwitch()
return aw; return aw;
} }
bool B15F::analogWrite0(uint16_t value) void B15F::analogWrite0(uint16_t value)
{ {
uint8_t rq[] = uint8_t rq[] =
{ {
@ -284,14 +295,16 @@ bool B15F::analogWrite0(uint16_t value)
static_cast<uint8_t >(value & 0xFF), static_cast<uint8_t >(value & 0xFF),
static_cast<uint8_t >(value >> 8) static_cast<uint8_t >(value >> 8)
}; };
assertRequestLength(rq, RQ_ANALOG_WRITE_0);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == MSG_OK; assertCode(aw, MSG_OK);
} }
bool B15F::analogWrite1(uint16_t value) void B15F::analogWrite1(uint16_t value)
{ {
uint8_t rq[] = uint8_t rq[] =
{ {
@ -299,11 +312,13 @@ bool B15F::analogWrite1(uint16_t value)
static_cast<uint8_t >(value & 0xFF), static_cast<uint8_t >(value & 0xFF),
static_cast<uint8_t >(value >> 8) static_cast<uint8_t >(value >> 8)
}; };
assertRequestLength(rq, RQ_ANALOG_WRITE_1);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == MSG_OK; assertCode(aw, MSG_OK);
} }
uint16_t B15F::analogRead(uint8_t channel) uint16_t B15F::analogRead(uint8_t channel)
@ -318,6 +333,7 @@ uint16_t B15F::analogRead(uint8_t channel)
channel channel
}; };
assertRequestLength(rq, RQ_ANALOG_READ);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint16_t aw; uint16_t aw;
@ -328,8 +344,7 @@ uint16_t B15F::analogRead(uint8_t channel)
return aw; return aw;
} }
void void B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b,
B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b,
uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count) uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
{ {
// prepare pointers // prepare pointers
@ -351,6 +366,7 @@ B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, u
static_cast<uint8_t >(count >> 8) static_cast<uint8_t >(count >> 8)
}; };
assertRequestLength(rq, RQ_ADC_DAC_STROKE);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
for (uint16_t i = 0; i < count; i++) for (uint16_t i = 0; i < count; i++)
@ -382,8 +398,7 @@ B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, u
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
if(aw != MSG_OK) assertCode(aw, MSG_OK);
abort("Sequenz unterbrochen");
} }
uint8_t B15F::pwmSetFrequency(uint32_t freq) uint8_t B15F::pwmSetFrequency(uint32_t freq)
@ -399,6 +414,7 @@ uint8_t B15F::pwmSetFrequency(uint32_t freq)
static_cast<uint8_t>((freq >> 24) & 0xFF) static_cast<uint8_t>((freq >> 24) & 0xFF)
}; };
assertRequestLength(rq, RQ_PWM_SET_FREQ);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -406,7 +422,7 @@ uint8_t B15F::pwmSetFrequency(uint32_t freq)
return aw; return aw;
} }
bool B15F::pwmSetValue(uint8_t value) void B15F::pwmSetValue(uint8_t value)
{ {
usart.clearInputBuffer(); usart.clearInputBuffer();
@ -416,14 +432,15 @@ bool B15F::pwmSetValue(uint8_t value)
value value
}; };
assertRequestLength(rq, RQ_PWM_SET_VALUE);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == MSG_OK; assertCode(aw, MSG_OK);
} }
bool B15F::setMem8(volatile uint8_t* adr, uint8_t val) void B15F::setMem8(volatile uint8_t* adr, uint8_t val)
{ {
usart.clearInputBuffer(); usart.clearInputBuffer();
@ -435,11 +452,12 @@ bool B15F::setMem8(volatile uint8_t* adr, uint8_t val)
val val
}; };
assertRequestLength(rq, RQ_SET_MEM_8);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
usart.receive(&aw, 0, sizeof(aw)); usart.receive(&aw, 0, sizeof(aw));
return aw == val; assertCode(aw, MSG_OK);
} }
uint8_t B15F::getMem8(volatile uint8_t* adr) uint8_t B15F::getMem8(volatile uint8_t* adr)
@ -453,6 +471,7 @@ uint8_t B15F::getMem8(volatile uint8_t* adr)
static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8) static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
}; };
assertRequestLength(rq, RQ_GET_MEM_8);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -460,7 +479,7 @@ uint8_t B15F::getMem8(volatile uint8_t* adr)
return aw; return aw;
} }
bool B15F::setMem16(volatile uint16_t* adr, uint16_t val) void B15F::setMem16(volatile uint16_t* adr, uint16_t val)
{ {
usart.clearInputBuffer(); usart.clearInputBuffer();
@ -473,11 +492,12 @@ bool B15F::setMem16(volatile uint16_t* adr, uint16_t val)
static_cast<uint8_t >(val >> 8) static_cast<uint8_t >(val >> 8)
}; };
assertRequestLength(rq, RQ_SET_MEM_16);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint16_t aw; uint16_t aw;
usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw)); usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
return aw == val; assertCode(aw, MSG_OK);
} }
uint16_t B15F::getMem16(volatile uint16_t* adr) uint16_t B15F::getMem16(volatile uint16_t* adr)
@ -491,6 +511,7 @@ uint16_t B15F::getMem16(volatile uint16_t* adr)
static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8) static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
}; };
assertRequestLength(rq, RQ_GET_MEM_16);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint16_t aw; uint16_t aw;
@ -498,9 +519,9 @@ uint16_t B15F::getMem16(volatile uint16_t* adr)
return aw; return aw;
} }
bool B15F::setRegister(volatile uint8_t* adr, uint8_t val) void B15F::setRegister(volatile uint8_t* adr, uint8_t val)
{ {
return setMem8(adr, val); setMem8(adr, val);
} }
uint8_t B15F::getRegister(volatile uint8_t* adr) uint8_t B15F::getRegister(volatile uint8_t* adr)
@ -517,6 +538,7 @@ uint16_t* B15F::getInterruptCounterOffset()
RQ_COUNTER_OFFSET RQ_COUNTER_OFFSET
}; };
assertRequestLength(rq, RQ_COUNTER_OFFSET);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint16_t aw; uint16_t aw;
@ -533,6 +555,7 @@ void B15F::setServoEnabled(void)
RQ_SERVO_ENABLE RQ_SERVO_ENABLE
}; };
assertRequestLength(rq, RQ_SERVO_ENABLE);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -549,6 +572,7 @@ void B15F::setServoDisabled(void)
RQ_SERVO_DISABLE RQ_SERVO_DISABLE
}; };
assertRequestLength(rq, RQ_SERVO_DISABLE);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -569,7 +593,8 @@ void B15F::setServoPosition(uint16_t pos)
static_cast<uint8_t >(pos & 0xFF), static_cast<uint8_t >(pos & 0xFF),
static_cast<uint8_t >(pos >> 8) static_cast<uint8_t >(pos >> 8)
}; };
assertRequestLength(rq, RQ_SERVO_SET_POS);
usart.transmit(&rq[0], 0, sizeof(rq)); usart.transmit(&rq[0], 0, sizeof(rq));
uint8_t aw; uint8_t aw;
@ -593,7 +618,14 @@ B15F::B15F()
void B15F::init() void B15F::init()
{ {
std::string device = exec("bash -c 'ls /dev/ttyUSB*'"); #ifdef __arm__
// Raspberry Pi serial interface
std::string device = exec("bash -c 'ls /dev/ttyAMA* 2> /dev/null'");
#else
// normal PC serial interface
std::string device = exec("bash -c 'ls /dev/ttyUSB* 2> /dev/null'");
#endif
while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos || while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos ||
device.find('\t') != std::string::npos) device.find('\t') != std::string::npos)
device.pop_back(); device.pop_back();
@ -635,9 +667,3 @@ void B15F::init()
std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")" std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")"
<< std::endl; << std::endl;
} }
void B15F::assertCode(uint8_t& code, uint8_t expectation) const
{
if(code != expectation)
throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ")");
}

View file

@ -130,21 +130,21 @@ public:
* WICHTIG: Es darf dabei nichts an den Klemmen angeschlossen sein! * WICHTIG: Es darf dabei nichts an den Klemmen angeschlossen sein!
* \throws DriverException * \throws DriverException
*/ */
bool activateSelfTestMode(void); void activateSelfTestMode(void);
/** /**
* Setzt den Wert des digitalen Ausgabeports 0 * Setzt den Wert des digitalen Ausgabeports 0
* \param port Wert für gesamten Port * \param port Wert für gesamten Port
* \throws DriverException * \throws DriverException
*/ */
bool digitalWrite0(uint8_t); void digitalWrite0(uint8_t);
/** /**
* Setzt den Wert des digitalen Ausgabeports 1 * Setzt den Wert des digitalen Ausgabeports 1
* \param port Wert für gesamten Port * \param port Wert für gesamten Port
* \throws DriverException * \throws DriverException
*/ */
bool digitalWrite1(uint8_t); void digitalWrite1(uint8_t);
/** /**
* Liest den Wert des digitalen Eingabeports 0 * Liest den Wert des digitalen Eingabeports 0
@ -172,14 +172,14 @@ public:
* \param port 10-Bit Wert * \param port 10-Bit Wert
* \throws DriverException * \throws DriverException
*/ */
bool analogWrite0(uint16_t port); void analogWrite0(uint16_t port);
/** /**
* Setzt den Wert des Digital-Analog-Converters (DAC / DAU) 1 * Setzt den Wert des Digital-Analog-Converters (DAC / DAU) 1
* \param port 10-Bit Wert * \param port 10-Bit Wert
* \throws DriverException * \throws DriverException
*/ */
bool analogWrite1(uint16_t port); void analogWrite1(uint16_t port);
/** /**
* Liest den Wert des Analog-Digital-Converters (ADC / ADU) * Liest den Wert des Analog-Digital-Converters (ADC / ADU)
@ -221,7 +221,7 @@ public:
* \param value PWM Wert [0..TOP] * \param value PWM Wert [0..TOP]
* \throws DriverException * \throws DriverException
*/ */
bool pwmSetValue(uint8_t value); void pwmSetValue(uint8_t value);
/** /**
* Setzt direkt den Wert einer MCU Speicherzelle der Größe 8 Bit. * Setzt direkt den Wert einer MCU Speicherzelle der Größe 8 Bit.
@ -231,7 +231,7 @@ public:
* \param val Neuer Wert für die Zelle * \param val Neuer Wert für die Zelle
* \return true, falls Vorgang erfolgreich * \return true, falls Vorgang erfolgreich
*/ */
bool setMem8(volatile uint8_t* adr, uint8_t val); void setMem8(volatile uint8_t* adr, uint8_t val);
/** /**
* Liefert den Wert einer MCU Speicherzelle der Größe 8 Bit. * Liefert den Wert einer MCU Speicherzelle der Größe 8 Bit.
@ -247,9 +247,9 @@ public:
* *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen! * *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen!
* \param adr Speicheradresse * \param adr Speicheradresse
* \param val Neuer Wert für die Zelle * \param val Neuer Wert für die Zelle
* \return true, falls Vorgang erfolgreich * \throws DriverException
*/ */
bool setMem16(volatile uint16_t* adr, uint16_t val); void setMem16(volatile uint16_t* adr, uint16_t val);
/** /**
* Liefert den Wert einer MCU Speicherzelle der Größe 16 Bit. * Liefert den Wert einer MCU Speicherzelle der Größe 16 Bit.
@ -264,9 +264,9 @@ public:
* *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen! * *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen!
* \param adr Speicheradresse * \param adr Speicheradresse
* \param val Neuer Wert für das Register * \param val Neuer Wert für das Register
* \return true, falls Vorgang erfolgreich * \throws DriverException
*/ */
bool setRegister(volatile uint8_t* adr, uint8_t val); void setRegister(volatile uint8_t* adr, uint8_t val);
/** /**
* Diese Funktion ist ein Alias für getMem8(). * Diese Funktion ist ein Alias für getMem8().
@ -283,17 +283,20 @@ public:
/** /**
* Aktiviert das Servo Signal an PB2 und Initialisiert es mit 1,5ms Pulselänge. * Aktiviert das Servo Signal an PB2 und Initialisiert es mit 1,5ms Pulselänge.
* \throws DriverException
*/ */
void setServoEnabled(void); void setServoEnabled(void);
/** /**
* Deaktiviert das Servo Signal an PB2. * Deaktiviert das Servo Signal an PB2.
* \throws DriverException
*/ */
void setServoDisabled(void); void setServoDisabled(void);
/** /**
* Setzt die Pulselänge des Servo Signals und damit die Position. * Setzt die Pulselänge des Servo Signals und damit die Position.
* \param pos Pulselänge des Signals in Mikrosekunden * \param pos Pulselänge des Signals in Mikrosekunden
* \throws DriverException
*/ */
void setServoPosition(uint16_t pos); void setServoPosition(uint16_t pos);
@ -326,7 +329,23 @@ private:
* Wirft eine Exception, falls der Code ungleich dem erwarteten Wert ist. * Wirft eine Exception, falls der Code ungleich dem erwarteten Wert ist.
* \throws DriverException * \throws DriverException
*/ */
void assertCode(uint8_t& code, uint8_t expectation) const; template<typename CodeType, typename ExpectationType>
void assertCode(CodeType& code, ExpectationType expectation) const
{
if(code != static_cast<CodeType>(expectation))
throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ")");
}
/**
* Wirft eine Exception, falls die Request die falsche Länge hat.
* \throws DriverException
*/
template<size_t RequestLength>
void assertRequestLength(uint8_t (&)[RequestLength], uint8_t rq_num)
{
if(RequestLength != rq_len[rq_num])
throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ")");
}
USART usart; //!< USART Instanz für serielle Verbindung USART usart; //!< USART Instanz für serielle Verbindung
static B15F* instance; //!< private Instanz für Singleton static B15F* instance; //!< private Instanz für Singleton