This commit is contained in:
Kristian Kosev
2022-04-06 23:57:15 +03:00
committed by GitHub
parent 199f8a98b0
commit 66762af4d5
9 changed files with 628 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,76 @@
/*
* This file is part of the hoverboard-firmware-hack-V2 project. The
* firmware is used to hack the generation 2 board of the hoverboard.
* These new hoverboards have no mainboard anymore. They consist of
* two Sensorboards which have their own BLDC-Bridge per Motor and an
* ARM Cortex-M3 processor GD32F130C8.
*
* Copyright (C) 2018 Florian Staeblein
* Copyright (C) 2018 Jakob Broemauer
* Copyright (C) 2018 Kai Liebich
* Copyright (C) 2018 Christoph Lehnert
*
* The program is based on the hoverboard project by Niklas Fauth. The
* structure was tried to be as similar as possible, so that everyone
* could find a better way through the code.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "RCReceiver.h"
#include "SteeringSerial.h"
#include "utils.h"
void setup()
{
// Initialize steering serial
InitSteeringSerial();
// Enable Debug LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, 1);
// Initialize RC receiver
InitRCReceiver();
// Start RC receiver
RCReceiverStart();
}
void loop()
{
uint16_t channel1 = GetRCValue(0);
uint16_t channel2 = GetRCValue(1);
uint16_t channel3 = GetRCValue(2);
// Activate/deactivate speed mode
float factor = channel3 < 1500 ? 0.5 : 1;
// Handle receiver values
SetSpeed(channel1, factor);
SetSteer(channel2);
/* SendDebug(); */
// Reply only when you receive data
if (Serial.available() > 0)
{
char character = Serial.read();
if (character == '\n')
{
SendAnswer();
}
}
}

View File

@@ -0,0 +1,211 @@
/*
* This file is part of the hoverboard-firmware-hack-V2 project. The
* firmware is used to hack the generation 2 board of the hoverboard.
* These new hoverboards have no mainboard anymore. They consist of
* two Sensorboards which have their own BLDC-Bridge per Motor and an
* ARM Cortex-M3 processor GD32F130C8.
*
* Copyright (C) 2018 Florian Staeblein
* Copyright (C) 2018 Jakob Broemauer
* Copyright (C) 2018 Kai Liebich
* Copyright (C) 2018 Christoph Lehnert
*
* The program is based on the hoverboard project by Niklas Fauth. The
* structure was tried to be as similar as possible, so that everyone
* could find a better way through the code.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "RCReceiver.h"
uint16_t m_pulseStart[SERVOS]; // Last measured pulse start for each input.
uint16_t m_pulseLength_us[SERVOS]; // Last measured pulse length for each input.
static uint8_t lastB = 0;
volatile static bool enable = false;
volatile static bool pinChangeActive = false;
uint16_t RCReceiverGetStartCount();
uint16_t RCReceiverGetStopCount(uint8_t p_servo);
uint16_t RCReceiverGetCnt();
//----------------------------------------------------------------------------
// Initializes the steering serial
//----------------------------------------------------------------------------
void InitRCReceiver(void)
{
// Deinitialize timer1
TCCR1A = 0;
TCCR1B = 0;
TCCR1C = 0;
TIMSK1 = 0;
OCR1A = 0;
OCR1B = 0;
TCNT1 = 0;
// We use pin 8-10 PB0, PB1, PB2 as Servo input pins
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
// We use pin change interrupts to detect changes in the signal
// Only allow pin change interrupts for PB0-3 (digital pins 8-10)
PCMSK0 |= (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2);
// Enable pin change interrupt 0
PCICR |= (1 << PCIE0);
}
//----------------------------------------------------------------------------
// Starts the receiver
//----------------------------------------------------------------------------
void RCReceiverStart()
{
// Clean buffers
for (uint8_t i = 0; i < SERVOS; ++i)
{
m_pulseStart[i] = 0;
m_pulseLength_us[i] = ZERO_US;
}
// Start Timer 1
// Timer 1 counts up with 1MHz, so that 1 count = 1us
// Overflow interrupt after 1000000MHz / 65536 = 0,065536s -> every 65,5ms
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11) | _BV(CS10))) | _BV(CS11);
TIMSK1 |= _BV(TOIE1);
}
//----------------------------------------------------------------------------
// Returns the current result value of specified pin
//----------------------------------------------------------------------------
uint16_t GetRCValue(uint8_t pin)
{
if (pin < 0 || pin > SERVOS)
{
return ZERO_US;
}
return m_pulseLength_us[pin];
}
//----------------------------------------------------------------------------
// Will be called when a reciever pin changes
//----------------------------------------------------------------------------
void RCReceiverPinChanged(uint8_t p_servo, bool p_high)
{
if (p_high)
{
// Start of pulse
m_pulseStart[p_servo] = RCReceiverGetStartCount();
}
else
{
// End of pulse
m_pulseLength_us[p_servo] = CLAMP(RCReceiverGetStopCount(p_servo), 1000, 2000);
}
}
//----------------------------------------------------------------------------
// Returns the start count of the timer
//----------------------------------------------------------------------------
uint16_t RCReceiverGetStartCount()
{
uint16_t cnt = RCReceiverGetCnt();
// Start of pulse
return cnt;
}
//----------------------------------------------------------------------------
// Returns the stop count of the specified input pin
//----------------------------------------------------------------------------
uint16_t RCReceiverGetStopCount(uint8_t p_servo)
{
uint16_t cnt = RCReceiverGetCnt();
// End of pulse
return (cnt - m_pulseStart[p_servo]) >> 1;
}
//----------------------------------------------------------------------------
// Returns the count value of the timer
//----------------------------------------------------------------------------
uint16_t RCReceiverGetCnt()
{
uint8_t oldSREG = SREG;
cli();
uint16_t cnt = TCNT1;
SREG = oldSREG;
return cnt;
}
//----------------------------------------------------------------------------
// Interrupt service routine for timer1 overflow
//----------------------------------------------------------------------------
ISR(TIMER1_OVF_vect)
{
sei();
// Between two overflow interrupts (every 65,5ms) should be
// at least one pin change interrupt (receiver pwm period is 6ms)
if (pinChangeActive)
{
enable = true;
}
else
{
m_pulseLength_us[0] = ZERO_US;
m_pulseLength_us[1] = ZERO_US;
m_pulseLength_us[2] = ZERO_US;
enable = false;
}
pinChangeActive = false;
}
//
//----------------------------------------------------------------------------
// Interrupt service routine for pin change port 0 interrupt
//----------------------------------------------------------------------------
ISR(PCINT0_vect)
{
if (enable == false)
{
pinChangeActive = true;
return;
}
pinChangeActive = true;
uint8_t newB = PINB;
// Bitwise XOR will set all bits that have changed
uint8_t chgB = newB ^ lastB;
lastB = newB;
// Has any of the pins changed?
if (chgB)
{
// Find out which pin has changed
if (chgB & _BV(0))
{
RCReceiverPinChanged(0, newB & _BV(0));
}
if (chgB & _BV(1))
{
RCReceiverPinChanged(1, newB & _BV(1));
}
if (chgB & _BV(2))
{
RCReceiverPinChanged(2, newB & _BV(2));
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* This file is part of the hoverboard-firmware-hack-V2 project. The
* firmware is used to hack the generation 2 board of the hoverboard.
* These new hoverboards have no mainboard anymore. They consist of
* two Sensorboards which have their own BLDC-Bridge per Motor and an
* ARM Cortex-M3 processor GD32F130C8.
*
* Copyright (C) 2018 Florian Staeblein
* Copyright (C) 2018 Jakob Broemauer
* Copyright (C) 2018 Kai Liebich
* Copyright (C) 2018 Christoph Lehnert
*
* The program is based on the hoverboard project by Niklas Fauth. The
* structure was tried to be as similar as possible, so that everyone
* could find a better way through the code.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RCRECEIVER_H
#define RCRECEIVER_H
#include <inttypes.h>
#include <Arduino.h>
#include "utils.h"
//----------------------------------------------------------------------------
// Defines
//----------------------------------------------------------------------------
#define SERVOS 3
#define ZERO_US 1500
//----------------------------------------------------------------------------
// Initializes the RC receiver
//----------------------------------------------------------------------------
void InitRCReceiver(void);
//----------------------------------------------------------------------------
// Starts the receiver
//----------------------------------------------------------------------------
void RCReceiverStart();
//----------------------------------------------------------------------------
// Returns the current result value of specified pin
//----------------------------------------------------------------------------
uint16_t GetRCValue(uint8_t pin);
#endif

View File

@@ -0,0 +1,181 @@
/*
* This file is part of the hoverboard-firmware-hack-V2 project. The
* firmware is used to hack the generation 2 board of the hoverboard.
* These new hoverboards have no mainboard anymore. They consist of
* two Sensorboards which have their own BLDC-Bridge per Motor and an
* ARM Cortex-M3 processor GD32F130C8.
*
* Copyright (C) 2018 Florian Staeblein
* Copyright (C) 2018 Jakob Broemauer
* Copyright (C) 2018 Kai Liebich
* Copyright (C) 2018 Christoph Lehnert
*
* The program is based on the hoverboard project by Niklas Fauth. The
* structure was tried to be as similar as possible, so that everyone
* could find a better way through the code.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SteeringSerial.h"
//----------------------------------------------------------------------------
// Variables
//----------------------------------------------------------------------------
int32_t speedValue = 0;
int32_t steerValue = 0;
uint8_t upperLEDMaster = 0;
uint8_t lowerLEDMaster = 0;
uint8_t mosfetOutMaster = 0;
uint8_t upperLEDSlave = 0;
uint8_t lowerLEDSlave = 0;
uint8_t mosfetOutSlave = 0;
uint8_t beepsBackwards = 0;
uint8_t activateWeakening = 0;
void SendBuffer(uint8_t buffer[], uint8_t length);
uint16_t CalcCRC(uint8_t *ptr, int count);
//----------------------------------------------------------------------------
// Initializes the steering serial
//----------------------------------------------------------------------------
void InitSteeringSerial(void)
{
// Set up serial communication
Serial.begin(19200, SERIAL_8N1);
}
//----------------------------------------------------------------------------
// Sets the speed value
//----------------------------------------------------------------------------
void SetSpeed(uint16_t data, float factor)
{
int16_t tempValue = ((float)data * 2 ) - 3000.0; // Value -1000 to 1000
tempValue *= factor;
tempValue = CLAMP(tempValue, -1000, 1000); // Avoid calculation failure
speedValue = tempValue;
}
//----------------------------------------------------------------------------
// Sets the steering value
//----------------------------------------------------------------------------
void SetSteer(uint16_t data)
{
int16_t tempValue = ((float)data * 2 ) - 3000.0; // Value -1000 to 1000
tempValue = CLAMP(tempValue, -1000, 1000); // Avoid calculation failure
if (speedValue < 0)
{
steerValue *= -1;
}
steerValue = tempValue;
}
//----------------------------------------------------------------------------
// Sends answer to master device
//----------------------------------------------------------------------------
void SendAnswer(void)
{
int index = 0;
uint8_t buffer[9];
uint8_t byte1 = 0;
uint8_t byte2 = 0;
uint8_t byte3 = 0;
uint8_t byte4 = 0;
uint8_t sendByte = 0;
sendByte |= (activateWeakening << 7);
sendByte |= (beepsBackwards << 6);
sendByte |= (mosfetOutSlave << 5);
sendByte |= (lowerLEDSlave << 4);
sendByte |= (upperLEDSlave << 3);
sendByte |= (mosfetOutMaster << 2);
sendByte |= (lowerLEDMaster << 1);
sendByte |= (upperLEDMaster << 0);
uint16_t speedValue_Format = (uint16_t)(speedValue);
byte1 |= (speedValue_Format >> 8) & 0xFF;
byte2 |= speedValue_Format & 0xFF;
uint16_t steerValue_Format = (uint16_t)(steerValue);
byte3 |= (steerValue_Format >> 8) & 0xFF;
byte4 |= steerValue_Format & 0xFF;
// Send answer
buffer[index++] = '/';
buffer[index++] = byte1;
buffer[index++] = byte2;
buffer[index++] = byte3;
buffer[index++] = byte4;
buffer[index++] = sendByte;
// Calculate CRC
uint16_t crc = CalcCRC(buffer, index);
buffer[index++] = (crc >> 8) & 0xFF;
buffer[index++] = crc & 0xFF;
// Stop byte
buffer[index++] = '\n';
SendBuffer(buffer, index);
}
//----------------------------------------------------------------------------
// Calculates CRC value
//----------------------------------------------------------------------------
uint16_t CalcCRC(uint8_t *ptr, int count)
{
uint16_t crc;
uint8_t i;
crc = 0;
while (--count >= 0)
{
crc = crc ^ (uint16_t) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
{
crc = crc << 1 ^ 0x1021;
}
else
{
crc = crc << 1;
}
} while(--i);
}
return (crc);
}
//----------------------------------------------------------------------------
// Sends buffer
//----------------------------------------------------------------------------
void SendBuffer(uint8_t buffer[], uint8_t length)
{
uint8_t index = 0;
for(; index < length; index++)
{
Serial.write(buffer[index]);
}
}
//----------------------------------------------------------------------------
// Sends debug infos
//----------------------------------------------------------------------------
void SendDebug()
{
Serial.print(speedValue);
Serial.print(",");
Serial.println(steerValue);
}

View File

@@ -0,0 +1,64 @@
/*
* This file is part of the hoverboard-firmware-hack-V2 project. The
* firmware is used to hack the generation 2 board of the hoverboard.
* These new hoverboards have no mainboard anymore. They consist of
* two Sensorboards which have their own BLDC-Bridge per Motor and an
* ARM Cortex-M3 processor GD32F130C8.
*
* Copyright (C) 2018 Florian Staeblein
* Copyright (C) 2018 Jakob Broemauer
* Copyright (C) 2018 Kai Liebich
* Copyright (C) 2018 Christoph Lehnert
*
* The program is based on the hoverboard project by Niklas Fauth. The
* structure was tried to be as similar as possible, so that everyone
* could find a better way through the code.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STEERINGSERIAL_H
#define STEERINGSERIAL_H
#include <inttypes.h>
#include <hardwareSerial.h>
#include "utils.h"
//----------------------------------------------------------------------------
// Initializes the steering serial
//----------------------------------------------------------------------------
void InitSteeringSerial(void);
//----------------------------------------------------------------------------
// Sets the speed value
//----------------------------------------------------------------------------
void SetSpeed(uint16_t data, float factor);
//----------------------------------------------------------------------------
// Sets the steering value
//----------------------------------------------------------------------------
void SetSteer(uint16_t data);
//----------------------------------------------------------------------------
// Sends answer to master device
//----------------------------------------------------------------------------
void SendAnswer(void);
//----------------------------------------------------------------------------
// Sends debug infos
//----------------------------------------------------------------------------
void SendDebug();
#endif

View File

@@ -0,0 +1,38 @@
/*
* This file is part of the hoverboard-firmware-hack-V2 project. The
* firmware is used to hack the generation 2 board of the hoverboard.
* These new hoverboards have no mainboard anymore. They consist of
* two Sensorboards which have their own BLDC-Bridge per Motor and an
* ARM Cortex-M3 processor GD32F130C8.
*
* Copyright (C) 2018 Florian Staeblein
* Copyright (C) 2018 Jakob Broemauer
* Copyright (C) 2018 Kai Liebich
* Copyright (C) 2018 Christoph Lehnert
*
* The program is based on the hoverboard project by Niklas Fauth. The
* structure was tried to be as similar as possible, so that everyone
* could find a better way through the code.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UTILS_H
#define UTILS_H
#define ABS(a) (((a) < 0.0) ? -(a) : (a))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define MAP(x, xMin, xMax, yMin, yMax) ((x - xMin) * (yMax - yMin) / (xMax - xMin) + yMin)
#endif