NV14 implementation partially merged with actual Flysky version.
This commit is contained in:
@@ -267,7 +267,8 @@ enum TelemetryProtocol
|
||||
PROTOCOL_TELEMETRY_HITEC,
|
||||
PROTOCOL_TELEMETRY_HOTT,
|
||||
PROTOCOL_TELEMETRY_MULTIMODULE,
|
||||
PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_MULTIMODULE,
|
||||
PROTOCOL_TELEMETRY_FLYSKY_NV14,
|
||||
PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_FLYSKY_NV14,
|
||||
PROTOCOL_TELEMETRY_LUA
|
||||
};
|
||||
|
||||
|
||||
+23
-3
@@ -463,16 +463,36 @@ PACK(struct ModuleData {
|
||||
uint8_t spare2:1 SKIP;
|
||||
int8_t refreshRate; // definition as framelength for ppm (* 5 + 225 = time in 1/10 ms)
|
||||
} sbus);
|
||||
NOBACKUP(PACK(struct {
|
||||
NOBACKUP(struct {
|
||||
uint8_t receivers; // 5 bits spare
|
||||
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME];
|
||||
}) pxx2);
|
||||
#if defined(PCBFLYSKY)
|
||||
} pxx2);
|
||||
#if defined(AFHDS2)
|
||||
NOBACKUP(struct {
|
||||
uint8_t rx_id[4];
|
||||
uint8_t mode;
|
||||
uint8_t rx_freq[2];
|
||||
} flysky);
|
||||
#endif
|
||||
#if defined(AFHDS3)
|
||||
NOBACKUP(PACK(struct {
|
||||
uint8_t bindPower:3;
|
||||
uint8_t runPower:3;
|
||||
uint8_t emi:1;
|
||||
uint8_t spare:1;
|
||||
uint8_t telemetry:1;
|
||||
uint8_t mode:4;
|
||||
uint8_t spare2:3;
|
||||
uint16_t failsafeTimeout; //4
|
||||
uint16_t rxFreq;
|
||||
//one more free byte
|
||||
bool isSbus() {
|
||||
return (mode & 1);
|
||||
}
|
||||
bool isPWM() {
|
||||
return mode < 2;
|
||||
}
|
||||
} afhds3));
|
||||
#endif
|
||||
} NAME(mod) FUNC(select_mod_type);
|
||||
|
||||
|
||||
@@ -60,5 +60,6 @@
|
||||
#define BARGRAPH2_COLOR COLOR(BARGRAPH2_COLOR_INDEX)
|
||||
#define BARGRAPH_BGCOLOR COLOR(BARGRAPH_BGCOLOR_INDEX)
|
||||
#define SCROLLBOX_COLOR COLOR(SCROLLBOX_COLOR_INDEX)
|
||||
#define BATTERY_CHARGE_COLOR COLOR(BATTERY_CHARGE_COLOR_INDEX)
|
||||
|
||||
#endif // _COLORS_H_
|
||||
|
||||
@@ -68,7 +68,8 @@ class FrskyTheme: public ThemeBase
|
||||
lcdColorTable[OVERLAY_COLOR_INDEX] = BLACK;
|
||||
lcdColorTable[BARGRAPH1_COLOR_INDEX] = RED;
|
||||
lcdColorTable[BARGRAPH2_COLOR_INDEX] = RGB(167, 167, 167);
|
||||
lcdColorTable[BARGRAPH_BGCOLOR_INDEX] = RGB(222, 222, 222);
|
||||
lcdColorTable[BARGRAPH_BGCOLOR_INDEX] = RGB(222, 222, 222);;
|
||||
lcdColorTable[BATTERY_CHARGE_COLOR_INDEX] = GREEN;
|
||||
}
|
||||
|
||||
void loadMenuIcon(uint8_t index, const char * filename, uint32_t color=MENU_COLOR) const
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "afhds2.h"
|
||||
|
||||
afhds2::afhds2() {
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
}
|
||||
|
||||
afhds2::~afhds2() {
|
||||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PULSES_AFHDS2_H_
|
||||
#define PULSES_AFHDS2_H_
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
struct FlySkySerialPulsesData {
|
||||
uint8_t pulses[64];
|
||||
uint8_t * ptr;
|
||||
uint8_t frame_index;
|
||||
uint8_t crc;
|
||||
uint8_t state;
|
||||
uint8_t timeout;
|
||||
uint8_t esc_state;
|
||||
uint8_t telemetry[64];
|
||||
uint8_t telemetry_index;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
enum AfhdsSpecialChars {
|
||||
END = 0xC0, //Frame end
|
||||
START = END,
|
||||
ESC_END = 0xDC, //Escaped frame end - in case END occurs in fame then ESC ESC_END must be used
|
||||
ESC = 0xDB, //Escaping character
|
||||
ESC_ESC = 0xDD, //Escaping character in case ESC occurs in fame then ESC ESC_ESC must be used
|
||||
};
|
||||
|
||||
|
||||
class afhds2 {
|
||||
public:
|
||||
afhds2();
|
||||
virtual ~afhds2();
|
||||
};
|
||||
|
||||
#endif /* PULSES_AFHDS2_H_ */
|
||||
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "afhds3.h"
|
||||
#include "../debug.h"
|
||||
#include "../definitions.h"
|
||||
|
||||
#define FAILSAFE_HOLD 1
|
||||
#define FAILSAFE_CUSTOM 2
|
||||
namespace afhds3 {
|
||||
|
||||
|
||||
uint8_t ModuleModeToState [] = {
|
||||
ModuleState::STATE_READY, //not defined
|
||||
ModuleState::STATE_STANDBY, //MODULE_MODE_E::STANDBY
|
||||
ModuleState::STATE_BINDING, //MODULE_MODE_E::BIND
|
||||
ModuleState::STATE_UPDATING_RX, //MODULE_MODE_E::RX_UPDATE
|
||||
ModuleState::STATE_SYNC_DONE, //MODULE_MODE_E::RUN
|
||||
};
|
||||
|
||||
static const char* const moduleStateText[] = {
|
||||
"",
|
||||
"HW Error",
|
||||
"Binding",
|
||||
"Connecting",
|
||||
"Connected",
|
||||
"Standby",
|
||||
"Waiting for update",
|
||||
"Updating",
|
||||
"Updating RX",
|
||||
"Updating RX failed",
|
||||
"Testing"
|
||||
"Not ready",
|
||||
"Ready",
|
||||
"HW test"
|
||||
};
|
||||
|
||||
const char* afhds3::getState() {
|
||||
if(data->state <= ModuleState::STATE_READY) return moduleStateText[data->state];
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void afhds3::putByte(uint8_t byte) {
|
||||
this->putBytes(&byte, 1);
|
||||
}
|
||||
|
||||
void afhds3::putBytes(uint8_t* data, int length) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
uint8_t byte = data[i];
|
||||
this->data->crc += byte;
|
||||
if (END == byte) {
|
||||
*this->data->ptr++ = ESC;
|
||||
*this->data->ptr++ = ESC_END;
|
||||
}
|
||||
else if (ESC == byte) {
|
||||
*this->data->ptr++ = ESC;
|
||||
*this->data->ptr++ = ESC_ESC;
|
||||
}
|
||||
else {
|
||||
*this->data->ptr++ = byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afhds3::putHeader(COMMAND command, FRAME_TYPE frame) {
|
||||
operationState = State::SENDING_COMMAND;
|
||||
data->ptr = this->data->pulses;
|
||||
data->crc = 0;
|
||||
*data->ptr++ = END;
|
||||
uint8_t buffer[] = { FrameAddress, data->frame_index, frame, command};
|
||||
putBytes(buffer, 4);
|
||||
}
|
||||
|
||||
|
||||
void afhds3::putFooter() {
|
||||
putByte(data->crc ^ 0xff);
|
||||
*data->ptr++ = END;
|
||||
data->frame_index++;
|
||||
|
||||
switch((FRAME_TYPE)data->pulses[3])
|
||||
{
|
||||
case FRAME_TYPE::REQUEST_GET_DATA:
|
||||
case FRAME_TYPE::REQUEST_SET_EXPECT_ACK:
|
||||
case FRAME_TYPE::REQUEST_SET_EXPECT_DATA:
|
||||
operationState = State::AWAITING_RESPONSE;
|
||||
break;
|
||||
default:
|
||||
operationState = State::IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void afhds3::putFrame(COMMAND command, FRAME_TYPE frame, uint8_t* data, uint8_t dataLength){
|
||||
putHeader(command, frame);
|
||||
if(dataLength > 0) putBytes(data, dataLength);
|
||||
putFooter();
|
||||
}
|
||||
|
||||
void afhds3::addToQueue(COMMAND command, FRAME_TYPE frameType, uint8_t* data, uint8_t dataLength) {
|
||||
request* r = new request(command, frameType, data, dataLength);
|
||||
commandQueue.push(r);
|
||||
}
|
||||
|
||||
void afhds3::clearQueue() {
|
||||
while(!commandQueue.empty()) {
|
||||
request* r = commandQueue.front();
|
||||
delete r;
|
||||
commandQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
bool checkCRC(const uint8_t* data, uint8_t size)
|
||||
{
|
||||
uint8_t crc = 0;
|
||||
//skip start byte
|
||||
for (uint8_t i = 1; i < size; i++) {
|
||||
crc += data[i];
|
||||
}
|
||||
return (crc ^ 0xff) == data[size];
|
||||
}
|
||||
|
||||
bool containsData(enum FRAME_TYPE frameType) {
|
||||
return frameType == FRAME_TYPE::RESPONSE_DATA || frameType == FRAME_TYPE::REQUEST_SET_EXPECT_DATA ||
|
||||
frameType == FRAME_TYPE::REQUEST_SET_EXPECT_ACK || frameType == FRAME_TYPE::REQUEST_SET_EXPECT_DATA ||
|
||||
frameType == FRAME_TYPE::REQUEST_SET_NO_RESP;
|
||||
}
|
||||
|
||||
void afhds3::setState(uint8_t state) {
|
||||
if(state == data->state) return;
|
||||
uint8_t oldState = data->state;
|
||||
data->state = state;
|
||||
if(oldState == ModuleState::STATE_BINDING) {
|
||||
if(operationCallback != nullptr) {
|
||||
operationCallback(false);
|
||||
operationCallback = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afhds3::parseData(uint8_t* rxBuffer, uint8_t rxBufferCount) {
|
||||
|
||||
if(!checkCRC(rxBuffer, rxBufferCount - 2)) {
|
||||
TRACE("AFHDS3 [INVALID CRC]");
|
||||
return;
|
||||
}
|
||||
AfhdsFrame* responseFrame = reinterpret_cast<AfhdsFrame*>(rxBuffer);
|
||||
AfhdsFrame* requestFrame = reinterpret_cast<AfhdsFrame*>(data->pulses);
|
||||
uint8_t oldState = data->state;
|
||||
if(containsData((enum FRAME_TYPE)responseFrame->frameType)) {
|
||||
switch(responseFrame->command)
|
||||
{
|
||||
case COMMAND::MODULE_READY:
|
||||
TRACE("AFHDS3 [MODULE_READY] %02X", responseFrame->value);
|
||||
setState(responseFrame->value == MODULE_STATUS_READY ? ModuleState::STATE_READY : ModuleState::STATE_NOT_READY);
|
||||
if(data->state == ModuleState::STATE_READY && oldState != data->state) {
|
||||
addToQueue(COMMAND::MODULE_VERSION, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
addToQueue(COMMAND::MODULE_POWER_STATUS, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
addToQueue(COMMAND::MODULE_GET_CONFIG, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
uint8_t mode = MODULE_MODE_E::RUN;
|
||||
addToQueue(COMMAND::MODULE_MODE, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, &mode, 1);
|
||||
//addToQueue(COMMAND::MODULE_STATE, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
}
|
||||
break;
|
||||
case COMMAND::MODULE_GET_CONFIG:
|
||||
std::memcpy((void*)cfg.buffer, &responseFrame->value, sizeof(cfg.buffer));
|
||||
TRACE("AFHDS3 [MODULE_GET_CONFIG] telemetry %d", cfg.config.telemetry);
|
||||
break;
|
||||
case COMMAND::MODULE_VERSION:
|
||||
std::memcpy((void*)&version, &responseFrame->value, sizeof(version));
|
||||
TRACE("AFHDS3 [MODULE_VERSION] Product %d, HW %d, BOOT %d, FW %d", version.productNumber, version.hardwereVersion, version.bootloaderVersion, version.firmwareVersion);
|
||||
break;
|
||||
case COMMAND::MODULE_POWER_STATUS:
|
||||
powerSource = (enum MODULE_POWER_SOURCE)responseFrame->value;
|
||||
TRACE("AFHDS3 [MODULE_POWER_STATUS], %d", powerSource);
|
||||
break;
|
||||
case COMMAND::MODULE_STATE:
|
||||
TRACE("AFHDS3 [MODULE_STATE] %02X", responseFrame->value);
|
||||
setState(responseFrame->value);
|
||||
break;
|
||||
case COMMAND::MODULE_MODE:
|
||||
TRACE("AFHDS3 [MODULE_MODE] %02X", responseFrame->value);
|
||||
if(responseFrame->value != CMD_RESULT::SUCCESS) {
|
||||
setState(ModuleState::STATE_NOT_READY);
|
||||
}
|
||||
else addToQueue(COMMAND::MODULE_STATE, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
|
||||
break;
|
||||
case COMMAND::MODULE_SET_CONFIG:
|
||||
if(responseFrame->value != CMD_RESULT::SUCCESS) {
|
||||
setState(ModuleState::STATE_NOT_READY);
|
||||
}
|
||||
TRACE("AFHDS3 [MODULE_SET_CONFIG], %02X", responseFrame->value);
|
||||
break;
|
||||
case COMMAND::TELEMETRY_DATA:
|
||||
uint8_t* telemetry = &responseFrame->value;
|
||||
uint8_t length = telemetry[1];
|
||||
uint8_t id = telemetry[2];
|
||||
if(telemetry[0] == 0x22) {
|
||||
if(length == 5) {
|
||||
if(id == 0xFA) telemetry[2] = 0xF8; //remap to afhds3 snr
|
||||
processSensor(telemetry + 2, 0xAA);
|
||||
}
|
||||
else if(length == 6 && id == FRM302_STATUS) {
|
||||
//convert to ibus
|
||||
uint16_t t = (uint16_t)(((int16_t)telemetry[4] *10) + 400);
|
||||
uint8_t dataTemp[] = { ++id, telemetry[3], (uint8_t)(t & 0xFF), (uint8_t)(t >> 8)};
|
||||
processSensor(dataTemp, 0xAA);
|
||||
uint8_t dataVoltage[] = { ++id, telemetry[3], telemetry[5], telemetry[6] };
|
||||
processSensor(dataVoltage, 0xAA);
|
||||
}
|
||||
else if(length == 7) processSensor(telemetry + 2, 0xAC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(responseFrame->frameType == FRAME_TYPE::REQUEST_GET_DATA || responseFrame->frameType == FRAME_TYPE::REQUEST_SET_EXPECT_DATA)
|
||||
{
|
||||
TRACE("Command %02X NOT IMPLEMENTED!", responseFrame->command);
|
||||
}
|
||||
else if (responseFrame->frameType == FRAME_TYPE::REQUEST_SET_EXPECT_ACK) {
|
||||
addToQueue((enum COMMAND)responseFrame->command, FRAME_TYPE::RESPONSE_ACK);
|
||||
}
|
||||
else if(responseFrame->frameType == FRAME_TYPE::RESPONSE_DATA || responseFrame->frameType == FRAME_TYPE::RESPONSE_ACK) {
|
||||
if(operationState == State::AWAITING_RESPONSE /* && requestFrame->command == responseFrame->command*/) {
|
||||
operationState = State::IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void afhds3::onDataReceived(uint8_t byte, uint8_t* rxBuffer, uint8_t& rxBufferCount, uint8_t maxSize) {
|
||||
if (rxBufferCount == 0 && byte != AfhdsSpecialChars::START) {
|
||||
TRACE("AFHDS3 [SKIP] %02X", byte);
|
||||
data->esc_state = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (byte == AfhdsSpecialChars::ESC) {
|
||||
data->esc_state = rxBufferCount;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxBufferCount > 1 && byte == AfhdsSpecialChars::END) {
|
||||
rxBuffer[rxBufferCount++] = byte;
|
||||
parseData(rxBuffer, rxBufferCount);
|
||||
rxBufferCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->esc_state && byte == AfhdsSpecialChars::ESC_END) byte = AfhdsSpecialChars::END;
|
||||
else if (data->esc_state && byte == AfhdsSpecialChars::ESC_ESC) byte = AfhdsSpecialChars::ESC;
|
||||
//reset esc index
|
||||
data->esc_state = 0;
|
||||
|
||||
if (rxBufferCount >= maxSize) {
|
||||
TRACE("AFHDS3 [BUFFER OVERFLOW]");
|
||||
rxBufferCount = 0;
|
||||
}
|
||||
rxBuffer[rxBufferCount++] = byte;
|
||||
}
|
||||
void afhds3::trace(const char* message) {
|
||||
char buffer[256];
|
||||
char *pos = buffer;
|
||||
for (int i = 0; i < data->ptr - data->pulses; i++) {
|
||||
pos += std::snprintf(pos, buffer + sizeof(buffer) - pos, "%02X ", data->pulses[i]);
|
||||
}
|
||||
(*pos) = 0;
|
||||
TRACE("%s size = %d data %s", message, data->ptr - data->pulses, buffer);
|
||||
}
|
||||
void afhds3::setupPulses() {
|
||||
//TRACE("%d state %d repeatCount %d", (int)operationState, this->data->state, repeatCount);
|
||||
if(operationState == State::AWAITING_RESPONSE) {
|
||||
if(repeatCount++ < 5) return; //re-send
|
||||
else reset(false);
|
||||
}
|
||||
data->ptr = data->pulses;
|
||||
repeatCount = 0;
|
||||
if (operationState == State::UNKNOWN || data->state == ModuleState::STATE_NOT_READY) {
|
||||
putFrame(COMMAND::MODULE_READY, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//check waiting commands
|
||||
if(!commandQueue.empty()) {
|
||||
request* r = commandQueue.front();
|
||||
commandQueue.pop();
|
||||
putFrame(r->command, r->frameType, r->payload, r->payloadSize);
|
||||
trace("AFHDS3 [CMD QUEUE] data");
|
||||
delete r;
|
||||
return;
|
||||
}
|
||||
|
||||
//config should be loaded already
|
||||
if(syncSettings()) return;
|
||||
|
||||
switch(data->state) {
|
||||
case ModuleState::STATE_READY:
|
||||
reset();
|
||||
break;
|
||||
case ModuleState::STATE_HW_ERROR:
|
||||
case ModuleState::STATE_BINDING:
|
||||
case ModuleState::STATE_UPDATING_RX:
|
||||
case ModuleState::STATE_UPDATING_WAIT:
|
||||
case ModuleState::STATE_UPDATING_MOD:
|
||||
case ModuleState::STATE_SYNC_RUNNING:
|
||||
case ModuleState::STATE_HW_TEST:
|
||||
if(idleCount++ % 100 == 0) putFrame(COMMAND::MODULE_STATE, FRAME_TYPE::REQUEST_GET_DATA);
|
||||
break;
|
||||
case ModuleState::STATE_SYNC_DONE:
|
||||
if(cfg.config.telemetry && idleCount++ % 800 == 0) {
|
||||
uint8_t failSafe[3+MAX_CHANNELS*2] = {0x60, 0x12};
|
||||
uint8_t channels = setFailSafe((int16_t*)(failSafe + 3));
|
||||
failSafe[2] = channels *2;
|
||||
putFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, failSafe, 3 + channels*2);
|
||||
//trace("AFHDS3 [AFHDS3 SET FAILSAFE] data");
|
||||
}
|
||||
else sendChannelsData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool afhds3::syncSettings() {
|
||||
if (moduleData->afhds3.runPower != cfg.config.runPower) {
|
||||
cfg.config.runPower = moduleData->afhds3.runPower;
|
||||
uint8_t data[] = { 0x20, 0x13, 0x01, moduleData->afhds3.runPower };
|
||||
TRACE("AFHDS3 SET TX POWER %d", moduleData->afhds3.runPower);
|
||||
putFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data));
|
||||
return true;
|
||||
}
|
||||
if(moduleData->afhds3.rxFreq != cfg.config.pwmFreq) {
|
||||
cfg.config.pwmFreq = moduleData->afhds3.rxFreq;
|
||||
uint8_t data[] = {0x70, 0x17, 0x02, (uint8_t)(moduleData->afhds3.rxFreq & 0xFF), (uint8_t)(moduleData->afhds3.rxFreq >> 8)};
|
||||
TRACE("AFHDS3 SET RX FREQ");
|
||||
putFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data));
|
||||
return true;
|
||||
}
|
||||
PULSE_MODE modelPulseMode = moduleData->afhds3.isPWM() ? PULSE_MODE::PWM: PULSE_MODE::PPM_MODE;
|
||||
if(modelPulseMode != cfg.config.pulseMode) {
|
||||
cfg.config.pulseMode = modelPulseMode;
|
||||
TRACE("AFHDS3 PWM/PPM %d", modelPulseMode);
|
||||
uint8_t data[] = {0x70, 0x16, 0x01, (uint8_t)(modelPulseMode)};
|
||||
putFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data));
|
||||
return true;
|
||||
}
|
||||
|
||||
SERIAL_MODE modelSerialMode = moduleData->afhds3.isSbus() ? SERIAL_MODE::SBUS_MODE : SERIAL_MODE::IBUS;
|
||||
if(modelSerialMode != cfg.config.serialMode) {
|
||||
cfg.config.serialMode = modelSerialMode;
|
||||
TRACE("AFHDS3 IBUS/SBUS %d", modelSerialMode);
|
||||
uint8_t data[] = {0x70, 0x18, 0x01, (uint8_t)(modelSerialMode)};
|
||||
putFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(moduleData->afhds3.failsafeTimeout != cfg.config.failSafeTimout) {
|
||||
moduleData->afhds3.failsafeTimeout = cfg.config.failSafeTimout;
|
||||
uint8_t data[] = { 0x60, 0x12, 0x02, (uint8_t)(moduleData->afhds3.failsafeTimeout & 0xFF), (uint8_t)(moduleData->afhds3.failsafeTimeout >> 8) };
|
||||
putFrame(COMMAND::SEND_COMMAND, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, data, sizeof(data));
|
||||
TRACE("AFHDS3 TRACE FAILSAFE TMEOUT");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void afhds3::sendChannelsData() {
|
||||
uint8_t channels_start = moduleData->channelsStart;
|
||||
uint8_t channelsCount = 8 + moduleData->channelsCount;
|
||||
uint8_t channels_last = channels_start + channelsCount;
|
||||
|
||||
uint8_t channels[2*((8 + moduleData->channelsCount) + 1)];
|
||||
channels[0] = 0x01;
|
||||
channels[1] = channelsCount;
|
||||
|
||||
for(uint8_t channel = channels_start; channel < channels_last; channel++) {
|
||||
int16_t channelValue = convert(getChannelValue(channel));
|
||||
*((int16_t*)(channels + (channel * 2) + 2)) = channelValue;
|
||||
}
|
||||
putFrame(COMMAND::CHANNELS_FAILSAFE_DATA, FRAME_TYPE::REQUEST_SET_NO_RESP, channels, sizeof(channels));
|
||||
}
|
||||
|
||||
void afhds3::bind(bindCallback_t callback) {
|
||||
operationCallback = callback;
|
||||
TRACE("AFHDS3 [BIND]");
|
||||
setModelData();
|
||||
addToQueue(COMMAND::MODULE_SET_CONFIG, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, cfg.buffer, sizeof(cfg.buffer));
|
||||
uint8_t cmd = MODULE_MODE_E::BIND;
|
||||
addToQueue(COMMAND::MODULE_MODE, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, &cmd, 1);
|
||||
}
|
||||
|
||||
void afhds3::range(bindCallback_t callback) {
|
||||
TRACE("AFHDS3 [RANGE CHECK] NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
void afhds3::cancel() {
|
||||
if(operationCallback!=nullptr) operationCallback(false);
|
||||
reset(false);
|
||||
}
|
||||
void afhds3::stop() {
|
||||
TRACE("AFHDS3 STOP");
|
||||
uint8_t cmd = MODULE_MODE_E::STANDBY;
|
||||
putFrame(COMMAND::MODULE_MODE, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, &cmd, 1);
|
||||
reset(true);
|
||||
}
|
||||
|
||||
|
||||
void afhds3::setToDefault() {
|
||||
moduleData->afhds3.bindPower = BIND_POWER::MIN_0dbm;
|
||||
moduleData->afhds3.runPower = RUN_POWER::PLUS_15bBm;
|
||||
moduleData->afhds3.emi = EMI_STANDARD::FCC;
|
||||
moduleData->afhds3.telemetry = TELEMETRY::TELEMETRY_ENABLED;
|
||||
moduleData->afhds3.rxFreq = 50;
|
||||
moduleData->afhds3.failsafeTimeout = 1000;
|
||||
moduleData->channelsCount = 14 - 8;
|
||||
moduleData->failsafeMode = FAILSAFE_HOLD;
|
||||
//" PWM+i"" PWM+s"" PPM+i"" PPM+s"
|
||||
moduleData->afhds3.mode = 0;
|
||||
for (uint8_t channel = 0; channel < MAX_OUTPUT_CHANNELS; channel++) {
|
||||
failsafeChannels[channel] = 0;
|
||||
}
|
||||
}
|
||||
int16_t afhds3::convert(int channelValue) {
|
||||
//pulseValue = limit<uint16_t>(0, 988 + ((channelValue + 1024) / 2), 0xfff);
|
||||
//988 - 750 = 238
|
||||
//238 * 20 = 4760
|
||||
//2250 - 2012 = 238
|
||||
//238 * 20 = 4760
|
||||
// 988 ---- 2012
|
||||
//-10240 ---- 10240
|
||||
//-1024 ---- 1024
|
||||
return limit<int16_t>(FAILSAFE_MIN, channelValue*10, FAILSAFE_MAX);
|
||||
}
|
||||
void afhds3::setModelData() {
|
||||
cfg.config.bindPower = moduleData->afhds3.bindPower;
|
||||
cfg.config.runPower = moduleData->afhds3.runPower;
|
||||
cfg.config.emiStandard = moduleData->afhds3.emi;
|
||||
cfg.config.telemetry = moduleData->afhds3.telemetry;
|
||||
cfg.config.pwmFreq = moduleData->afhds3.rxFreq;
|
||||
cfg.config.serialMode = moduleData->afhds3.isSbus() ? SERIAL_MODE::SBUS_MODE : SERIAL_MODE::IBUS;
|
||||
cfg.config.pulseMode = moduleData->afhds3.isPWM() ? PULSE_MODE::PWM: PULSE_MODE::PPM_MODE;
|
||||
cfg.config.channelCount = 8 + moduleData->channelsCount;
|
||||
cfg.config.failSafeTimout = moduleData->afhds3.failsafeTimeout;
|
||||
setFailSafe(cfg.config.failSafeMode);
|
||||
|
||||
}
|
||||
uint8_t afhds3::setFailSafe(int16_t* target) {
|
||||
int16_t pulseValue = 0;
|
||||
uint8_t channels_start = moduleData->channelsStart;
|
||||
uint8_t channels_last = channels_start + 8 + moduleData->channelsCount;;
|
||||
|
||||
for (uint8_t channel = channels_start; channel < channels_last; channel++) {
|
||||
if (moduleData->failsafeMode == FAILSAFE_CUSTOM) pulseValue = convert(failsafeChannels[channel]);
|
||||
else if (moduleData->failsafeMode == FAILSAFE_HOLD) pulseValue = FAILSAFE_KEEP_LAST;
|
||||
else pulseValue = convert(getChannelValue(channel));
|
||||
target[channel-channels_start] = pulseValue;
|
||||
}
|
||||
return (uint8_t)(channels_last - channels_start);
|
||||
}
|
||||
|
||||
|
||||
void afhds3::onModelSwitch() {
|
||||
//uint8_t cmd = MODULE_MODE_E::STANDBY;
|
||||
//putFrame(COMMAND::MODULE_MODE, FRAME_TYPE::REQUEST_SET_EXPECT_DATA, &cmd, 1);
|
||||
//setModelData();
|
||||
}
|
||||
|
||||
void afhds3::reset(bool resetFrameCount) {
|
||||
TRACE("AFHDS3 RESET");
|
||||
clearQueue();
|
||||
repeatCount = 0;
|
||||
idleCount = 0;
|
||||
this->data->state = ModuleState::STATE_NOT_READY;
|
||||
this->data->frame_index = 1;
|
||||
this->data->timeout = 0;
|
||||
this->data->esc_state = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PULSES_AFHDS3_H_
|
||||
#define PULSES_AFHDS3_H_
|
||||
|
||||
#include "afhds2.h"
|
||||
#include "../datastructs.h"
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
|
||||
#define AFHDS3_BAUDRATE 1500000
|
||||
namespace afhds3 {
|
||||
|
||||
typedef void (*bindCallback_t) (bool);
|
||||
typedef void (*processSensor_t) (const uint8_t *, uint8_t);
|
||||
typedef int32_t (*getChannelValue_t)(uint8_t);
|
||||
enum DeviceAddress {
|
||||
TRANSMITTER = 0x01, MODULE = 0x03,
|
||||
};
|
||||
|
||||
enum FRAME_TYPE {
|
||||
REQUEST_GET_DATA = 0x01, //Get data response: ACK + DATA
|
||||
REQUEST_SET_EXPECT_DATA = 0x02, //Set data response: ACK + DATA
|
||||
REQUEST_SET_EXPECT_ACK = 0x03, //Set data response: ACK
|
||||
REQUEST_SET_NO_RESP = 0x05, //Set data response: none
|
||||
RESPONSE_DATA = 0x10, //Response ACK + DATA
|
||||
RESPONSE_ACK = 0x20, //Response ACK
|
||||
NOT_USED = 0xff
|
||||
};
|
||||
|
||||
enum COMMAND {
|
||||
MODULE_READY = 0x01,
|
||||
MODULE_STATE = 0x02,
|
||||
MODULE_MODE = 0x03,
|
||||
MODULE_SET_CONFIG = 0x04,
|
||||
MODULE_GET_CONFIG = 0x06,
|
||||
CHANNELS_FAILSAFE_DATA = 0x07,
|
||||
TELEMETRY_DATA = 0x09,
|
||||
SEND_COMMAND = 0x0C,
|
||||
COMMAND_RESULT = 0x0D,
|
||||
MODULE_POWER_STATUS = 0x0F,
|
||||
MODULE_VERSION = 0x1F,
|
||||
};
|
||||
|
||||
enum COMMAND_DIRECTION {
|
||||
RADIO_TO_MODULE = 0, MODULE_TO_RADIO = 1
|
||||
};
|
||||
|
||||
enum DATA_TYPE {
|
||||
READY_DT, // 8 bytes 0x01 Not ready 0x02 Ready
|
||||
STATE_DT, // See MODULE_STATE
|
||||
MODE_DT,
|
||||
MOD_CONFIG_DT,
|
||||
CHANNELS_DT,
|
||||
TELEMETRY_DT,
|
||||
MODULE_POWER_DT,
|
||||
MODULE_VERSION_DT,
|
||||
EMPTY_DT,
|
||||
};
|
||||
//enum used by command response -> translate to ModuleState
|
||||
enum MODULE_READY_E {
|
||||
MODULE_STATUS_UNKNOWN = 0x00,
|
||||
MODULE_STATUS_NOT_READY = 0x01,
|
||||
MODULE_STATUS_READY = 0x02
|
||||
};
|
||||
|
||||
enum ModuleState {
|
||||
STATE_HW_ERROR = 0x01,
|
||||
STATE_BINDING = 0x02,
|
||||
STATE_SYNC_RUNNING = 0x03,
|
||||
STATE_SYNC_DONE = 0x04,
|
||||
STATE_STANDBY = 0x05,
|
||||
STATE_UPDATING_WAIT = 0x06,
|
||||
STATE_UPDATING_MOD = 0x07,
|
||||
STATE_UPDATING_RX = 0x08,
|
||||
STATE_UPDATING_RX_FAILED = 0x09,
|
||||
STATE_RF_TESTING = 0x0a,
|
||||
STATE_NOT_READY = 0x0b, //virtual
|
||||
STATE_READY = 0x0c, //virtual
|
||||
STATE_HW_TEST = 0xff,
|
||||
};
|
||||
|
||||
//used for set command
|
||||
enum MODULE_MODE_E {
|
||||
STANDBY = 0x01,
|
||||
BIND = 0x02, //after bind module will enter run mode
|
||||
RUN = 0x03,
|
||||
RX_UPDATE = 0x04, //after successful update module will enter standby mode, otherwise hw error will be raised
|
||||
};
|
||||
|
||||
enum CMD_RESULT {
|
||||
FAILURE = 0x01,
|
||||
SUCCESS = 0x02,
|
||||
};
|
||||
|
||||
|
||||
#define MIN_FREQ 50
|
||||
#define MAX_FREQ 400
|
||||
#define MAX_CHANNELS 18
|
||||
#define FAILSAFE_KEEP_LAST 0x8000
|
||||
#define FAILSAFE_MIN -15000
|
||||
#define FAILSAFE_MAX 15000
|
||||
|
||||
enum BIND_POWER {
|
||||
MIN_16dBm = 0x00,
|
||||
MIN_5dBm = 0x01,
|
||||
MIN_0dbm = 0x02,
|
||||
PLUS_5dBm = 0x03,
|
||||
PLUS_14dBm = 0x04
|
||||
};
|
||||
|
||||
enum RUN_POWER {
|
||||
PLUS_15bBm = 0x00,
|
||||
PLUS_20bBm = 0x01,
|
||||
PLUS_27dbm = 0x02,
|
||||
PLUS_30dBm = 0x03,
|
||||
PLUS_33dBm = 0x04
|
||||
};
|
||||
|
||||
enum EMI_STANDARD {
|
||||
FCC = 0x00, CE = 0x01
|
||||
};
|
||||
|
||||
enum TELEMETRY {
|
||||
TELEMETRY_DISABLED = 0x00, TELEMETRY_ENABLED = 0x01
|
||||
};
|
||||
|
||||
enum PULSE_MODE {
|
||||
PWM = 0x00, PPM_MODE = 0x01,
|
||||
};
|
||||
|
||||
enum SERIAL_MODE {
|
||||
IBUS = 0x00, SBUS_MODE = 0x02
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) Config_s {
|
||||
uint8_t bindPower;
|
||||
uint8_t runPower;
|
||||
uint8_t emiStandard;
|
||||
uint8_t telemetry;
|
||||
uint16_t pwmFreq;
|
||||
uint8_t pulseMode;
|
||||
uint8_t serialMode;
|
||||
uint8_t channelCount;
|
||||
uint16_t failSafeTimout;
|
||||
int16_t failSafeMode[MAX_CHANNELS];
|
||||
};
|
||||
|
||||
union Config_u {
|
||||
Config_s config;
|
||||
uint8_t buffer[sizeof(Config_s)];
|
||||
};
|
||||
|
||||
enum CHANNELS_DATA_MODE {
|
||||
CHANNELS = 0x01, FAIL_SAFE = 0x02,
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) ChannelsData {
|
||||
uint8_t mode;
|
||||
uint8_t channelsNumber;
|
||||
int16_t data[MAX_CHANNELS];
|
||||
};
|
||||
|
||||
union ChannelsData_u {
|
||||
ChannelsData data;
|
||||
uint8_t buffer[sizeof(ChannelsData)];
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) TelemetryData {
|
||||
uint8_t sensorType;
|
||||
uint8_t length;
|
||||
uint8_t type;
|
||||
uint8_t semsorID;
|
||||
uint8_t data[8];
|
||||
};
|
||||
|
||||
enum MODULE_POWER_SOURCE {
|
||||
INTERNAL = 0x01, EXTERNAL = 0x02,
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) ModuleVersion {
|
||||
uint32_t productNumber;
|
||||
uint32_t hardwereVersion;
|
||||
uint32_t bootloaderVersion;
|
||||
uint32_t firmwareVersion;
|
||||
uint32_t rfVersion;
|
||||
};
|
||||
|
||||
|
||||
union AfhdsFrameData {
|
||||
uint8_t value;
|
||||
Config_s Config;
|
||||
ChannelsData Channels;
|
||||
TelemetryData Telemetry;
|
||||
ModuleVersion Version;
|
||||
};
|
||||
|
||||
struct __attribute__ ((packed)) AfhdsFrame {
|
||||
uint8_t startByte;
|
||||
uint8_t address;
|
||||
uint8_t frameNumber;
|
||||
uint8_t frameType;
|
||||
uint8_t command;
|
||||
uint8_t value;
|
||||
|
||||
AfhdsFrameData* GetData() {
|
||||
return reinterpret_cast<AfhdsFrameData*>(&value);
|
||||
}
|
||||
};
|
||||
|
||||
#define FRM302_STATUS 0x56
|
||||
|
||||
enum State {
|
||||
UNKNOWN = 0,
|
||||
SENDING_COMMAND,
|
||||
AWAITING_RESPONSE,
|
||||
IDLE
|
||||
};
|
||||
|
||||
class request {
|
||||
public:
|
||||
request(COMMAND command, FRAME_TYPE frameType, const uint8_t* data = nullptr, uint8_t length = 0) {
|
||||
this->command = command;
|
||||
this->frameType = frameType;
|
||||
if(data && length){
|
||||
payload = new uint8_t[length];
|
||||
std::memcpy(payload, data, length);
|
||||
}
|
||||
else payload = nullptr;
|
||||
payloadSize = length;
|
||||
}
|
||||
~request() {
|
||||
if(payload != nullptr) {
|
||||
delete[] payload;
|
||||
payload = nullptr;
|
||||
}
|
||||
}
|
||||
enum COMMAND command;
|
||||
enum FRAME_TYPE frameType;
|
||||
uint8_t* payload;
|
||||
uint8_t payloadSize;
|
||||
};
|
||||
|
||||
class afhds3 {
|
||||
public:
|
||||
afhds3(FlySkySerialPulsesData* data, ModuleData* moduleData, int16_t* failsafeChannels, getChannelValue_t getChannelValue, processSensor_t processSensor) {
|
||||
this->data = data;
|
||||
this->moduleData = moduleData;
|
||||
this->getChannelValue = getChannelValue;
|
||||
this->processSensor = processSensor;
|
||||
this->failsafeChannels = failsafeChannels;
|
||||
reset();
|
||||
}
|
||||
|
||||
virtual ~afhds3() {
|
||||
clearQueue();
|
||||
}
|
||||
|
||||
const uint32_t baudrate = AFHDS3_BAUDRATE;
|
||||
const uint16_t parity = ((uint16_t)0x0000); //USART_Parity_No
|
||||
const uint16_t stopBits = ((uint16_t)0x0000); //USART_StopBits_1
|
||||
const uint16_t wordLength = ((uint16_t)0x0000); //USART_WordLength_8b
|
||||
const uint16_t commandTimout = 5; //ms
|
||||
|
||||
void setupPulses();
|
||||
void onDataReceived(uint8_t data, uint8_t* rxBuffer, uint8_t& rxBufferCount, uint8_t maxSize);
|
||||
void reset(bool resetFrameCount = true);
|
||||
void bind(bindCallback_t callback);
|
||||
void range(bindCallback_t callback);
|
||||
void cancel();
|
||||
const char* getState();
|
||||
void stop();
|
||||
void setToDefault();
|
||||
void setModelData();
|
||||
private:
|
||||
const uint8_t FrameAddress = DeviceAddress::TRANSMITTER | (DeviceAddress::MODULE << 4);
|
||||
const uint16_t commandRepeatCount = 5;
|
||||
void putByte(uint8_t byte);
|
||||
void putBytes(uint8_t* data, int length);
|
||||
void putHeader(COMMAND command, FRAME_TYPE frameType);
|
||||
void putFooter();
|
||||
void putFrame(COMMAND command, FRAME_TYPE frameType, uint8_t* data = nullptr, uint8_t dataLength = 0);
|
||||
void addToQueue(COMMAND command, FRAME_TYPE frameType, uint8_t* data = nullptr, uint8_t dataLength = 0);
|
||||
void parseData(uint8_t* rxBuffer, uint8_t rxBufferCount);
|
||||
void setState(uint8_t state);
|
||||
bool syncSettings();
|
||||
void trace(const char* message);
|
||||
uint8_t setFailSafe(int16_t* target);
|
||||
int16_t convert(int channelValue);
|
||||
void onModelSwitch();
|
||||
void sendChannelsData();
|
||||
void clearQueue();
|
||||
|
||||
//external data
|
||||
FlySkySerialPulsesData* data;
|
||||
ModuleData* moduleData;
|
||||
int16_t* failsafeChannels;
|
||||
int16_t* channelOutputs;
|
||||
bindCallback_t operationCallback;
|
||||
getChannelValue_t getChannelValue;
|
||||
processSensor_t processSensor;
|
||||
//missing ppm center!
|
||||
|
||||
//local config
|
||||
Config_u cfg;
|
||||
ModuleVersion version;
|
||||
enum MODULE_POWER_SOURCE powerSource;
|
||||
//buffer where the channels are
|
||||
State operationState;
|
||||
uint16_t repeatCount;
|
||||
uint32_t idleCount;
|
||||
std::queue<request*> commandQueue;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* PULSES_AFHDS3_H_ */
|
||||
+94
-179
@@ -21,49 +21,17 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
#define END 0xC0
|
||||
#define ESC 0xDB
|
||||
#define ESC_END 0xDC
|
||||
#define ESC_ESC 0xDD
|
||||
#include "flysky.h"
|
||||
|
||||
#define FRAME_TYPE_REQUEST_ACK 0x01
|
||||
#define FRAME_TYPE_REQUEST_NACK 0x02
|
||||
#define FRAME_TYPE_ANSWER 0x10
|
||||
|
||||
enum FlySkyModuleCommandID {
|
||||
COMMAND_ID_NONE,
|
||||
COMMAND_ID_RF_INIT,
|
||||
COMMAND_ID_BIND,
|
||||
COMMAND_ID_SET_RECEIVER_ID,
|
||||
COMMAND_ID_RF_GET_CONFIG,
|
||||
COMMAND_ID_SEND_CHANNEL_DATA,
|
||||
COMMAND_ID_RX_SENSOR_DATA,
|
||||
COMMAND_ID_SET_RX_PWM_PPM,
|
||||
COMMAND_ID_SET_RX_SERVO_FREQ,
|
||||
COMMAND_ID_GET_FIRMWARE_REV,
|
||||
COMMAND_ID_SET_RX_IBUS_SBUS,
|
||||
COMMAND_ID_SET_RX_IBUS_SERVO_EXT,
|
||||
COMMAND_ID0C_UPDATE_RF_FIRMWARE = 0x0C,
|
||||
COMMAND_ID0D_SET_TX_POWER = 0x0D,
|
||||
COMMAND_ID_SET_RF_PROTOCOL,
|
||||
COMMAND_ID_TEST_RANGE,
|
||||
COMMAND_ID_TEST_RF_RESERVED,
|
||||
COMMAND_ID20_UPDATE_RX_FIRMWARE = 0x20,
|
||||
|
||||
COMMAND_ID_LAST
|
||||
};
|
||||
#define IS_VALID_COMMAND_ID(id) ((id) < COMMAND_ID_LAST)
|
||||
|
||||
#ifndef custom_log
|
||||
#define custom_log
|
||||
#endif
|
||||
enum DEBUG_RF_FRAME_PRINT_E {
|
||||
FRAME_PRINT_OFF,// 0:OFF, 1:RF frame only, 2:TX frame only, 3:Both RF and TX frame
|
||||
RF_FRAME_ONLY,
|
||||
TX_FRAME_ONLY,
|
||||
BOTH_FRAME_PRINT
|
||||
};
|
||||
|
||||
#define DEBUG_RF_FRAME_PRINT FRAME_PRINT_OFF
|
||||
#define FLYSKY_MODULE_TIMEOUT 155 /* ms */
|
||||
#define NUM_OF_NV14_CHANNELS (14)
|
||||
@@ -72,70 +40,6 @@ enum DEBUG_RF_FRAME_PRINT_E {
|
||||
#define gRomData g_model.moduleData[INTERNAL_MODULE].flysky
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
enum FlySkySensorType_E {
|
||||
FLYSKY_SENSOR_RX_VOLTAGE,
|
||||
FLYSKY_SENSOR_RX_SIGNAL,
|
||||
FLYSKY_SENSOR_RX_RSSI,
|
||||
FLYSKY_SENSOR_RX_NOISE,
|
||||
FLYSKY_SENSOR_RX_SNR,
|
||||
FLYSKY_SENSOR_TEMP,
|
||||
FLYSKY_SENSOR_EXT_VOLTAGE,
|
||||
FLYSKY_SENSOR_MOTO_RPM,
|
||||
FLYSKY_SENSOR_PRESURRE,
|
||||
FLYSKY_SENSOR_GPS
|
||||
};
|
||||
|
||||
enum FlySkyModuleState_E {
|
||||
FLYSKY_MODULE_STATE_SET_TX_POWER,
|
||||
FLYSKY_MODULE_STATE_INIT,
|
||||
FLYSKY_MODULE_STATE_BIND,
|
||||
FLYSKY_MODULE_STATE_SET_RECEIVER_ID,
|
||||
FLYSKY_MODULE_STATE_SET_RX_PWM_PPM,
|
||||
FLYSKY_MODULE_STATE_SET_RX_IBUS_SBUS,
|
||||
FLYSKY_MODULE_STATE_SET_RX_FREQUENCY,
|
||||
FLYSKY_MODULE_STATE_UPDATE_RF_FIRMWARE,
|
||||
FLYSKY_MODULE_STATE_UPDATE_RX_FIRMWARE,
|
||||
FLYSKY_MODULE_STATE_UPDATE_HALL_FIRMWARE,
|
||||
FLYSKY_MODULE_STATE_UPDATE_RF_PROTOCOL,
|
||||
FLYSKY_MODULE_STATE_GET_RECEIVER_CONFIG,
|
||||
FLYSKY_MODULE_STATE_GET_RX_FIRMWARE_INFO,
|
||||
FLYSKY_MODULE_STATE_GET_RX_FW_VERSION,
|
||||
FLYSKY_MODULE_STATE_GET_RF_FIRMWARE_INFO,
|
||||
FLYSKY_MODULE_STATE_GET_RF_FW_VERSION,
|
||||
FLYSKY_MODULE_STATE_IDLE,
|
||||
FLYSKY_MODULE_STATE_DEFAULT,
|
||||
};
|
||||
|
||||
enum FlySkyBindState_E {
|
||||
BIND_LOW_POWER,
|
||||
BIND_NORMAL_POWER,
|
||||
BIND_EXIT,
|
||||
};
|
||||
|
||||
enum FlySkyRxPulse_E {
|
||||
FLYSKY_PWM,
|
||||
FLYSKY_PPM
|
||||
};
|
||||
|
||||
enum FlySkyRxPort_E {
|
||||
FLYSKY_IBUS,
|
||||
FLYSKY_SBUS
|
||||
};
|
||||
|
||||
enum FlySkyFirmwareType_E {
|
||||
FLYSKY_RX_FIRMWARE,
|
||||
FLYSKY_RF_FIRMWARE
|
||||
};
|
||||
|
||||
enum FlySkyChannelDataType_E {
|
||||
FLYSKY_CHANNEL_DATA_NORMAL,
|
||||
FLYSKY_CHANNEL_DATA_FAILSAFE
|
||||
};
|
||||
|
||||
enum FlySkyPulseModeValue_E {
|
||||
PWM_IBUS, PWM_SBUS,
|
||||
PPM_IBUS, PPM_SBUS
|
||||
};
|
||||
#define GET_FLYSKY_PWM_PPM (gRomData.mode < 2 ? FLYSKY_PWM: FLYSKY_PPM)
|
||||
#define GET_FLYSKY_IBUS_SBUS (gRomData.mode & 1 ? FLYSKY_SBUS: FLYSKY_IBUS)
|
||||
|
||||
@@ -197,7 +101,7 @@ typedef struct RX_INFO_S {
|
||||
|
||||
static rx_sensor_t rx_sensor_info;
|
||||
static uint8_t tx_working_power = 90;
|
||||
|
||||
static uint8_t lastState = FLYSKY_MODULE_STATE_IDLE;
|
||||
static rf_info_t rf_info = {
|
||||
.id = {8, 8, 8, 8},
|
||||
.bind_power = BIND_NORMAL_POWER,
|
||||
@@ -474,15 +378,15 @@ void setFlySkyChannelData(int channel, int16_t servoValue)
|
||||
|
||||
void sendPulsesFrameByState(uint8_t port, uint8_t frameState)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = frameState;
|
||||
modulePulsesData[port].flysky.state_index = FLYSKY_MODULE_TIMEOUT;
|
||||
intmodulePulsesData.flysky.state = frameState;
|
||||
intmodulePulsesData.flysky.timeout = FLYSKY_MODULE_TIMEOUT;
|
||||
//setupPulsesFlySky(port); // effect immediately
|
||||
}
|
||||
|
||||
|
||||
bool isRxBindingState(uint8_t port)
|
||||
{
|
||||
return moduleFlag[port] == MODULE_BIND;
|
||||
return moduleState[port].mode == MODULE_MODE_BIND;
|
||||
}
|
||||
|
||||
bool isFlySkyUsbDownload(void)
|
||||
@@ -501,22 +405,24 @@ void onIntmoduleSetPower(bool isPowerOn)
|
||||
INTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
//REMOVED FROM OPENTX
|
||||
void resetPulsesFlySky(uint8_t port);
|
||||
|
||||
void onIntmoduleBindReceiver(uint8_t port)
|
||||
{
|
||||
resetPulsesFlySky(port);
|
||||
moduleFlag[port] = MODULE_BIND;
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
moduleState[port].mode = MODULE_MODE_BIND;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
}
|
||||
|
||||
void onFlySkyReceiverPulseMode(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_RX_PWM_PPM;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_RX_PWM_PPM;
|
||||
}
|
||||
|
||||
void onFlySkyReceiverPulsePort(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_RX_IBUS_SBUS;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_RX_IBUS_SBUS;
|
||||
}
|
||||
|
||||
void onIntmoduleReceiverSetFrequency(uint8_t port)
|
||||
@@ -533,96 +439,105 @@ void onIntmoduleReceiverSetPulse(uint8_t port, uint8_t mode_and_port) // mode_an
|
||||
void onFlySkyTransmitterPower(uint8_t port, uint8_t dBmValue)
|
||||
{
|
||||
tx_working_power = dBmValue;
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_TX_POWER;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_TX_POWER;
|
||||
}
|
||||
|
||||
|
||||
void onFlySkyUpdateReceiverFirmwareStart(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_UPDATE_RX_FIRMWARE;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_UPDATE_RX_FIRMWARE;
|
||||
}
|
||||
void setFlyskyState(uint8_t port, uint8_t state) {
|
||||
intmodulePulsesData.flysky.state = state;
|
||||
}
|
||||
|
||||
void onIntmoduleUsbDownloadStart(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_UPDATE_RF_FIRMWARE;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_UPDATE_RF_FIRMWARE;
|
||||
}
|
||||
|
||||
void onFlySkyUsbDownloadStart(uint8_t fw_state)
|
||||
{
|
||||
rf_info.fw_state = fw_state;
|
||||
}
|
||||
|
||||
void onFlySkyGetVersionInfoStart(uint8_t port, uint8_t isRfTransfer)
|
||||
{
|
||||
lastState = intmodulePulsesData.flysky.state;
|
||||
if ( isRfTransfer != 0 )
|
||||
setFlyskyState(port, FLYSKY_MODULE_STATE_GET_RF_FW_VERSION);
|
||||
else setFlyskyState(port, FLYSKY_MODULE_STATE_GET_RX_FW_VERSION);
|
||||
}
|
||||
void onFlySkyUpdateTransmitterProtocol(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_UPDATE_RF_PROTOCOL;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_UPDATE_RF_PROTOCOL;
|
||||
}
|
||||
|
||||
|
||||
void onFlySkyGetReceiverFirmwareInfo(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_GET_RX_FIRMWARE_INFO;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_GET_RX_FIRMWARE_INFO;
|
||||
}
|
||||
|
||||
void onFlySkyGetTransmitterFirmwareInfo(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_GET_RF_FIRMWARE_INFO;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_GET_RF_FIRMWARE_INFO;
|
||||
}
|
||||
|
||||
void onFlySkyGetReceiverFirmwareVersion(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_GET_RX_FW_VERSION;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_GET_RX_FW_VERSION;
|
||||
}
|
||||
|
||||
void onFlySkyGetTransmitterFirmwareVersion(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_GET_RF_FW_VERSION;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_GET_RF_FW_VERSION;
|
||||
}
|
||||
|
||||
void initFlySkyArray(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.ptr = modulePulsesData[port].flysky.pulses;
|
||||
modulePulsesData[port].flysky.crc = 0;
|
||||
intmodulePulsesData.flysky.ptr = intmodulePulsesData.flysky.pulses;
|
||||
intmodulePulsesData.flysky.crc = 0;
|
||||
}
|
||||
|
||||
inline void putFlySkyByte(uint8_t port, uint8_t byte)
|
||||
{
|
||||
if (END == byte) {
|
||||
*modulePulsesData[port].flysky.ptr++ = ESC;
|
||||
*modulePulsesData[port].flysky.ptr++ = ESC_END;
|
||||
*intmodulePulsesData.flysky.ptr++ = ESC;
|
||||
*intmodulePulsesData.flysky.ptr++ = ESC_END;
|
||||
}
|
||||
else if (ESC == byte) {
|
||||
*modulePulsesData[port].flysky.ptr++ = ESC;
|
||||
*modulePulsesData[port].flysky.ptr++ = ESC_ESC;
|
||||
*intmodulePulsesData.flysky.ptr++ = ESC;
|
||||
*intmodulePulsesData.flysky.ptr++ = ESC_ESC;
|
||||
}
|
||||
else {
|
||||
*modulePulsesData[port].flysky.ptr++ = byte;
|
||||
*intmodulePulsesData.flysky.ptr++ = byte;
|
||||
}
|
||||
}
|
||||
|
||||
void putFlySkyFrameByte(uint8_t port, uint8_t byte)
|
||||
{
|
||||
modulePulsesData[port].flysky.crc += byte;
|
||||
intmodulePulsesData.flysky.crc += byte;
|
||||
putFlySkyByte(port, byte);
|
||||
}
|
||||
|
||||
void putFlySkyFrameHead(uint8_t port)
|
||||
{
|
||||
*modulePulsesData[port].flysky.ptr++ = END;
|
||||
*intmodulePulsesData.flysky.ptr++ = END;
|
||||
}
|
||||
|
||||
void putFlySkyFrameIndex(uint8_t port)
|
||||
{
|
||||
putFlySkyFrameByte(port, modulePulsesData[port].flysky.frame_index);
|
||||
putFlySkyFrameByte(port, intmodulePulsesData.flysky.frame_index);
|
||||
}
|
||||
|
||||
void putFlySkyFrameCrc(uint8_t port)
|
||||
{
|
||||
putFlySkyByte(port, modulePulsesData[port].flysky.crc ^ 0xff);
|
||||
putFlySkyByte(port, intmodulePulsesData.flysky.crc ^ 0xff);
|
||||
}
|
||||
|
||||
void putFlySkyFrameTail(uint8_t port)
|
||||
{
|
||||
*modulePulsesData[port].flysky.ptr++ = END;
|
||||
*intmodulePulsesData.flysky.ptr++ = END;
|
||||
}
|
||||
|
||||
|
||||
@@ -719,7 +634,7 @@ void putFlySkySendChannelData(uint8_t port)
|
||||
uint8_t channels_count = min<unsigned int>(NUM_OF_NV14_CHANNELS, channels_start + 8 + g_model.moduleData[port].channelsCount);
|
||||
putFlySkyFrameByte(port, channels_count);
|
||||
for (uint8_t channel = channels_start; channel < channels_count; channel++) {
|
||||
int16_t failsafeValue = g_model.moduleData[port].failsafeChannels[channel];
|
||||
int16_t failsafeValue = g_model.failsafeChannels[channel];
|
||||
uint16_t pulseValue = limit<uint16_t>(900, 900 + ((2100 - 900) * (failsafeValue + 1024) / 2048), 2100);
|
||||
putFlySkyFrameByte(port, pulseValue & 0xff);
|
||||
putFlySkyFrameByte(port, pulseValue >> 8);
|
||||
@@ -761,8 +676,8 @@ void putFlySkyUpdateRfProtocol(uint8_t port)
|
||||
|
||||
void incrFlySkyFrame(uint8_t port)
|
||||
{
|
||||
if (++modulePulsesData[port].flysky.frame_index == 0)
|
||||
modulePulsesData[port].flysky.frame_index = 1;
|
||||
if (++intmodulePulsesData.flysky.frame_index == 0)
|
||||
intmodulePulsesData.flysky.frame_index = 1;
|
||||
}
|
||||
|
||||
bool checkFlySkyFrameCrc(const uint8_t * ptr, uint8_t size)
|
||||
@@ -792,7 +707,7 @@ bool checkFlySkyFrameCrc(const uint8_t * ptr, uint8_t size)
|
||||
|
||||
void parseFlySkyFeedbackFrame(uint8_t port)
|
||||
{
|
||||
const uint8_t * ptr = modulePulsesData[port].flysky.telemetry;
|
||||
const uint8_t * ptr = intmodulePulsesData.flysky.telemetry;
|
||||
if (*ptr++ != END)
|
||||
return;
|
||||
|
||||
@@ -802,15 +717,15 @@ void parseFlySkyFeedbackFrame(uint8_t port)
|
||||
uint8_t first_para = *ptr++;
|
||||
uint8_t * p_data = NULL;
|
||||
|
||||
if (!checkFlySkyFrameCrc(modulePulsesData[port].flysky.telemetry + 1, modulePulsesData[port].flysky.telemetry_index - 2)) {
|
||||
if (!checkFlySkyFrameCrc(intmodulePulsesData.flysky.telemetry + 1, intmodulePulsesData.flysky.telemetry_index - 2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (command_id) {
|
||||
default:
|
||||
if (moduleFlag[port] == MODULE_NORMAL_MODE
|
||||
&& modulePulsesData[port].flysky.state >= FLYSKY_MODULE_STATE_IDLE) {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
if (moduleState[port].mode == MODULE_MODE_NORMAL
|
||||
&& intmodulePulsesData.flysky.state >= FLYSKY_MODULE_STATE_IDLE) {
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
if (DEBUG_RF_FRAME_PRINT & RF_FRAME_ONLY) TRACE("State back to channel data");
|
||||
}
|
||||
break;
|
||||
@@ -818,27 +733,27 @@ void parseFlySkyFeedbackFrame(uint8_t port)
|
||||
case COMMAND_ID_RF_INIT: {
|
||||
if (first_para == 0x01) { // action only RF ready
|
||||
|
||||
if (moduleFlag[port] == MODULE_BIND) {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_BIND;
|
||||
if (moduleState[port].mode == MODULE_MODE_BIND) {
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_BIND;
|
||||
incrFlySkyFrame(port);
|
||||
}
|
||||
|
||||
/*else if (moduleFlag[port] == MODULE_RANGECHECK) {
|
||||
/*else if (moduleState[port].mode == MODULE_MODE_RANGECHECK) {
|
||||
|
||||
}*/
|
||||
|
||||
if (modulePulsesData[port].flysky.state == FLYSKY_MODULE_STATE_INIT) {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_RECEIVER_ID;
|
||||
if (intmodulePulsesData.flysky.state == FLYSKY_MODULE_STATE_INIT) {
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_RECEIVER_ID;
|
||||
incrFlySkyFrame(port);
|
||||
}
|
||||
}
|
||||
else modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_IDLE;
|
||||
else intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_ID_BIND: {
|
||||
if (frame_type != FRAME_TYPE_ANSWER) {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_IDLE;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
g_model.header.modelId[port] = ptr[2];
|
||||
@@ -850,11 +765,11 @@ void parseFlySkyFeedbackFrame(uint8_t port)
|
||||
TRACE("New Rx ID: %02X %02X %02X %02X", gRomData.rx_id[0], gRomData.rx_id[1], gRomData.rx_id[2], gRomData.rx_id[3]);
|
||||
SET_DIRTY();
|
||||
resetPulsesFlySky(port);
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
break;
|
||||
|
||||
case COMMAND_ID_RF_GET_CONFIG:
|
||||
modulePulsesData[port].flysky.frame_index = frame_number;
|
||||
intmodulePulsesData.flysky.frame_index = frame_number;
|
||||
sendPulsesFrameByState(port, FLYSKY_MODULE_STATE_GET_RECEIVER_CONFIG);
|
||||
break;
|
||||
}
|
||||
@@ -883,46 +798,46 @@ void parseFlySkyFeedbackFrame(uint8_t port)
|
||||
p_data[1] = *ptr++;
|
||||
}
|
||||
|
||||
if (moduleFlag[port] == MODULE_RANGECHECK) {
|
||||
moduleFlag[port] = MODULE_NORMAL_MODE;
|
||||
if (moduleState[port].mode == MODULE_MODE_RANGECHECK) {
|
||||
moduleState[port].mode = MODULE_MODE_NORMAL;
|
||||
onFlySkyTransmitterPower(port, 0); // set power 0
|
||||
break;
|
||||
}
|
||||
|
||||
if (moduleFlag[port] == MODULE_NORMAL_MODE && modulePulsesData[port].flysky.state >= FLYSKY_MODULE_STATE_IDLE) {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
if (moduleState[port].mode == MODULE_MODE_NORMAL && intmodulePulsesData.flysky.state >= FLYSKY_MODULE_STATE_IDLE) {
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_ID_SET_RECEIVER_ID: {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
return;
|
||||
}
|
||||
|
||||
case COMMAND_ID0D_SET_TX_POWER: {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_ID_SET_RX_PWM_PPM: {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_RX_IBUS_SBUS;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_RX_IBUS_SBUS;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_ID_SET_RX_IBUS_SBUS: {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_RX_FREQUENCY;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_RX_FREQUENCY;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_ID_SET_RX_SERVO_FREQ: {
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_DEFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_ID0C_UPDATE_RF_FIRMWARE: {
|
||||
rf_info.fw_state = FLYSKY_MODULE_STATE_UPDATE_RF_FIRMWARE;
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_IDLE;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -946,7 +861,7 @@ void checkFlySkyFeedback(uint8_t port)
|
||||
uint8_t byte;
|
||||
|
||||
while (intmoduleGetByte(&byte)) {
|
||||
//if ( modulePulsesData[port].flysky.state == FLYSKY_MODULE_STATE_IDLE
|
||||
//if ( intmodulePulsesData.flysky.state == FLYSKY_MODULE_STATE_IDLE
|
||||
// && rf_info.fw_state == FLYSKY_MODULE_STATE_UPDATE_RF_FIRMWARE )
|
||||
{
|
||||
Parse_Character(&rfProtocolRx, byte );
|
||||
@@ -966,7 +881,7 @@ void checkFlySkyFeedback(uint8_t port)
|
||||
if ( 0x01 == rfProtocolRx.length &&
|
||||
( 0x05 == rfProtocolRx.data[0] || 0x06 == rfProtocolRx.data[0]) )
|
||||
{
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
rf_info.fw_state = 0;
|
||||
}
|
||||
|
||||
@@ -975,26 +890,26 @@ void checkFlySkyFeedback(uint8_t port)
|
||||
//continue;
|
||||
}
|
||||
|
||||
if (byte == END && modulePulsesData[port].flysky.telemetry_index > 0) {
|
||||
if (byte == END && intmodulePulsesData.flysky.telemetry_index > 0) {
|
||||
parseFlySkyFeedbackFrame(port);
|
||||
modulePulsesData[port].flysky.telemetry_index = 0;
|
||||
intmodulePulsesData.flysky.telemetry_index = 0;
|
||||
}
|
||||
else {
|
||||
if (byte == ESC) {
|
||||
modulePulsesData[port].flysky.esc_state = 1;
|
||||
intmodulePulsesData.flysky.esc_state = 1;
|
||||
}
|
||||
else {
|
||||
if (modulePulsesData[port].flysky.esc_state) {
|
||||
modulePulsesData[port].flysky.esc_state = 0;
|
||||
if (intmodulePulsesData.flysky.esc_state) {
|
||||
intmodulePulsesData.flysky.esc_state = 0;
|
||||
if (byte == ESC_END)
|
||||
byte = END;
|
||||
else if (byte == ESC_ESC)
|
||||
byte = ESC;
|
||||
}
|
||||
modulePulsesData[port].flysky.telemetry[modulePulsesData[port].flysky.telemetry_index++] = byte;
|
||||
if (modulePulsesData[port].flysky.telemetry_index >= sizeof(modulePulsesData[port].flysky.telemetry)) {
|
||||
intmodulePulsesData.flysky.telemetry[intmodulePulsesData.flysky.telemetry_index++] = byte;
|
||||
if (intmodulePulsesData.flysky.telemetry_index >= sizeof(intmodulePulsesData.flysky.telemetry)) {
|
||||
// TODO buffer is full, log an error?
|
||||
modulePulsesData[port].flysky.telemetry_index = 0;
|
||||
intmodulePulsesData.flysky.telemetry_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1004,11 +919,11 @@ void checkFlySkyFeedback(uint8_t port)
|
||||
|
||||
void resetPulsesFlySky(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].flysky.frame_index = 1;
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_SET_TX_POWER;
|
||||
modulePulsesData[port].flysky.state_index = 0;
|
||||
modulePulsesData[port].flysky.esc_state = 0;
|
||||
moduleFlag[port] = MODULE_NORMAL_MODE;
|
||||
intmodulePulsesData.flysky.frame_index = 1;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_SET_TX_POWER;
|
||||
intmodulePulsesData.flysky.timeout = 0;
|
||||
intmodulePulsesData.flysky.esc_state = 0;
|
||||
moduleState[port].mode = MODULE_MODE_NORMAL;
|
||||
uint16_t rx_freq = g_model.moduleData[port].flysky.rx_freq[0];
|
||||
rx_freq += (g_model.moduleData[port].flysky.rx_freq[1] * 256);
|
||||
if (50 > rx_freq || 400 < rx_freq) {
|
||||
@@ -1026,13 +941,13 @@ void setupPulsesFlySky(uint8_t port)
|
||||
putFlySkyFrameHead(port);
|
||||
putFlySkyFrameIndex(port);
|
||||
|
||||
if (modulePulsesData[port].flysky.state < FLYSKY_MODULE_STATE_DEFAULT) {
|
||||
if (intmodulePulsesData.flysky.state < FLYSKY_MODULE_STATE_DEFAULT) {
|
||||
|
||||
if (++modulePulsesData[port].flysky.state_index >= FLYSKY_MODULE_TIMEOUT / PXX_PERIOD_DURATION) {
|
||||
if (++intmodulePulsesData.flysky.timeout >= FLYSKY_MODULE_TIMEOUT / 9) {
|
||||
|
||||
modulePulsesData[port].flysky.state_index = 0;
|
||||
intmodulePulsesData.flysky.timeout = 0;
|
||||
|
||||
switch (modulePulsesData[port].flysky.state) {
|
||||
switch (intmodulePulsesData.flysky.state) {
|
||||
|
||||
case FLYSKY_MODULE_STATE_INIT:
|
||||
putFlySkyRfInit(port);
|
||||
@@ -1048,7 +963,7 @@ void setupPulsesFlySky(uint8_t port)
|
||||
|
||||
case FLYSKY_MODULE_STATE_GET_RECEIVER_CONFIG:
|
||||
putFlySkyGetReceiverConfig(port);
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
break;
|
||||
|
||||
case FLYSKY_MODULE_STATE_SET_TX_POWER:
|
||||
@@ -1096,11 +1011,11 @@ void setupPulsesFlySky(uint8_t port)
|
||||
break;
|
||||
|
||||
case FLYSKY_MODULE_STATE_IDLE:
|
||||
modulePulsesData[port].pxx_uart.ptr = modulePulsesData[port].pxx_uart.pulses;
|
||||
intmodulePulsesData.flysky.ptr = intmodulePulsesData.flysky.pulses;
|
||||
return;
|
||||
|
||||
default:
|
||||
modulePulsesData[port].flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
intmodulePulsesData.flysky.state = FLYSKY_MODULE_STATE_INIT;
|
||||
initFlySkyArray(port);
|
||||
if ((DEBUG_RF_FRAME_PRINT & TX_FRAME_ONLY)) {
|
||||
TRACE("State back to INIT\r\n");
|
||||
@@ -1123,10 +1038,10 @@ void setupPulsesFlySky(uint8_t port)
|
||||
|
||||
if ((DEBUG_RF_FRAME_PRINT & TX_FRAME_ONLY)) {
|
||||
/* print each command, except channel data by interval */
|
||||
uint8_t * data = modulePulsesData[port].pxx_uart.pulses;
|
||||
uint8_t * data = intmodulePulsesData.flysky.pulses;
|
||||
if (data[3] != COMMAND_ID_SEND_CHANNEL_DATA || (set_loop_cnt++ % 100 == 0)) {
|
||||
uint8_t size = modulePulsesData[port].pxx_uart.ptr - data;
|
||||
TRACE_NOCRLF("TX(State%0d)%0dB:", modulePulsesData[port].flysky.state, size);
|
||||
uint8_t size = intmodulePulsesData.flysky.ptr - data;
|
||||
TRACE_NOCRLF("TX(State%0d)%0dB:", intmodulePulsesData.flysky.state, size);
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
TRACE_NOCRLF(" %02X", data[idx]);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "pxx1.h"
|
||||
#include "pxx2.h"
|
||||
#include "multi.h"
|
||||
#include "flysky.h"
|
||||
#include "modules_helpers.h"
|
||||
#include "ff.h"
|
||||
|
||||
@@ -272,7 +273,9 @@ union InternalModulePulsesData {
|
||||
PwmPxx1Pulses pxx;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(AFHDS2)
|
||||
FlySkySerialPulsesData flysky;
|
||||
#endif
|
||||
#if defined(PXX2)
|
||||
Pxx2Pulses pxx2;
|
||||
#endif
|
||||
@@ -305,6 +308,9 @@ union ExternalModulePulsesData {
|
||||
#if defined(DSM2) || defined(MULTIMODULE) || defined(SBUS)
|
||||
Dsm2PulsesData dsm2;
|
||||
#endif
|
||||
#if defined(AFHDS3)
|
||||
FlySkySerialPulsesData flysky;
|
||||
#endif
|
||||
|
||||
PpmPulsesData<pulse_duration_t> ppm;
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ option(PPM "PPM TX Module" ON)
|
||||
option(DSM2 "DSM2 TX Module" ON)
|
||||
option(SBUS "SBUS TX Module" ON)
|
||||
option(CROSSFIRE "Crossfire TX Module" ON)
|
||||
option(AFHDS2 "Support for AFHDS2" OFF)
|
||||
option(AFHDS3 "Support for AFHDS3" OFF)
|
||||
option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON)
|
||||
option(DEBUG_INTERRUPTS "Count interrupts" OFF)
|
||||
option(DEBUG_LATENCY "Debug latency" OFF)
|
||||
@@ -147,7 +149,18 @@ endif()
|
||||
|
||||
if(MULTIMODULE)
|
||||
add_definitions(-DMULTIMODULE)
|
||||
set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/multi.cpp io/multi_firmware_update.cpp)
|
||||
set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/hitec.cpp telemetry/hott.cpp telemetry/multi.cpp io/multi_firmware_update.cpp)
|
||||
endif()
|
||||
if(MULTIMODULE OR AFHDS3)
|
||||
set(SRC ${SRC} telemetry/flysky_ibus.cpp)
|
||||
endif()
|
||||
if(AFHDS2)
|
||||
add_definitions(-DAFHDS2)
|
||||
set(SRC ${SRC} telemetry/flysky_nv14.cpp)
|
||||
endif()
|
||||
|
||||
if(AFHDS3)
|
||||
add_definitions(-DAFHDS3)
|
||||
endif()
|
||||
|
||||
if(CROSSFIRE)
|
||||
@@ -236,3 +249,17 @@ if(SBUS)
|
||||
sbus.cpp
|
||||
)
|
||||
endif()
|
||||
if(AFHDS2)
|
||||
set(PULSES_SRC
|
||||
${PULSES_SRC}
|
||||
afhds2.cpp
|
||||
flysky.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(AFHDS3)
|
||||
set(PULSES_SRC
|
||||
${PULSES_SRC}
|
||||
afhds3.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -102,7 +102,7 @@ if(PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT (PCB STREQUAL X10 OR PCB STREQUAL X12S))
|
||||
if(NOT (PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14))
|
||||
set(BOOTLOADER_SRC
|
||||
${BOOTLOADER_SRC}
|
||||
../../../../../targets/${TARGET_DIR}/i2c_driver.cpp
|
||||
|
||||
@@ -516,6 +516,6 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
#if defined(PCBHORUS) || defined(PCBNV14)
|
||||
void *__dso_handle = nullptr;
|
||||
#endif
|
||||
|
||||
@@ -167,11 +167,11 @@ uint32_t isFirmwareStart(const uint8_t * buffer)
|
||||
return 0;
|
||||
}
|
||||
// First ISR pointer in FLASH
|
||||
if ((block[1] & 0xFFF00000) != 0x08000000) {
|
||||
if ((block[1] & 0xFFC00000) != 0x08000000) {//for nv14 firmware may start up to 0x81F ....
|
||||
return 0;
|
||||
}
|
||||
// Second ISR pointer in FLASH
|
||||
if ((block[2] & 0xFFF00000) != 0x08000000) {
|
||||
if ((block[2] & 0xFFC00000) != 0x08000000) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
#define USBD_VID 0x0483
|
||||
|
||||
#define USBD_LANGID_STRING 0x409
|
||||
#define USBD_MANUFACTURER_STRING "FrSky"
|
||||
#define USBD_SERIALNUMBER_FS_STRING "00000000001B"
|
||||
|
||||
|
||||
@@ -216,8 +215,10 @@ uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length)
|
||||
* @param length : pointer to data length variable
|
||||
* @retval pointer to descriptor buffer
|
||||
*/
|
||||
static const char USBD_MANUFACTURER_STRING[] = { USB_MANUFACTURER };
|
||||
uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length)
|
||||
{
|
||||
|
||||
USBD_GetString ((uint8_t*)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
option(DISK_CACHE "Enable SD card disk cache" YES)
|
||||
option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" YES)
|
||||
option(DISK_CACHE "Enable SD card disk cache" ON)
|
||||
option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON)
|
||||
option(FLYSKY_HALL_STICKS "sticks for FlySky hall sticks" ON)
|
||||
option(FLYSKY_HALL_STICKS_REVERSE "Reverse sticks for FlySky hall sticks" OFF)
|
||||
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
|
||||
option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON)
|
||||
|
||||
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
|
||||
set(CPU_TYPE STM32F4)
|
||||
set(HSE_VALUE 12000000)
|
||||
set(SDCARD YES)
|
||||
set(SDCARD YES)
|
||||
set(STORAGE SDCARD)
|
||||
set(STORAGE_FORMAT BIN)
|
||||
set(HAPTIC YES)
|
||||
@@ -24,7 +24,7 @@ endif()
|
||||
set(RAMBACKUP YES)
|
||||
set(PPM_LIMITS_SYMETRICAL YES)
|
||||
# for size report script
|
||||
set(CPU_TYPE_FULL STM32F429BIT6)
|
||||
set(CPU_TYPE_FULL STM32F429xI)
|
||||
set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM2=8192")
|
||||
option(USB_SERIAL "Enable USB serial (CDC)" ON)
|
||||
|
||||
@@ -37,7 +37,6 @@ add_definitions(-DPCBNV14 -DPCBFLYSKY -DINTERNAL_MODULE_BAUDRATE=${PCB_RF_BAUD})
|
||||
#add_definitions(-DSOFTWARE_VOLUME)
|
||||
set(TARGET_SRC
|
||||
${TARGET_SRC}
|
||||
#../common/arm/stm32/audio_dac_driver.cpp
|
||||
audio_spi_driver.cpp
|
||||
adc_driver.cpp
|
||||
)
|
||||
@@ -64,11 +63,22 @@ add_definitions(-DSTM32F429_439xx -DSDRAM -DCOLORLCD -DLIBOPENUI -DHARDWARE_TOUC
|
||||
add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK)
|
||||
add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE})
|
||||
add_definitions(-DPWR_BUTTON_${PWR_BUTTON})
|
||||
add_definitions(-DCROSSFIRE_NATIVE)
|
||||
add_definitions(-DFLYSKY_HALL_STICKS_REVERSE)
|
||||
add_definitions(-DHALL_STICKS)
|
||||
#add_definitions(-DFLYSKY_AUTO_POWER_DOWN)
|
||||
|
||||
if(STICKS_DEAD_ZONE)
|
||||
add_definitions(-DSTICK_DEAD_ZONE)
|
||||
endif()
|
||||
|
||||
if(NOT UNEXPECTED_SHUTDOWN)
|
||||
add_definitions(-DNO_UNEXPECTED_SHUTDOWN)
|
||||
endif()
|
||||
|
||||
set(AFHDS2 ON)
|
||||
set(AFHDS3 ON)
|
||||
|
||||
include_directories(${RADIO_SRC_DIR}/fonts/colorlcd gui/${GUI_DIR} gui/${GUI_DIR}/layouts)
|
||||
|
||||
file(GLOB THEMES_SRC RELATIVE ${RADIO_SRC_DIR}/gui/colorlcd ${RADIO_SRC_DIR}/gui/colorlcd/themes/*.cpp)
|
||||
@@ -110,14 +120,15 @@ set(FIRMWARE_TARGET_SRC
|
||||
|
||||
if(BOOTLOADER)
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
../common/arm/loadboot.cpp
|
||||
)
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
../common/arm/loadboot.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(PULSES_SRC
|
||||
${PULSES_SRC}
|
||||
#flysky.cpp
|
||||
set(SRC
|
||||
${SRC}
|
||||
io/frsky_firmware_update.cpp
|
||||
io/multi_firmware_update.cpp
|
||||
)
|
||||
|
||||
set(STM32LIB_SRC
|
||||
@@ -126,6 +137,8 @@ set(STM32LIB_SRC
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_ltdc.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_tim.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma2d.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c
|
||||
STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c
|
||||
)
|
||||
|
||||
if(PYTHONINTERP_FOUND)
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
#if defined(SIMU)
|
||||
// not needed
|
||||
#elif defined(PCBNV14)
|
||||
const int8_t ana_direction[NUM_ANALOGS] = { 0 };
|
||||
const int8_t ana_direction[NUM_ANALOGS] = { 0 /*STICK1*/, 0 /*STICK2*/, 0 /*STICK3*/, 0 /*STICK4*/,
|
||||
0 /*POT1*/, 0 /*POT2*/, 0 /*SWA*/, 0 /*SWB*/,
|
||||
0 /*SWC*/, -1 /*SWD*/, 0 /*SWE*/, -1 /*SWF*/,
|
||||
0 /*SWH*/, 0 /*SWG*/,
|
||||
0 /*TX_VOLTAGE*/ };
|
||||
const uint8_t anas_mapping[NUM_ANALOGS] = { 0 /*STICK1*/, 1 /*STICK2*/, 2 /*STICK3*/, 3 /*STICK4*/,
|
||||
4 /*POT1*/, 5 /*POT2*/, 6 /*SWA*/, 13 /*SWB*/,
|
||||
7 /*SWC*/, 14 /*SWD*/, 8 /*SWE*/, 9 /*SWF*/,
|
||||
@@ -64,13 +68,18 @@
|
||||
#define FIRST_ANALOG_ADC 0
|
||||
#define NUM_MAIN_ANALOGS_ADC 10
|
||||
#define NUM_MAIN_ANALOGS_ADC_EXT (NUM_MAIN_ANALOGS - 10)
|
||||
#elif defined(PCBNV14) && defined(HALL_STICKS)
|
||||
#define FIRST_ANALOG_ADC 4
|
||||
#define NUM_MAIN_ANALOGS_ADC 9
|
||||
#else
|
||||
#define FIRST_ANALOG_ADC 0
|
||||
#define FIRST_SUB_ANALOG_ADC 0
|
||||
#define NUM_MAIN_ANALOGS_ADC (SUB_ANALOG_POS)
|
||||
#define NUM_SUB_ANALOGS_ADC (NUM_ANALOGS - SUB_ANALOG_POS)
|
||||
#endif
|
||||
|
||||
#ifndef NUM_SUB_ANALOGS_ADC
|
||||
#define NUM_SUB_ANALOGS_ADC 0
|
||||
#endif
|
||||
uint16_t adcValues[NUM_ANALOGS] __DMA;
|
||||
|
||||
void adcInit()
|
||||
@@ -104,7 +113,7 @@ void adcInit()
|
||||
ADC_MAIN->CR1 = ADC_CR1_SCAN;
|
||||
ADC_MAIN->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS;
|
||||
ADC_MAIN->SQR1 = (NUM_MAIN_ANALOGS_ADC-1) << 20; // bits 23:20 = number of conversions
|
||||
#if defined(PCBNV14)
|
||||
#if NUM_SUB_ANALOGS_ADC > 0
|
||||
ADC_SUB->CR1 = ADC_CR1_SCAN;
|
||||
ADC_SUB->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS;
|
||||
ADC_SUB->SQR1 = (NUM_SUB_ANALOGS_ADC-1) << 20; // bits 23:20 = number of conversions
|
||||
@@ -138,11 +147,16 @@ void adcInit()
|
||||
ADC_MAIN->SQR2 = (ADC_CHANNEL_SWE<<0) + (ADC_CHANNEL_SWF<<5) + (ADC_CHANNEL_LIBATT<<10) + (ADC_CHANNEL_DRYBATT<<15); // conversions 7 and more
|
||||
ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_SWA<<10) + (ADC_CHANNEL_SWB<<15) + (ADC_CHANNEL_SWC<<20) + (ADC_CHANNEL_SWD<<25); // conversions 1 to 6
|
||||
#elif defined(PCBNV14)
|
||||
#if !defined(HALL_STICKS)
|
||||
ADC_MAIN->SQR1 |= (ADC_CHANNEL_BATT <<0 );
|
||||
ADC_MAIN->SQR2 = (ADC_CHANNEL_SWA << 0) + (ADC_CHANNEL_SWC << 5) + (ADC_CHANNEL_SWE << 10) + (ADC_CHANNEL_SWF << 15) + (ADC_CHANNEL_SWG << 20) + (ADC_CHANNEL_SWH << 25); // conversions 7 and more
|
||||
ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6
|
||||
ADC_SUB->SQR3 = (ADC_CHANNEL_SWB<<0) + (ADC_CHANNEL_SWD<<5); // conversions 1 to 2
|
||||
|
||||
#else
|
||||
ADC_MAIN->SQR2 = (ADC_CHANNEL_SWG << 0) + (ADC_CHANNEL_SWH << 5) + (ADC_CHANNEL_BATT << 10); // conversions 7 and more
|
||||
ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_SWA<<10) + (ADC_CHANNEL_SWC<<15) + (ADC_CHANNEL_SWE<<20) + (ADC_CHANNEL_SWF<<25); // conversions 1 to 6
|
||||
ADC_SUB->SQR3 = (ADC_CHANNEL_SWB<<0) + (ADC_CHANNEL_SWD<<5); // conversions 1 to 2
|
||||
#endif
|
||||
#else
|
||||
ADC_MAIN->SQR2 = (ADC_CHANNEL_POT3<<0) + (ADC_CHANNEL_SLIDER1<<5) + (ADC_CHANNEL_SLIDER2<<10) + (ADC_CHANNEL_BATT<<15); // conversions 7 and more
|
||||
ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6
|
||||
@@ -159,7 +173,7 @@ void adcInit()
|
||||
ADC_MAIN_DMA_Stream->NDTR = NUM_MAIN_ANALOGS_ADC;
|
||||
ADC_MAIN_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0;
|
||||
|
||||
#if defined(PCBNV14)
|
||||
#if NUM_SUB_ANALOGS > 0
|
||||
ADC_SUB->SMPR1 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24);
|
||||
ADC_SUB->SMPR2 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24) + (ADC_SAMPTIME<<27);
|
||||
|
||||
@@ -192,6 +206,8 @@ void adcInit()
|
||||
sticksPwmInit();
|
||||
}
|
||||
#endif
|
||||
//Avoid reading wrong values when the adcRead not be called.
|
||||
adcRead();
|
||||
}
|
||||
|
||||
void adcSingleRead()
|
||||
@@ -201,7 +217,7 @@ void adcSingleRead()
|
||||
ADC_MAIN_SET_DMA_FLAGS();
|
||||
ADC_MAIN_DMA_Stream->CR |= DMA_SxCR_EN; // Enable DMA
|
||||
ADC_MAIN->CR2 |= (uint32_t) ADC_CR2_SWSTART;
|
||||
#if defined(PCBNV14)
|
||||
#if NUM_SUB_ANALOGS_ADC > 0
|
||||
ADC_SUB_DMA_Stream->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
ADC_SUB->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR);
|
||||
ADC_SUB_SET_DMA_FLAGS();
|
||||
|
||||
@@ -78,6 +78,8 @@
|
||||
|
||||
#define READ_DREQ() (GPIO_ReadInputDataBit(AUDIO_DREQ_GPIO, AUDIO_DREQ_GPIO_PIN))
|
||||
|
||||
bool isAudioOn = false;
|
||||
|
||||
void audioSpiInit(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
@@ -164,13 +166,10 @@ void audioSpiSetSpeed(uint8_t speed)
|
||||
break;
|
||||
}
|
||||
AUDIO_SPI->CR1 |= 0x01 << 6;
|
||||
|
||||
//SPI_Cmd(AUDIO_SPI, ENABLE);
|
||||
}
|
||||
|
||||
uint8_t audioSpiReadWriteByte(uint8_t value)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint16_t time_out = 0x0FFF;
|
||||
while (SPI_I2S_GetFlagStatus(AUDIO_SPI, SPI_I2S_FLAG_TXE) == RESET) {
|
||||
if (--time_out == 0) {
|
||||
@@ -199,10 +198,7 @@ uint8_t audioSpiReadWriteByte(uint8_t value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = SPI_I2S_ReceiveData(AUDIO_SPI);
|
||||
|
||||
return ret;
|
||||
return SPI_I2S_ReceiveData(AUDIO_SPI);
|
||||
}
|
||||
|
||||
uint8_t audioWaitDreq(int32_t delay_us)
|
||||
@@ -321,7 +317,6 @@ uint8_t audioSoftReset(void)
|
||||
audioSpiReadWriteByte(0X0);
|
||||
delay_01us(100); // 10us
|
||||
XDCS_HIGH();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -386,15 +381,8 @@ void Audio_Sine_Test(void)
|
||||
|
||||
uint32_t audioSpiWriteData(const uint8_t * buffer, uint32_t size)
|
||||
{
|
||||
int i = 55;
|
||||
|
||||
XDCS_LOW();
|
||||
|
||||
if (58 == i)
|
||||
{
|
||||
TRACE("\nbuffer = %d \r\n)", buffer);
|
||||
}
|
||||
|
||||
uint32_t index = 0;
|
||||
while (index < size && READ_DREQ() != 0) {
|
||||
for (int i=0; i<MP3_BUFFER_SIZE && index<size; i++) {
|
||||
@@ -426,7 +414,20 @@ void audioSendRiffHeader()
|
||||
audioSpiWriteBuffer(RiffHeader, sizeof(RiffHeader));
|
||||
}
|
||||
|
||||
#if defined(PCBNV14)
|
||||
void audioOn()
|
||||
{
|
||||
if(isAudioOn) return;
|
||||
GPIO_SetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN);
|
||||
isAudioOn = true;
|
||||
}
|
||||
|
||||
void audioOff()
|
||||
{
|
||||
if(!isAudioOn) return;
|
||||
GPIO_ResetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN);
|
||||
isAudioOn = false;
|
||||
}
|
||||
|
||||
void audioShutdownInit()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
@@ -436,21 +437,26 @@ void audioShutdownInit()
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(AUDIO_SHUTDOWN_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN); // we never RESET it, there is a 2s delay on STARTUP
|
||||
audioOn();
|
||||
}
|
||||
#endif
|
||||
|
||||
void audioInit()
|
||||
{
|
||||
#if defined(PCBNV14)
|
||||
audioShutdownInit();
|
||||
// TODO X10 code missing
|
||||
#endif
|
||||
|
||||
audioSpiInit();
|
||||
/* Audio setting */
|
||||
audioSpiSetSpeed(SPI_SPEED_64);
|
||||
audioHardReset();
|
||||
audioSoftReset();
|
||||
audioSpiSetSpeed(SPI_SPEED_8);
|
||||
delay_01us(10000);
|
||||
audioSendRiffHeader();
|
||||
audioOn();
|
||||
delay_01us(10000);
|
||||
|
||||
}
|
||||
|
||||
uint8_t * currentBuffer = NULL;
|
||||
uint8_t * currentBuffer = nullptr;
|
||||
uint32_t currentSize = 0;
|
||||
int16_t newVolume = -1;
|
||||
|
||||
@@ -461,13 +467,14 @@ void audioSetCurrentBuffer(const AudioBuffer * buffer)
|
||||
currentSize = buffer->size * 2;
|
||||
}
|
||||
else {
|
||||
currentBuffer = NULL;
|
||||
currentBuffer = nullptr;
|
||||
currentSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void audioConsumeCurrentBuffer()
|
||||
{
|
||||
//return;
|
||||
if (newVolume >= 0) {
|
||||
uint8_t value = newVolume;
|
||||
audioSpiWriteCmd(SPI_VOL, (value << 8) + value);
|
||||
@@ -485,7 +492,7 @@ void audioConsumeCurrentBuffer()
|
||||
currentSize -= written;
|
||||
if (currentSize == 0) {
|
||||
audioQueue.buffersFifo.freeNextFilledBuffer();
|
||||
currentBuffer = NULL;
|
||||
currentBuffer = nullptr;
|
||||
currentSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,32 @@ void backlightInit()
|
||||
BACKLIGHT_TIMER->BDTR |= TIM_BDTR_MOE;
|
||||
}
|
||||
|
||||
uint8_t lastDutyCycle = 0;
|
||||
|
||||
void backlightEnable(uint8_t dutyCycle)
|
||||
{
|
||||
// TODO SET provided cycle - for now ensure backlight will be on
|
||||
//BACKLIGHT_TIMER->CCR1 = dutyCycle;
|
||||
BACKLIGHT_TIMER->CCR1 = BACKLIGHT_LEVEL_MAX;
|
||||
BACKLIGHT_TIMER->CCR1 = dutyCycle;
|
||||
if(!dutyCycle) {
|
||||
//experimental to turn off LCD when no backlight
|
||||
if(lcdOffFunction) lcdOffFunction();
|
||||
}
|
||||
else if(!lastDutyCycle) {
|
||||
if(lcdOnFunction) lcdOnFunction();
|
||||
else lcdInit();
|
||||
}
|
||||
lastDutyCycle = dutyCycle;
|
||||
}
|
||||
|
||||
void lcdOff() {
|
||||
backlightEnable(0);
|
||||
}
|
||||
|
||||
void lcdOn(){
|
||||
if(lcdOnFunction) lcdOnFunction();
|
||||
else lcdInit();
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX);
|
||||
}
|
||||
|
||||
bool isBacklightEnabled() {
|
||||
return lastDutyCycle != 0;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,17 @@
|
||||
|
||||
#define __BATTERY_DRIVER_C__
|
||||
|
||||
#define BATTERY_W 140
|
||||
#define BATTERY_H 320
|
||||
#define BATTERY_TOP ((LCD_H - BATTERY_H)/2)
|
||||
#define BATTERY_CONNECTOR_W 32
|
||||
#define BATTERY_CONNECTOR_H 10
|
||||
#define BATTERY_BORDER 4
|
||||
#define BATTERY_W_INNER (BATTERY_W - 2*BATTERY_BORDER)
|
||||
#define BATTERY_H_INNER (BATTERY_H - 2*BATTERY_BORDER)
|
||||
#define BATTERY_TOP_INNER (BATTERY_TOP + BATTERY_BORDER)
|
||||
|
||||
void init_battery_charge()
|
||||
void battery_charge_init()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = PWR_CHARGE_FINISHED_GPIO_PIN | PWR_CHARGING_GPIO_PIN;
|
||||
@@ -34,51 +43,155 @@ void init_battery_charge()
|
||||
GPIO_SetBits(PWR_CHARGING_GPIO, PWR_CHARGE_FINISHED_GPIO_PIN | PWR_CHARGING_GPIO_PIN);
|
||||
}
|
||||
|
||||
#define CHARGE_SAMPLES 10
|
||||
|
||||
uint16_t get_battery_charge_state()
|
||||
{
|
||||
if (!READ_CHARGE_FINISHED_STATE())
|
||||
{
|
||||
return CHARGE_FINISHED;
|
||||
}
|
||||
else if (!READ_CHARGING_STATE())
|
||||
{
|
||||
return CHARGE_STARTED;
|
||||
}
|
||||
static uint16_t chargeSamples[CHARGE_SAMPLES] = {0};
|
||||
static uint16_t chargeSampleIndex = 0;
|
||||
uint16_t chargeState = CHARGE_UNKNOWN;
|
||||
int maxSamples = CHARGE_SAMPLES;
|
||||
#if !defined(SIMU)
|
||||
bool isFinished = !READ_CHARGE_FINISHED_STATE();
|
||||
bool isCharging = !READ_CHARGING_STATE();
|
||||
//maxSamples = boardState == BOARD_POWER_OFF ? CHARGE_SAMPLES/2 : CHARGE_SAMPLES;
|
||||
if(chargeSampleIndex >= maxSamples) chargeSampleIndex = 0;
|
||||
uint16_t currentChargeState = isFinished ? CHARGE_FINISHED : isCharging ? CHARGE_STARTED : CHARGE_NONE;
|
||||
chargeSamples[chargeSampleIndex++] = currentChargeState;
|
||||
//TRACE("CHARGE sample %d value %d", chargeSampleIndex -1, currentChargeState);
|
||||
#endif
|
||||
uint8_t temp1 = 0, temp2 = 0, temp3 = 0;
|
||||
for(int index = 0; index < maxSamples; index++) {
|
||||
if(chargeSamples[index] == CHARGE_FINISHED)
|
||||
{
|
||||
temp1++;
|
||||
}
|
||||
else if(chargeSamples[index] == CHARGE_STARTED)
|
||||
{
|
||||
temp2++;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp3++;
|
||||
}
|
||||
|
||||
return CHARGE_NONE;
|
||||
if(temp1>=temp2&& temp1>temp3)
|
||||
{
|
||||
chargeState = CHARGE_FINISHED;
|
||||
}
|
||||
else if(temp2>=temp1&& temp2>temp3)
|
||||
{
|
||||
chargeState = CHARGE_STARTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
chargeState = CHARGE_NONE;
|
||||
}
|
||||
}
|
||||
return chargeState;
|
||||
}
|
||||
|
||||
void drawChargingInfo(uint16_t chargeState){
|
||||
static int progress = 0;
|
||||
const char* text = chargeState == CHARGE_STARTED ? STR_BATTERYCHARGING : STR_BATTERYFULL;
|
||||
int h = 0;
|
||||
LcdFlags color = 0;
|
||||
if(CHARGE_STARTED == chargeState)
|
||||
{
|
||||
if(progress >= 100)
|
||||
{
|
||||
progress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
progress+=25;
|
||||
}
|
||||
text = STR_BATTERYCHARGING;
|
||||
h = ((BATTERY_H_INNER * progress) / 100);
|
||||
color = ROUND|BATTERY_CHARGE_COLOR;
|
||||
}
|
||||
else if(CHARGE_FINISHED == chargeState)
|
||||
{
|
||||
text = STR_BATTERYFULL;
|
||||
h = BATTERY_H_INNER;
|
||||
color = ROUND|BATTERY_CHARGE_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = STR_BATTERYNONE;
|
||||
h = BATTERY_H_INNER;
|
||||
color = ROUND|TRIM_SHADOW_COLOR;
|
||||
}
|
||||
|
||||
uint16_t getBatteryVoltage()
|
||||
BACKLIGHT_ENABLE();
|
||||
lcd->drawSizedText(LCD_W/2, LCD_H-50, text, strlen(text), CENTERED|MAINVIEW_PANES_COLOR);
|
||||
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_W)/2, BATTERY_TOP, BATTERY_W, BATTERY_H, SOLID, ROUND|MAINVIEW_PANES_COLOR);
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_W_INNER)/2, BATTERY_TOP_INNER, BATTERY_W_INNER, BATTERY_H_INNER, SOLID, ROUND|TRIM_SHADOW_COLOR);
|
||||
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_W_INNER)/2, BATTERY_TOP_INNER + BATTERY_H_INNER - h , BATTERY_W_INNER, h, SOLID, color);
|
||||
lcd->drawFilledRect((LCD_W - BATTERY_CONNECTOR_W)/2, BATTERY_TOP-BATTERY_CONNECTOR_H , BATTERY_CONNECTOR_W, BATTERY_CONNECTOR_H, SOLID, MAINVIEW_PANES_COLOR);
|
||||
}
|
||||
#define CHARGE_INFO_DURATION 500
|
||||
//this method should be called by timer interrupt or by GPIO interrupt
|
||||
void handle_battery_charge(uint32_t last_press_time)
|
||||
{
|
||||
#if defined (SIMU)
|
||||
return 350 + g_eeGeneral.txVoltageCalibration;
|
||||
#else
|
||||
int32_t t = getAnalogValue(TX_VOLTAGE) + g_eeGeneral.txVoltageCalibration;
|
||||
#if !defined(SIMU)
|
||||
static uint32_t updateTime = 0;
|
||||
static uint16_t lastState = CHARGE_UNKNOWN;
|
||||
static uint32_t info_until = 0;
|
||||
static bool lcdInited = false;
|
||||
|
||||
t *= ( 3300 * 20);
|
||||
t /= ( 4095 * 10);
|
||||
t = ( t * 100 + 500 ) / 1000;
|
||||
if(boardState != BOARD_POWER_OFF) return;
|
||||
uint32_t now = get_tmr10ms();
|
||||
uint16_t chargeState = get_battery_charge_state();
|
||||
if(chargeState != CHARGE_UNKNOWN) {
|
||||
|
||||
return t;
|
||||
if(lastState != chargeState) {
|
||||
//avoid positive check when none and unknown
|
||||
if(lastState + chargeState > 1) {
|
||||
//charge state changed - last state known
|
||||
info_until = now + (CHARGE_INFO_DURATION);
|
||||
}
|
||||
}
|
||||
//power buttons pressed
|
||||
else if(now - last_press_time < POWER_ON_DELAY) {
|
||||
info_until = now + CHARGE_INFO_DURATION;
|
||||
}
|
||||
lastState = chargeState;
|
||||
}
|
||||
|
||||
if(now > info_until) {
|
||||
info_until = 0;
|
||||
lcd->clear();
|
||||
BACKLIGHT_DISABLE();
|
||||
if(lcdInited) {
|
||||
lcdOff();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(updateTime == 0 || ((get_tmr10ms() - updateTime) >= 50))
|
||||
{
|
||||
if(!lcdInited) {
|
||||
backlightInit();
|
||||
lcdInit();
|
||||
lcdInited = true;
|
||||
}
|
||||
else {
|
||||
lcdOn();
|
||||
}
|
||||
updateTime = get_tmr10ms();
|
||||
lcdNextLayer();
|
||||
lcd->clear();
|
||||
drawChargingInfo(chargeState);
|
||||
lcdRefresh();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t getBatteryVoltage()
|
||||
{
|
||||
int32_t instant_vbat = anaIn(TX_VOLTAGE); // using filtered ADC value on purpose
|
||||
return (uint16_t)((instant_vbat * (1000 + g_eeGeneral.txVoltageCalibration)) / 2942);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
enum ChargeState
|
||||
{
|
||||
CHARGE_UNKNOWN,
|
||||
CHARGE_NONE,
|
||||
CHARGE_STARTED,
|
||||
CHARGE_FINISHED
|
||||
@@ -48,25 +49,9 @@ enum ChargeState
|
||||
#define READ_CHARGE_FINISHED_STATE() GPIO_ReadInputDataBit( PWR_CHARGE_FINISHED_GPIO, PWR_CHARGE_FINISHED_GPIO_PIN )
|
||||
#define READ_CHARGING_STATE() GPIO_ReadInputDataBit( PWR_CHARGING_GPIO, PWR_CHARGING_GPIO_PIN )
|
||||
|
||||
extern void init_battery_charge();
|
||||
extern void battery_charge_init();
|
||||
extern void handle_battery_charge(uint32_t last_press_time);
|
||||
extern uint16_t get_battery_charge_state();
|
||||
extern uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "opentx.h"
|
||||
#include "touch.h"
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -62,8 +63,6 @@ void init1msTimer()
|
||||
NVIC_EnableIRQ(INTERRUPT_xMS_IRQn);
|
||||
NVIC_SetPriority(INTERRUPT_xMS_IRQn, 7);
|
||||
}
|
||||
|
||||
// TODO use the same than board_sky9x.cpp
|
||||
void interrupt1ms()
|
||||
{
|
||||
static uint8_t pre_scale; // Used to get 10 Hz counter
|
||||
@@ -74,7 +73,7 @@ void interrupt1ms()
|
||||
debugCounter1ms++;
|
||||
#endif
|
||||
|
||||
#if defined(HAPTIC)
|
||||
#if defined(HAPTIC) && !defined(BOOT)
|
||||
if (pre_scale == 5 || pre_scale == 10) {
|
||||
DEBUG_TIMER_START(debugTimerHaptic);
|
||||
HAPTIC_HEARTBEAT();
|
||||
@@ -85,7 +84,7 @@ void interrupt1ms()
|
||||
if (pre_scale == 10) {
|
||||
pre_scale = 0;
|
||||
#if !defined(SIMU)
|
||||
hall_stick_loop();
|
||||
if (boardState == BOARD_STARTED) hall_stick_loop();
|
||||
#endif
|
||||
DEBUG_TIMER_START(debugTimerPer10ms);
|
||||
DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod);
|
||||
@@ -96,18 +95,70 @@ void interrupt1ms()
|
||||
DEBUG_TIMER_START(debugTimerRotEnc);
|
||||
DEBUG_TIMER_STOP(debugTimerRotEnc);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
extern "C" void INTERRUPT_xMS_IRQHandler()
|
||||
{
|
||||
INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF;
|
||||
interrupt1ms();
|
||||
DEBUG_INTERRUPT(INT_1MS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SEMIHOSTING)
|
||||
extern "C" void initialise_monitor_handles();
|
||||
#endif
|
||||
|
||||
|
||||
void delay_self(int count)
|
||||
{
|
||||
for (int i = 50000; i > 0; i--)
|
||||
{
|
||||
for (; count > 0; count--);
|
||||
}
|
||||
}
|
||||
#define RCC_AHB1PeriphMinimum (PWR_RCC_AHB1Periph |\
|
||||
LCD_RCC_AHB1Periph |\
|
||||
BACKLIGHT_RCC_AHB1Periph |\
|
||||
SDRAM_RCC_AHB1Periph \
|
||||
)
|
||||
#define RCC_AHB1PeriphOther (SD_RCC_AHB1Periph |\
|
||||
AUDIO_RCC_AHB1Periph |\
|
||||
MONITOR_RCC_AHB1Periph |\
|
||||
KEYS_RCC_AHB1Periph |\
|
||||
ADC_RCC_AHB1Periph |\
|
||||
AUX_SERIAL_RCC_AHB1Periph |\
|
||||
TELEMETRY_RCC_AHB1Periph |\
|
||||
TRAINER_RCC_AHB1Periph |\
|
||||
AUDIO_RCC_AHB1Periph |\
|
||||
HAPTIC_RCC_AHB1Periph |\
|
||||
INTMODULE_RCC_AHB1Periph |\
|
||||
INTMODULE_RCC_AHB1Periph|\
|
||||
EXTMODULE_RCC_AHB1Periph\
|
||||
)
|
||||
#define RCC_AHB3PeriphMinimum (SDRAM_RCC_AHB3Periph)
|
||||
|
||||
#define RCC_APB1PeriphMinimum (INTERRUPT_xMS_RCC_APB1Periph |\
|
||||
TIMER_2MHz_RCC_APB1Periph |\
|
||||
BACKLIGHT_RCC_APB1Periph \
|
||||
)
|
||||
|
||||
#define RCC_APB1PeriphOther (TELEMETRY_RCC_APB1Periph |\
|
||||
TRAINER_RCC_APB1Periph |\
|
||||
INTMODULE_RCC_APB1Periph |\
|
||||
HALL_RCC_APB1Periph |\
|
||||
EXTMODULE_RCC_APB1Periph |\
|
||||
INTMODULE_RCC_APB1Periph |\
|
||||
AUX_SERIAL_RCC_APB1Periph \
|
||||
)
|
||||
#define RCC_APB2PeriphMinimum (LCD_RCC_APB2Periph)
|
||||
|
||||
#define RCC_APB2PeriphOther (ADC_RCC_APB2Periph |\
|
||||
HAPTIC_RCC_APB2Periph |\
|
||||
AUX_SERIAL_RCC_APB2Periph |\
|
||||
AUDIO_RCC_APB2Periph |\
|
||||
EXTMODULE_RCC_APB2Periph \
|
||||
)
|
||||
|
||||
void boardInit()
|
||||
{
|
||||
#if defined(SEMIHOSTING)
|
||||
@@ -115,51 +166,15 @@ void boardInit()
|
||||
#endif
|
||||
|
||||
#if !defined(SIMU)
|
||||
RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph |
|
||||
LCD_RCC_AHB1Periph |
|
||||
BACKLIGHT_RCC_AHB1Periph |
|
||||
SD_RCC_AHB1Periph |
|
||||
SDRAM_RCC_AHB1Periph |
|
||||
AUDIO_RCC_AHB1Periph |
|
||||
MONITOR_RCC_AHB1Periph |
|
||||
KEYS_RCC_AHB1Periph |
|
||||
ADC_RCC_AHB1Periph |
|
||||
AUX_SERIAL_RCC_AHB1Periph |
|
||||
TELEMETRY_RCC_AHB1Periph |
|
||||
TRAINER_RCC_AHB1Periph |
|
||||
AUDIO_RCC_AHB1Periph |
|
||||
HAPTIC_RCC_AHB1Periph |
|
||||
INTMODULE_RCC_AHB1Periph |
|
||||
HALL_RCC_AHB1Periph |
|
||||
EXTMODULE_RCC_AHB1Periph,
|
||||
ENABLE);
|
||||
|
||||
RCC_AHB3PeriphClockCmd(SDRAM_RCC_AHB3Periph,
|
||||
ENABLE);
|
||||
|
||||
RCC_APB1PeriphClockCmd(INTERRUPT_xMS_RCC_APB1Periph |
|
||||
TIMER_2MHz_RCC_APB1Periph |
|
||||
TELEMETRY_RCC_APB1Periph |
|
||||
TRAINER_RCC_APB1Periph |
|
||||
INTMODULE_RCC_APB1Periph |
|
||||
HALL_RCC_APB1Periph |
|
||||
EXTMODULE_RCC_APB1Periph |
|
||||
BACKLIGHT_RCC_APB1Periph,
|
||||
ENABLE);
|
||||
|
||||
RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph |
|
||||
ADC_RCC_APB2Periph |
|
||||
HAPTIC_RCC_APB2Periph |
|
||||
AUX_SERIAL_RCC_APB2Periph |
|
||||
INTMODULE_RCC_APB2Periph |
|
||||
AUDIO_RCC_APB2Periph |
|
||||
EXTMODULE_RCC_APB2Periph,
|
||||
ENABLE);
|
||||
|
||||
pwrInit();
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1PeriphMinimum | RCC_AHB1PeriphOther, ENABLE);
|
||||
RCC_AHB3PeriphClockCmd(RCC_AHB3PeriphMinimum, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1PeriphMinimum | RCC_APB1PeriphOther, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2PeriphMinimum | RCC_APB2PeriphOther, ENABLE);
|
||||
|
||||
__enable_irq();
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
auxSerialInit(0, 0); // default serial mode (None if DEBUG nm ot defined)
|
||||
auxSerialInit(0, 0); // default serial mode (None if DEBUG not defined)
|
||||
#endif
|
||||
|
||||
__enable_irq();
|
||||
@@ -167,52 +182,83 @@ void boardInit()
|
||||
TRACE("\nNV14 board started :)");
|
||||
delay_ms(10);
|
||||
TRACE("RCC->CSR = %08x", RCC->CSR);
|
||||
audioInit();
|
||||
|
||||
// we need to initialize g_FATFS_Obj here, because it is in .ram section (because of DMA access)
|
||||
pwrInit();
|
||||
extModuleInit();
|
||||
battery_charge_init();
|
||||
init2MhzTimer();
|
||||
init1msTimer();
|
||||
TouchInit();
|
||||
uint32_t press_start = 0;
|
||||
uint32_t press_end = 0;
|
||||
if(UNEXPECTED_SHUTDOWN() || true) pwrOn();
|
||||
|
||||
while (boardState == BOARD_POWER_OFF)
|
||||
{
|
||||
uint32_t now = get_tmr10ms();
|
||||
if (pwrPressed())
|
||||
{
|
||||
press_end = now;
|
||||
if (press_start == 0) press_start = now;
|
||||
if ((now - press_start) > POWER_ON_DELAY)
|
||||
{
|
||||
pwrOn();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint32_t press_end_touch = press_end;
|
||||
if(touchState.event == TE_UP)
|
||||
{
|
||||
touchState.event = TE_NONE;
|
||||
press_end_touch = touchState.time;
|
||||
}
|
||||
press_start = 0;
|
||||
handle_battery_charge(press_end_touch);
|
||||
delay_ms(20);
|
||||
press_end = 0;
|
||||
}
|
||||
}
|
||||
|
||||
keysInit();
|
||||
audioInit();
|
||||
// we need to initialize g_FATFS_Obj here, because it is in .ram section (because of DMA access)
|
||||
// and this section is un-initialized
|
||||
memset(&g_FATFS_Obj, 0, sizeof(g_FATFS_Obj));
|
||||
|
||||
init_battery_charge();
|
||||
monitorInit();
|
||||
keysInit();
|
||||
adcInit();
|
||||
backlightInit();
|
||||
lcdInit();
|
||||
#if defined(FLYSKY_HALL_STICKS)
|
||||
hall_stick_init(FLYSKY_HALL_BAUDRATE);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
init2MhzTimer();
|
||||
init1msTimer();
|
||||
usbInit();
|
||||
hapticInit();
|
||||
|
||||
TouchInit();
|
||||
|
||||
|
||||
boardState = BOARD_STARTED;
|
||||
#if defined(DEBUG)
|
||||
DBGMCU_APB1PeriphConfig(DBGMCU_IWDG_STOP|DBGMCU_TIM1_STOP|DBGMCU_TIM2_STOP|DBGMCU_TIM3_STOP|DBGMCU_TIM4_STOP|DBGMCU_TIM5_STOP|DBGMCU_TIM6_STOP|DBGMCU_TIM7_STOP|DBGMCU_TIM8_STOP|DBGMCU_TIM9_STOP|DBGMCU_TIM10_STOP|DBGMCU_TIM11_STOP|DBGMCU_TIM12_STOP|DBGMCU_TIM13_STOP|DBGMCU_TIM14_STOP, ENABLE);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void boardOff()
|
||||
{
|
||||
BACKLIGHT_DISABLE();
|
||||
lcd->drawFilledRect(0, 0, LCD_WIDTH, LCD_HEIGHT, SOLID, HEADER_BGCOLOR);
|
||||
lcdOff();
|
||||
|
||||
while (pwrPressed()) {
|
||||
wdt_reset();
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
|
||||
SysTick->CTRL = 0; // turn off systick
|
||||
pwrOff();
|
||||
#if !defined (SIMU)
|
||||
#if defined(HAPTIC) && !defined(BOOT)
|
||||
haptic.event(AU_ERROR);
|
||||
delay_ms(50);
|
||||
#endif
|
||||
while(1)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_intmodule_heartbeat()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -54,8 +54,8 @@
|
||||
|
||||
extern uint16_t sessionTimer;
|
||||
|
||||
#define SLAVE_MODE() (g_model.trainerMode == TRAINER_MODE_SLAVE)
|
||||
#define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET)
|
||||
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
|
||||
#define TRAINER_CONNECTED() (true)
|
||||
|
||||
PACK(typedef struct {
|
||||
uint8_t pxx2Enabled:1;
|
||||
@@ -95,7 +95,7 @@ uint32_t sdGetSpeed();
|
||||
#define SD_IS_HC() (sdIsHC())
|
||||
#define SD_GET_SPEED() (sdGetSpeed())
|
||||
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
||||
#define SD_CARD_PRESENT() (true)
|
||||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
||||
void sdInit();
|
||||
void sdMount();
|
||||
void sdDone();
|
||||
@@ -133,8 +133,8 @@ void SDRAM_Init();
|
||||
// Pulses driver
|
||||
#define INTERNAL_MODULE_OFF() GPIO_SetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
|
||||
#define INTERNAL_MODULE_ON() GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN)
|
||||
#define EXTERNAL_MODULE_ON() GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
|
||||
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
|
||||
void EXTERNAL_MODULE_ON();
|
||||
void EXTERNAL_MODULE_OFF();
|
||||
#define BLUETOOTH_MODULE_ON() GPIO_ResetBits(BLUETOOTH_ON_GPIO, BLUETOOTH_ON_GPIO_PIN)
|
||||
#define BLUETOOTH_MODULE_OFF() GPIO_SetBits(BLUETOOTH_ON_GPIO, BLUETOOTH_ON_GPIO_PIN)
|
||||
#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
|
||||
@@ -162,6 +162,17 @@ void stop_trainer_capture();
|
||||
// Keys driver
|
||||
enum EnumKeys
|
||||
{
|
||||
KEY_ENTER,
|
||||
KEY_EXIT,
|
||||
KEY_PGUP,
|
||||
KEY_PGDN,
|
||||
KEY_UP,
|
||||
KEY_DOWN,
|
||||
KEY_RIGHT,
|
||||
KEY_LEFT,
|
||||
KEY_TELEM,
|
||||
KEY_MENU,
|
||||
KEY_RADIO,
|
||||
TRM_BASE,
|
||||
TRM_LH_DWN = TRM_BASE,
|
||||
TRM_LH_UP,
|
||||
@@ -173,14 +184,32 @@ enum EnumKeys
|
||||
TRM_RH_UP,
|
||||
TRM_LS_DWN,
|
||||
TRM_LS_UP,
|
||||
TRM_RS_DWN,
|
||||
TRM_RS_UP,
|
||||
TRM_LAST = TRM_RS_UP,
|
||||
TRM_LEFT_CLICK,
|
||||
TRM_RIGHT_CLICK,
|
||||
TRM_LAST = TRM_RIGHT_CLICK,
|
||||
NUM_KEYS
|
||||
};
|
||||
|
||||
#define IS_SHIFT_KEY(index) (false)
|
||||
#define IS_SHIFT_PRESSED() (false)&é&é&é""
|
||||
#define IS_SHIFT_PRESSED() (false)
|
||||
enum VirtualKeys {
|
||||
VKEY_MIN,
|
||||
VKEY_MAX,
|
||||
VKEY_INC,
|
||||
VKEY_DEC,
|
||||
VKEY_INC_LARGE,
|
||||
VKEY_DEC_LARGE,
|
||||
VKEY_DEFAULT,
|
||||
};
|
||||
|
||||
enum LUATouchEvent {
|
||||
TOUCH_DOWN = 1,
|
||||
TOUCH_UP,
|
||||
TOUCH_SLIDE_UP,
|
||||
TOUCH_SLIDE_DOWN,
|
||||
TOUCH_SLIDE_LEFT,
|
||||
TOUCH_SLIDE_RIGHT,
|
||||
};
|
||||
|
||||
enum EnumSwitches
|
||||
{
|
||||
@@ -228,6 +257,13 @@ enum EnumSwitchesPositions
|
||||
};
|
||||
|
||||
#define STORAGE_NUM_SWITCHES_POSITIONS (STORAGE_NUM_SWITCHES * 3)
|
||||
enum EnumPowerupState
|
||||
{
|
||||
BOARD_POWER_OFF = 0xCAFEDEAD,
|
||||
BOARD_POWER_ON = 0xDEADBEEF,
|
||||
BOARD_STARTED = 0xBAADF00D,
|
||||
BOARD_REBOOT = 0xC00010FF,
|
||||
};
|
||||
|
||||
void monitorInit();
|
||||
void keysInit();
|
||||
@@ -245,14 +281,15 @@ uint32_t readTrims();
|
||||
#define DBLKEYS_PRESSED_LFT_DWN(in) (false)
|
||||
|
||||
// WDT driver
|
||||
#define WDTO_500MS 500
|
||||
extern uint32_t powerupReason;
|
||||
extern uint32_t boardState;
|
||||
|
||||
#define SHUTDOWN_REQUEST 0xDEADBEEF
|
||||
#define NO_SHUTDOWN_REQUEST ~SHUTDOWN_REQUEST
|
||||
#define DIRTY_SHUTDOWN 0xCAFEDEAD
|
||||
#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN
|
||||
|
||||
#define WDG_DURATION 500 /*ms*/
|
||||
void watchdogInit(unsigned int duration);
|
||||
#if defined(SIMU)
|
||||
#define WAS_RESET_BY_WATCHDOG() (false)
|
||||
@@ -336,10 +373,11 @@ void adcInit();
|
||||
void adcRead();
|
||||
uint16_t getAnalogValue(uint8_t index);
|
||||
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
|
||||
uint16_t getBattery2Voltage(); // returns current battery voltage in 10mV steps
|
||||
|
||||
#define BATTERY_WARN 37 // 3.7V
|
||||
#define BATTERY_WARN 36 // 3.6V
|
||||
#define BATTERY_MIN 35 // 3.5V
|
||||
#define BATTERY_MAX 43 // 4.3V
|
||||
#define BATTERY_MAX 42 // 4.2V
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
@@ -347,20 +385,24 @@ extern "C" {
|
||||
|
||||
// Power driver
|
||||
#define SOFT_PWR_CTRL
|
||||
#define POWER_ON_DELAY 100 // 3s
|
||||
void pwrInit();
|
||||
void extModuleInit();
|
||||
uint32_t pwrCheck();
|
||||
#if defined(PCBFLYSKY)
|
||||
uint32_t lowPowerCheck();
|
||||
#endif
|
||||
|
||||
//TBD removed?!
|
||||
uint8_t UsbModeSelect( uint32_t index );
|
||||
void pwrOn();
|
||||
void pwrSoftReboot();
|
||||
void pwrOff();
|
||||
void pwrResetHandler();
|
||||
bool pwrPressed();
|
||||
uint32_t pwrPressedDuration();
|
||||
uint32_t pwrPressedDuration();;
|
||||
#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN)
|
||||
#define UNEXPECTED_SHUTDOWN() (false)
|
||||
#else
|
||||
#define UNEXPECTED_SHUTDOWN() ((powerupReason == DIRTY_SHUTDOWN) || WAS_RESET_BY_WATCHDOG_OR_SOFTWARE())
|
||||
#define UNEXPECTED_SHUTDOWN() (powerupReason == DIRTY_SHUTDOWN)
|
||||
#endif
|
||||
|
||||
// LCD driver
|
||||
@@ -377,7 +419,8 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x,
|
||||
void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h);
|
||||
void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format);
|
||||
void lcdSetContrast();
|
||||
#define lcdOff() backlightEnable(0) /* just disable the backlight */
|
||||
void lcdOff();
|
||||
void lcdOn();
|
||||
#define lcdSetRefVolt(...)
|
||||
#define lcdRefreshWait(...)
|
||||
void lcdStoreBackupBuffer();
|
||||
@@ -385,10 +428,12 @@ int lcdRestoreBackupBuffer();
|
||||
|
||||
// Backlight driver
|
||||
void backlightInit();
|
||||
#if defined(SIMU)
|
||||
#if defined(SIMU) || !defined(__cplusplus)
|
||||
#define backlightEnable(...)
|
||||
#define isBacklightEnabled() (true)
|
||||
#else
|
||||
void backlightEnable(uint8_t dutyCycle);
|
||||
void backlightEnable(uint8_t dutyCycle = 0);
|
||||
bool isBacklightEnabled();
|
||||
#endif
|
||||
|
||||
#define BACKLIGHT_LEVEL_MAX 100
|
||||
@@ -396,12 +441,11 @@ void backlightEnable(uint8_t dutyCycle);
|
||||
|
||||
#define BACKLIGHT_ENABLE() backlightEnable(globalData.unexpectedShutdown ? BACKLIGHT_LEVEL_MAX : BACKLIGHT_LEVEL_MAX-g_eeGeneral.backlightBright)
|
||||
#define BACKLIGHT_DISABLE() backlightEnable(globalData.unexpectedShutdown ? BACKLIGHT_LEVEL_MAX : ((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && (g_eeGeneral.backlightMode != e_backlight_mode_off)) ? 0 : g_eeGeneral.blOffBright)
|
||||
#define isBacklightEnabled() true
|
||||
|
||||
|
||||
#if !defined(SIMU)
|
||||
void usbJoystickUpdate();
|
||||
#endif
|
||||
#define USBD_MANUFACTURER_STRING "FlySky"
|
||||
#define USB_NAME "FlySky NV14"
|
||||
#define USB_MANUFACTURER 'F', 'l', 'y', 'S', 'k', 'y', ' ', ' ' /* 8 bytes */
|
||||
#define USB_PRODUCT 'N', 'V', '1', '4', ' ', ' ', ' ', ' ' /* 8 Bytes */
|
||||
@@ -419,6 +463,8 @@ void audioSpiSetSpeed(uint8_t speed);
|
||||
uint8_t audioHardReset();
|
||||
uint8_t audioSoftReset();
|
||||
void audioSendRiffHeader();
|
||||
void audioOn();
|
||||
void audioOff();
|
||||
|
||||
#define SPI_SPEED_2 0
|
||||
#define SPI_SPEED_4 1
|
||||
@@ -490,5 +536,4 @@ extern AuxSerialRxFifo auxSerialRxFifo;
|
||||
|
||||
uint8_t touchPressed(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||
|
||||
|
||||
#endif // _BOARD_H_
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "opentx.h"
|
||||
#include "../../common/arm/stm32/bootloader/boot.h"
|
||||
#include "../../common/arm/stm32/bootloader/bin_files.h"
|
||||
|
||||
#define SELECTED_COLOR (INVERS | DEFAULT_COLOR)
|
||||
|
||||
#include "bmp_plug_usb.lbm"
|
||||
#include "bmp_usb_plugged.lbm"
|
||||
#define DEFAULT_PADDING 28
|
||||
#define DOUBLE_PADDING 56
|
||||
#define MESSAGE_TOP (LCD_H - (2*DOUBLE_PADDING))
|
||||
//#include "bmp_plug_usb.lbm"
|
||||
//#include "bmp_usb_plugged.lbm"
|
||||
|
||||
const uint8_t LBM_FLASH[] = {
|
||||
#include "icon_flash.lbm"
|
||||
@@ -34,7 +35,7 @@ const uint8_t LBM_OK[] = {
|
||||
void bootloaderInitScreen()
|
||||
{
|
||||
lcdColorTable[DEFAULT_COLOR_INDEX] = BLACK;
|
||||
lcdColorTable[DEFAULT_BGCOLOR_INDEX] = WHITE;
|
||||
lcdColorTable[DEFAULT_BGCOLOR_INDEX] = WHITE;
|
||||
lcdColorTable[LINE_COLOR_INDEX] = RED;
|
||||
lcdColorTable[BARGRAPH1_COLOR_INDEX] = RED;
|
||||
lcdColorTable[BARGRAPH2_COLOR_INDEX] = RGB(73, 219, 62); // green
|
||||
@@ -42,52 +43,54 @@ void bootloaderInitScreen()
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX);
|
||||
}
|
||||
|
||||
static void bootloaderDrawTitle(unsigned int x, const char* text)
|
||||
static void bootloaderDrawTitle(const char* text)
|
||||
{
|
||||
lcdDrawText(x, 28, text);
|
||||
lcdDrawSolidFilledRect(28, 56, 422, 2, DEFAULT_COLOR);
|
||||
lcd->drawText(LCD_W/2, DEFAULT_PADDING, text, CENTERED | DEFAULT_COLOR);
|
||||
lcd->drawSolidFilledRect(DEFAULT_PADDING, DOUBLE_PADDING, LCD_W - DOUBLE_PADDING, 2, DEFAULT_COLOR);
|
||||
}
|
||||
|
||||
static void bootloaderDrawFooter()
|
||||
{
|
||||
lcdDrawSolidFilledRect(28, 234, 422, 2, DEFAULT_COLOR);
|
||||
lcd->drawSolidFilledRect(DEFAULT_PADDING, LCD_H - (DOUBLE_PADDING + 4), LCD_W - DOUBLE_PADDING, 2, DEFAULT_COLOR);
|
||||
}
|
||||
|
||||
void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
{
|
||||
#if defined(COLORLCD)
|
||||
lcdNextLayer();
|
||||
#endif
|
||||
// clear screen
|
||||
lcdDrawSolidFilledRect(0, 0, LCD_W-1, LCD_H-1, DEFAULT_BGCOLOR);
|
||||
|
||||
lcd->drawSolidFilledRect(0, 0, LCD_W-1, LCD_H-1, DEFAULT_BGCOLOR);
|
||||
int center = LCD_W/2;
|
||||
if (st == ST_START) {
|
||||
|
||||
bootloaderDrawTitle(88, "HORUS BOOTLOADER");
|
||||
bootloaderDrawTitle("NV14 BOOTLOADER");
|
||||
|
||||
lcdDrawBitmapPattern(90, 72, LBM_FLASH, DEFAULT_COLOR);
|
||||
lcdDrawText(124, 75, "Write Firmware");
|
||||
lcd->drawBitmapPattern(50, 72, LBM_FLASH, DEFAULT_COLOR);
|
||||
lcd->drawText(84, 75, "Write Firmware");
|
||||
|
||||
lcdDrawBitmapPattern(90, 107, LBM_EXIT, DEFAULT_COLOR);
|
||||
lcdDrawText(124, 110, "Exit");
|
||||
lcd->drawBitmapPattern(50, 107, LBM_EXIT, DEFAULT_COLOR);
|
||||
lcd->drawText(84, 110, "Exit");
|
||||
|
||||
lcdDrawSolidRect(119, (opt == 0) ? 72 : 107, 270, 26, 2, LINE_COLOR);
|
||||
lcd->drawSolidRect(79, (opt == 0) ? 72 : 107, LCD_W - 79 - 28, 26, 2, LINE_COLOR);
|
||||
|
||||
lcd->drawBitmap(60, 166, &BMP_PLUG_USB);
|
||||
lcdDrawText(195, 175, "Or plug in a USB cable");
|
||||
lcdDrawText(195, 200, "for mass storage");
|
||||
//lcd->drawBitmap(60, 166, &BMP_PLUG_USB);
|
||||
lcd->drawText(center, 175, "Or plug in a USB cable", CENTERED | DEFAULT_COLOR);
|
||||
lcd->drawText(center, 200, "for mass storage", CENTERED | DEFAULT_COLOR);
|
||||
|
||||
bootloaderDrawFooter();
|
||||
lcdDrawText( 36, 242, "Current Firmware:");
|
||||
lcdDrawText(200, 242, getOtherVersion(nullptr));
|
||||
lcd->drawText(center, LCD_H - DOUBLE_PADDING, "Current Firmware:", CENTERED | DEFAULT_COLOR);
|
||||
lcd->drawText(center, LCD_H - DEFAULT_PADDING, getOtherVersion(nullptr), CENTERED | DEFAULT_COLOR);
|
||||
}
|
||||
else if (st == ST_USB) {
|
||||
|
||||
lcd->drawBitmap(136, 98, &BMP_USB_PLUGGED);
|
||||
lcdDrawText(195, 128, "USB Connected");
|
||||
//lcd->drawBitmap(136, 98, &BMP_USB_PLUGGED);
|
||||
lcd->drawText(center, 128, "USB Connected", CENTERED | DEFAULT_COLOR);
|
||||
}
|
||||
else if (st == ST_FILE_LIST || st == ST_DIR_CHECK || st == ST_FLASH_CHECK ||
|
||||
st == ST_FLASHING || st == ST_FLASH_DONE) {
|
||||
|
||||
bootloaderDrawTitle(126, "SD>FIRMWARE");
|
||||
lcdDrawBitmapPattern(87, 16, LBM_SD, DEFAULT_COLOR);
|
||||
bootloaderDrawTitle("SD>FIRMWARE");
|
||||
lcd->drawBitmapPattern(DEFAULT_PADDING, 16, LBM_SD, DEFAULT_COLOR);
|
||||
|
||||
if (st == ST_FLASHING || st == ST_FLASH_DONE) {
|
||||
|
||||
@@ -98,39 +101,39 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
opt = 100; // Completed > 100%
|
||||
}
|
||||
|
||||
lcdDrawRect(70, 120, 340, 31, 2);
|
||||
lcdDrawSolidFilledRect(74, 124, (332 * opt) / 100, 23, color);
|
||||
lcd->drawRect(DEFAULT_PADDING, 120, LCD_W - DOUBLE_PADDING, 31, 2);
|
||||
lcd->drawSolidFilledRect(DEFAULT_PADDING+4, 124, ((LCD_W - DOUBLE_PADDING - 8) * opt) / 100, 23, color);
|
||||
}
|
||||
else if (st == ST_DIR_CHECK) {
|
||||
|
||||
if (opt == FR_NO_PATH) {
|
||||
lcdDrawText(90, 168, "Directory is missing");
|
||||
lcd->drawText(20, MESSAGE_TOP, "Directory is missing");
|
||||
}
|
||||
else {
|
||||
lcdDrawText(90, 168, "Directory is empty");
|
||||
lcd->drawText(20, MESSAGE_TOP, "Directory is empty");
|
||||
}
|
||||
|
||||
lcdDrawBitmapPattern(356, 158, LBM_ERROR, BARGRAPH1_COLOR);
|
||||
lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_ERROR, BARGRAPH1_COLOR);
|
||||
}
|
||||
else if (st == ST_FLASH_CHECK) {
|
||||
|
||||
bootloaderDrawFilename(str, 0, true);
|
||||
|
||||
if (opt == FC_ERROR) {
|
||||
lcdDrawText(94, 168, STR_INVALID_FIRMWARE);
|
||||
lcdDrawBitmapPattern(356, 158, LBM_ERROR, BARGRAPH1_COLOR);
|
||||
lcd->drawText(20, MESSAGE_TOP, STR_INVALID_FIRMWARE);
|
||||
lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_ERROR, BARGRAPH1_COLOR);
|
||||
}
|
||||
else if (opt == FC_OK) {
|
||||
VersionTag tag;
|
||||
extractFirmwareVersion(&tag);
|
||||
|
||||
lcdDrawText(168, 158, "Version:", RIGHT);
|
||||
lcdDrawText(174, 158, tag.version);
|
||||
lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP, "Version:", RIGHT);
|
||||
lcd->drawText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP, tag.version);
|
||||
|
||||
lcdDrawText(168, 178, "Radio:", RIGHT);
|
||||
lcdDrawText(174, 178, tag.flavour);
|
||||
lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP + DEFAULT_PADDING, "Radio:", RIGHT);
|
||||
lcd->drawText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP + DEFAULT_PADDING, tag.flavour);
|
||||
|
||||
lcdDrawBitmapPattern(356, 158, LBM_OK, BARGRAPH2_COLOR);
|
||||
lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_OK, BARGRAPH2_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,35 +141,35 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str)
|
||||
|
||||
if ( st != ST_DIR_CHECK && (st != ST_FLASH_CHECK || opt == FC_OK)) {
|
||||
|
||||
lcdDrawBitmapPattern(28, 242, LBM_FLASH, DEFAULT_COLOR);
|
||||
lcd->drawBitmapPattern(DEFAULT_PADDING, LCD_H - DOUBLE_PADDING - 2, LBM_FLASH, DEFAULT_COLOR);
|
||||
|
||||
if (st == ST_FILE_LIST) {
|
||||
lcdDrawText(56, 244, "[ENT] to select file");
|
||||
lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "[R TRIM] to select file");
|
||||
}
|
||||
else if (st == ST_FLASH_CHECK && opt == FC_OK) {
|
||||
lcdDrawText(56, 244, "Hold [ENT] long to flash");
|
||||
lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Hold [R TRIM] long to flash");
|
||||
}
|
||||
else if (st == ST_FLASHING) {
|
||||
lcdDrawText(56, 244, "Writing Firmware ...");
|
||||
lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Writing Firmware ...");
|
||||
}
|
||||
else if (st == ST_FLASH_DONE) {
|
||||
lcdDrawText(56, 244, "Writing Completed");
|
||||
lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Writing Completed");
|
||||
}
|
||||
}
|
||||
|
||||
if (st != ST_FLASHING) {
|
||||
lcdDrawBitmapPattern(305, 242, LBM_EXIT, DEFAULT_COLOR);
|
||||
lcdDrawText(335, 244, "[RTN] to exit");
|
||||
lcd->drawBitmapPattern(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING - 2, LBM_EXIT, DEFAULT_COLOR);
|
||||
lcd->drawText(DOUBLE_PADDING, LCD_H - DEFAULT_PADDING, "[L TRIM] to exit");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bootloaderDrawFilename(const char* str, uint8_t line, bool selected)
|
||||
{
|
||||
lcdDrawBitmapPattern(94, 76 + (line * 25), LBM_FILE, DEFAULT_COLOR);
|
||||
lcdDrawText(124, 75 + (line * 25), str);
|
||||
lcd->drawBitmapPattern(DEFAULT_PADDING, 76 + (line * 25), LBM_FILE, DEFAULT_COLOR);
|
||||
lcd->drawText(DEFAULT_PADDING + 30, 75 + (line * 25), str);
|
||||
|
||||
if (selected) {
|
||||
lcdDrawSolidRect(119, 72 + (line * 25), 278, 26, 2, LINE_COLOR);
|
||||
lcd->drawSolidRect(DEFAULT_PADDING + 25, 72 + (line * 25), LCD_W - (DEFAULT_PADDING + 25) - 28, 26, 2, LINE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,49 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
//fix it
|
||||
#if defined(EXTMODULE_USART)
|
||||
ModuleFifo extmoduleFifo;
|
||||
#endif
|
||||
bool stopOnTxDone = false;
|
||||
|
||||
void extmoduleSendNextFrame();
|
||||
|
||||
void EXTERNAL_MODULE_ON()
|
||||
{
|
||||
GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
GPIO_ResetBits(EXTMODULE_PWR_FIX_GPIO, EXTMODULE_PWR_FIX_GPIO_PIN);
|
||||
}
|
||||
void EXTERNAL_MODULE_OFF()
|
||||
{
|
||||
GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
GPIO_SetBits(EXTMODULE_PWR_FIX_GPIO, EXTMODULE_PWR_FIX_GPIO_PIN);
|
||||
}
|
||||
void extModuleInit()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
GPIO_Init(EXTMODULE_PWR_GPIO, &GPIO_InitStructure);
|
||||
|
||||
//for additional transistor to ensuring module is completely disabled
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||
//pin must be pulled to V+ (voltage of board - VCC is not enough to fully close transistor)
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_FIX_GPIO_PIN;
|
||||
GPIO_SetBits(EXTMODULE_PWR_FIX_GPIO, EXTMODULE_PWR_FIX_GPIO_PIN);
|
||||
GPIO_Init(EXTMODULE_PWR_FIX_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_INVERT_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_Init(EXTMODULE_TX_INVERT_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(EXTMODULE_TX_INVERT_GPIO, EXTMODULE_TX_INVERT_GPIO_PIN);
|
||||
}
|
||||
|
||||
void extmoduleStop()
|
||||
{
|
||||
@@ -89,27 +132,13 @@ void extmodulePpmStart()
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 45000;
|
||||
#if defined(PCBX10) || PCBREV >= 13
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // PWM mode 1
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE;
|
||||
EXTMODULE_TIMER->EGR = 1; // Reloads register values now
|
||||
EXTMODULE_TIMER->DIER = TIM_DIER_UDE; // Update DMA request
|
||||
EXTMODULE_TIMER->CR1 = TIM_CR1_CEN; // Start timer
|
||||
#elif defined(PCBNV14)
|
||||
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM mode 1
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE;
|
||||
EXTMODULE_TIMER->EGR = 1; // Reloads register values now
|
||||
EXTMODULE_TIMER->DIER = TIM_DIER_UDE; // Update DMA request
|
||||
EXTMODULE_TIMER->CR1 = TIM_CR1_CEN; // Start timer
|
||||
#else
|
||||
EXTMODULE_TIMER->CCR1 = GET_PPM_DELAY(EXTERNAL_MODULE)*2;
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (GET_PPM_POLARITY(EXTERNAL_MODULE) ? TIM_CCER_CC1P : 0);
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Reloads register values now
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Update DMA request
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; // Start timer
|
||||
#endif
|
||||
|
||||
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
@@ -143,28 +172,8 @@ void extmodulePxxStart()
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 18000;
|
||||
|
||||
#if defined(PCBX10) || PCBREV >= 13
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3NE;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR3 = 18;
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
#elif defined(PCBNV14)
|
||||
{
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 18;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
}
|
||||
#else
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC1NE | TIM_CCER_CC1NP; // TIM_CCER_CC1E | TIM_CCER_CC1P;
|
||||
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 18;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
@@ -172,7 +181,6 @@ void extmodulePxxStart()
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
#endif
|
||||
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
@@ -201,16 +209,6 @@ void extmoduleDsm2Start()
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 44000; // 22mS
|
||||
|
||||
#if defined(PCBX10) || PCBREV >= 13
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3P;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR3 = 0;
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
#else
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 0;
|
||||
@@ -219,7 +217,6 @@ void extmoduleDsm2Start()
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
#endif
|
||||
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
|
||||
+113
-30
@@ -97,10 +97,17 @@
|
||||
// ADC
|
||||
#define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_DMA2)
|
||||
#define ADC_RCC_APB2Periph (RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC3)
|
||||
#if !defined(HALL_STICKS)
|
||||
#define ADC_GPIO_PIN_STICK_LH GPIO_Pin_2 // PA.02
|
||||
#define ADC_GPIO_PIN_STICK_LV GPIO_Pin_3 // PA.03
|
||||
#define ADC_GPIO_PIN_STICK_RH GPIO_Pin_4 // PA.04
|
||||
#define ADC_GPIO_PIN_STICK_RV GPIO_Pin_5 // PA.05
|
||||
#else
|
||||
#define ADC_GPIO_PIN_STICK_LH 0
|
||||
#define ADC_GPIO_PIN_STICK_LV 0
|
||||
#define ADC_GPIO_PIN_STICK_RH 0
|
||||
#define ADC_GPIO_PIN_STICK_RV 0
|
||||
#endif
|
||||
#define ADC_GPIO_PIN_POT1 GPIO_Pin_6 // PA.06 VRA
|
||||
#define ADC_GPIO_PIN_POT2 GPIO_Pin_4 // PC.04 VRB
|
||||
#define ADC_GPIO_PIN_SWA GPIO_Pin_1 // PB.01
|
||||
@@ -118,10 +125,12 @@
|
||||
#define ADC_GPIOC_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5)
|
||||
#define ADC_GPIOF_PINS (GPIO_Pin_8 | GPIO_Pin_10)
|
||||
|
||||
#if !defined(HALL_STICKS)
|
||||
#define ADC_CHANNEL_STICK_LH ADC_Channel_2 // ADC123_IN2 -> ADC1_IN2
|
||||
#define ADC_CHANNEL_STICK_LV ADC_Channel_3 // ADC123_IN3 -> ADC1_IN3
|
||||
#define ADC_CHANNEL_STICK_RH ADC_Channel_4 // ADC12_IN4 -> ADC1_IN4
|
||||
#define ADC_CHANNEL_STICK_RV ADC_Channel_5 // ADC12_IN5 -> ADC1_IN5
|
||||
#endif
|
||||
#define ADC_CHANNEL_POT1 ADC_Channel_6 // ADC12_IN6 -> ADC1_IN6
|
||||
#define ADC_CHANNEL_POT2 ADC_Channel_14 // ADC12_IN14 -> ADC1_IN14
|
||||
#define ADC_CHANNEL_SWA ADC_Channel_9 // ADC12_IN9 -> ADC1_IN9
|
||||
@@ -193,6 +202,9 @@
|
||||
#define AUX_SERIAL_RX_INVERT_GPIO GPIOI
|
||||
#define AUX_SERIAL_RX_INVERT_GPIO_PIN GPIO_Pin_15 // PI.15
|
||||
|
||||
//used in BOOTLOADER
|
||||
#define SERIAL_RCC_AHB1Periph 0
|
||||
#define SERIAL_RCC_APB1Periph 0
|
||||
// Telemetry
|
||||
#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_DMA1)
|
||||
#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2
|
||||
@@ -252,6 +264,7 @@
|
||||
// TODO TIM3, TIM8, TIM14, review the channel in backlight_driver.cpp according to the chosen timer
|
||||
#define BACKLIGHT_RCC_AHB1Periph RCC_AHB1Periph_GPIOA
|
||||
#define BACKLIGHT_RCC_APB1Periph RCC_APB1Periph_TIM2
|
||||
#define BACKLIGHT_RCC_APB2Periph 0
|
||||
#define BACKLIGHT_GPIO GPIOA
|
||||
#define BACKLIGHT_GPIO_PIN GPIO_Pin_15
|
||||
#define BACKLIGHT_GPIO_PinSource GPIO_PinSource15
|
||||
@@ -259,9 +272,16 @@
|
||||
#define BACKLIGHT_GPIO_AF GPIO_AF_TIM2
|
||||
#define BACKLIGHT_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
//used in BOOTLOADER
|
||||
#define SERIAL_RCC_AHB1Periph 0
|
||||
#define SERIAL_RCC_APB1Periph 0
|
||||
#define ROTARY_ENCODER_RCC_APB1Periph 0
|
||||
|
||||
// SD card
|
||||
#define SD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
|
||||
#define SD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_DMA2)
|
||||
#define SD_RCC_APB1Periph 0
|
||||
#define SD_PRESENT_GPIO GPIOH
|
||||
#define SD_PRESENT_GPIO_PIN GPIO_Pin_10 // PH.10
|
||||
#define SD_SDIO_DMA_STREAM DMA2_Stream3
|
||||
#define SD_SDIO_DMA_CHANNEL DMA_Channel_4
|
||||
#define SD_SDIO_DMA_FLAG_FEIF DMA_FLAG_FEIF3
|
||||
@@ -324,18 +344,18 @@
|
||||
#define I2C_RCC_AHB1Periph 0
|
||||
#define I2C_RCC_APB1Periph 0
|
||||
|
||||
// Haptic: TIM1_CH2
|
||||
// Haptic: TIM1_CH1
|
||||
#define HAPTIC_PWM
|
||||
#define HAPTIC_RCC_AHB1Periph RCC_AHB1Periph_GPIOA
|
||||
#define HAPTIC_RCC_APB2Periph RCC_APB2ENR_TIM1EN
|
||||
#define HAPTIC_GPIO GPIOA
|
||||
#define HAPTIC_GPIO_PIN GPIO_Pin_9
|
||||
#define HAPTIC_GPIO_PIN GPIO_Pin_8
|
||||
#define HAPTIC_GPIO_TIMER TIM1
|
||||
#define HAPTIC_GPIO_AF GPIO_AF_TIM1
|
||||
#define HAPTIC_GPIO_PinSource GPIO_PinSource9
|
||||
#define HAPTIC_TIMER_OUTPUT_ENABLE TIM_CCER_CC2E
|
||||
#define HAPTIC_TIMER_MODE TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2
|
||||
#define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR2
|
||||
#define HAPTIC_GPIO_PinSource GPIO_PinSource8
|
||||
#define HAPTIC_TIMER_OUTPUT_ENABLE TIM_CCER_CC1E | TIM_CCER_CC1NE;
|
||||
#define HAPTIC_TIMER_MODE TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE
|
||||
#define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR1
|
||||
|
||||
// Internal Module
|
||||
#define HARDWARE_INTERNAL_MODULE
|
||||
@@ -359,42 +379,73 @@
|
||||
#define INTMODULE_TX_DMA_Stream_IRQn DMA1_Stream1_IRQn
|
||||
#define INTMODULE_TX_DMA_Stream_IRQHandler DMA1_Stream1_IRQHandler
|
||||
#define INTMODULE_TX_DMA_FLAG_TC DMA_IT_TCIF1
|
||||
|
||||
//TX new implementation
|
||||
#define INTMODULE_DMA_STREAM DMA1_Stream1
|
||||
#define INTMODULE_DMA_CHANNEL DMA_Channel_5
|
||||
#define INTMODULE_GPIO INTMODULE_TX_GPIO
|
||||
//#define INTMODULE_DMA_STREAM_IRQ INTMODULE_RX_DMA_Stream_IRQHandler
|
||||
#define INTMODULE_DMA_STREAM_IRQ INTMODULE_TX_DMA_Stream_IRQn
|
||||
|
||||
#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_UART7)
|
||||
#define INTMODULE_RCC_APB2Periph (RCC_APB2Periph_TIM1)
|
||||
#define INTMODULE_TIMER TIM1
|
||||
#define INTMODULE_TIMER_IRQn TIM1_CC_IRQn
|
||||
#define INTMODULE_TIMER_IRQHandler TIM1_CC_IRQHandler
|
||||
#define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_UART7 | RCC_APB1Periph_TIM3)
|
||||
|
||||
#define INTMODULE_RCC_APB2Periph 0
|
||||
#define INTMODULE_TIMER TIM3
|
||||
#define INTMODULE_TIMER_IRQn TIM3_IRQn
|
||||
#define INTMODULE_TIMER_IRQHandler TIM3_IRQHandler
|
||||
#define INTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
// External Module
|
||||
#define EXTMODULE
|
||||
#define EXTMODULE_PULSES
|
||||
#define EXTMODULE_PWR_GPIO GPIOD
|
||||
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_11
|
||||
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2)
|
||||
#define EXTMODULE_PWR_FIX_GPIO GPIOA
|
||||
#define EXTMODULE_PWR_FIX_GPIO_PIN GPIO_Pin_2 // PA.02
|
||||
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_DMA2)
|
||||
#define EXTMODULE_RCC_APB1Periph 0
|
||||
#define EXTMODULE_RCC_APB2Periph RCC_APB2Periph_TIM8
|
||||
#define EXTMODULE_RCC_APB2Periph (RCC_APB2Periph_TIM8 | RCC_APB2Periph_USART6)
|
||||
#define EXTMODULE_TX_GPIO GPIOC
|
||||
#define EXTMODULE_TX_GPIO_PIN GPIO_Pin_6 // PC.06
|
||||
#define EXTMODULE_TX_GPIO_PinSource GPIO_PinSource6
|
||||
#define EXTMODULE_TX_GPIO_AF GPIO_AF_TIM8
|
||||
#define EXTMODULE_TX_GPIO_AF_USART GPIO_AF_USART6
|
||||
#define EXTMODULE_RX_GPIO GPIOC
|
||||
#define EXTMODULE_RX_GPIO_PIN GPIO_Pin_7 // PC.07
|
||||
#define EXTMODULE_RX_GPIO_PinSource GPIO_PinSource7
|
||||
#define EXTMODULE_RX_GPIO_AF_USART GPIO_AF_USART6
|
||||
#define EXTMODULE_TIMER TIM8
|
||||
#define EXTMODULE_TIMER_IRQn TIM8_CC_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM8_CC_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
//USART
|
||||
#define EXTMODULE_USART_TX_DMA_CHANNEL DMA_Channel_5
|
||||
#define EXTMODULE_USART_TX_DMA_STREAM DMA2_Stream7
|
||||
#define EXTMODULE_USART_TX_DMA_IRQn DMA2_Stream7_IRQn
|
||||
#define EXTMODULE_USART_TX_DMA_IRQHandler DMA2_Stream7_IRQHandler
|
||||
#define EXTMODULE_USART_TX_DMA_FLAG_TC DMA_IT_TCIF7
|
||||
|
||||
#define EXTMODULE_USART_RX_DMA_CHANNEL DMA_Channel_5
|
||||
#define EXTMODULE_USART_RX_DMA_STREAM DMA2_Stream2
|
||||
#define EXTMODULE_USART_RX_DMA_IRQn DMA2_Stream5_IRQn
|
||||
#define EXTMODULE_USART_RX_DMA_IRQHandler DMA2_Stream5_IRQHandler
|
||||
#define EXTMODULE_USART_RX_DMA_FLAG_TC DMA_IT_TCIF5
|
||||
|
||||
#define EXTMODULE_USART_IRQHandler USART6_IRQHandler
|
||||
#define EXTMODULE_USART_IRQn USART6_IRQn
|
||||
|
||||
//TIMER
|
||||
#define EXTMODULE_DMA_CHANNEL DMA_Channel_7
|
||||
#define EXTMODULE_DMA_STREAM DMA2_Stream1
|
||||
#define EXTMODULE_DMA_IRQn DMA2_Stream1_IRQn
|
||||
#define EXTMODULE_DMA_IRQHandler DMA2_Stream1_IRQHandler
|
||||
#define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF1
|
||||
//#define EXTMODULE_USART USART6 // TODO
|
||||
#define EXTMODULE_USART USART6
|
||||
|
||||
#define EXTMODULE_TX_INVERT_GPIO GPIOE
|
||||
#define EXTMODULE_TX_INVERT_GPIO_PIN GPIO_Pin_3 // PE.03
|
||||
#define EXTMODULE_RX_INVERT_GPIO GPIOI
|
||||
#define EXTMODULE_RX_INVERT_GPIO_PIN GPIO_Pin_15 // PI.15
|
||||
|
||||
|
||||
// Heartbeat (not used)
|
||||
#define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
|
||||
@@ -410,20 +461,52 @@
|
||||
#define TRAINER_IN_GPIO_PinSource GPIO_PinSource12
|
||||
#define TRAINER_OUT_GPIO_PIN GPIO_Pin_13 // PD.13
|
||||
#define TRAINER_OUT_GPIO_PinSource GPIO_PinSource13
|
||||
// #define TRAINER_DETECT_GPIO GPIOB
|
||||
// #define TRAINER_DETECT_GPIO_PIN GPIO_Pin_4 // PB.04
|
||||
|
||||
#define TRAINER_TIMER TIM4
|
||||
#define TRAINER_TIMER_IRQn TIM4_IRQn
|
||||
#define TRAINER_GPIO_AF GPIO_AF_TIM4 // TIM4_CH1 (in) + TIM4_CH2 (out)
|
||||
#define TRAINER_OUT_DMA DMA1
|
||||
// #define TRAINER_OUT_DMA_CHANNEL DMA_Channel_2
|
||||
// #define TRAINER_OUT_DMA_STREAM DMA1_Stream3
|
||||
// #define TRAINER_OUT_DMA_IRQn DMA1_Stream3_IRQn
|
||||
// #define TRAINER_OUT_DMA_IRQHandler DMA1_Stream3_IRQHandler
|
||||
// #define TRAINER_OUT_DMA_FLAG_TC DMA_IT_TCIF3
|
||||
#define TRAINER_EXTMODULE_TIMER_IRQn TIM4_IRQn
|
||||
#define TRAINER_EXTMODULE_TIMER_IRQHandler TIM4_IRQHandler
|
||||
#define TRAINER_EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
#define TRAINER_TIMER_IRQn TIM4_IRQn
|
||||
#define TRAINER_TIMER_IRQHandler TIM4_IRQHandler
|
||||
#define TRAINER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
#define TRAINER_OUT_CCMR1 TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE;
|
||||
#define TRAINER_IN_CCMR1 TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_CC1S_0;
|
||||
|
||||
#define TRAINER_OUT_COUNTER_REGISTER TRAINER_TIMER->CCR2
|
||||
#define TRAINER_IN_COUNTER_REGISTER TRAINER_TIMER->CCR1
|
||||
#define TRAINER_SETUP_REGISTER TRAINER_TIMER->CCR3
|
||||
#define TRAINER_OUT_INTERRUPT_FLAG TIM_SR_CC1IF
|
||||
#define TRAINER_OUT_INTERRUPT_ENABLE TIM_DIER_CC1IE
|
||||
#define TRAINER_IN_INTERRUPT_ENABLE TIM_DIER_CC1IE
|
||||
#define TRAINER_IN_INTERRUPT_FLAG TIM_SR_CC1IF
|
||||
#define TRAINER_OUT_CCER TIM_CCER_CC2E
|
||||
#define TRAINER_CCER_POLARYTY TIM_CCER_CC2P
|
||||
#define TRAINER_IN_CCER TIM_CCER_CC1E
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#define TRAINER_MODULE_SBUS_GPIO EXTMODULE_USART_GPIO
|
||||
#define TRAINER_MODULE_SBUS_GPIO_PIN EXTMODULE_RX_GPIO_PIN
|
||||
#define TRAINER_MODULE_SBUS_GPIO_AF EXTMODULE_USART_GPIO_AF
|
||||
#define TRAINER_MODULE_SBUS_USART EXTMODULE_USART
|
||||
#define TRAINER_MODULE_SBUS_GPIO_PinSource EXTMODULE_RX_GPIO_PinSource
|
||||
#define TRAINER_MODULE_SBUS_DMA_STREAM EXTMODULE_DMA_STREAM
|
||||
#define TRAINER_MODULE_SBUS_DMA_CHANNEL EXTMODULE_DMA_CHANNEL
|
||||
*/
|
||||
/*
|
||||
#define TRAINER_MODULE_CPPM_GPIO EXTMODULE_USART_GPIO
|
||||
#define TRAINER_MODULE_CPPM_GPIO_PIN EXTMODULE_RX_GPIO_PIN
|
||||
#define TRAINER_MODULE_CPPM_GPIO_PinSource EXTMODULE_RX_GPIO_PinSource
|
||||
#define TRAINER_MODULE_CPPM_GPIO_AF GPIO_AF_TIM3
|
||||
#define TRAINER_MODULE_CPPM_TIMER TIM3
|
||||
#define TRAINER_MODULE_CPPM_COUNTER_REGISTER TRAINER_MODULE_CPPM_TIMER->CCR2
|
||||
#define TRAINER_MODULE_CPPM_INTERRUPT_ENABLE TIM_DIER_CC2IE
|
||||
#define TRAINER_MODULE_CPPM_INTERRUPT_FLAG TIM_SR_CC2IF
|
||||
#define TRAINER_MODULE_CPPM_CCMR1 (TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_CC2S_0)
|
||||
#define TRAINER_MODULE_CPPM_CCER TIM_CCER_CC2E
|
||||
#define TRAINER_MODULE_CPPM_TIMER_IRQn TIM3_IRQn
|
||||
#define TRAINER_MODULE_CPPM_TIMER_IRQHandler TIM3_IRQHandler
|
||||
*/
|
||||
|
||||
// Xms Interrupt
|
||||
#define INTERRUPT_xMS_RCC_APB1Periph RCC_APB1Periph_TIM14
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "pulses/flysky.h"
|
||||
|
||||
DMAFifo<HALLSTICK_BUFF_SIZE> hallDMAFifo __DMA (HALL_DMA_Stream_RX);
|
||||
Fifo<uint8_t, HALLSTICK_BUFF_SIZE> hallStickTxFifo;
|
||||
@@ -27,9 +28,9 @@ unsigned char HallCmd[264] __DMA;
|
||||
|
||||
STRUCT_HALL HallProtocol = { 0 };
|
||||
STRUCT_HALL HallProtocolTx = { 0 };
|
||||
STRUCT_HALL_CHANNEL Channel;
|
||||
STRUCT_STICK_CALIBRATION StickCallbration[4] = { {0, 0, 0} };
|
||||
unsigned short HallChVal[4];
|
||||
signed short hall_raw_values[FLYSKY_HALL_CHANNEL_COUNT];
|
||||
STRUCT_STICK_CALIBRATION hall_calibration[FLYSKY_HALL_CHANNEL_COUNT] = { {0, 0, 0} };
|
||||
unsigned short hall_adc_values[FLYSKY_HALL_CHANNEL_COUNT];
|
||||
|
||||
/* crc16 implementation according to CCITT standards */
|
||||
const unsigned short CRC16Table[256]= {
|
||||
@@ -92,14 +93,14 @@ uint16_t get_hall_adc_value(uint8_t ch)
|
||||
#if defined(FLYSKY_HALL_STICKS_REVERSE)
|
||||
ch = sticks_mapping[ch];
|
||||
|
||||
return MAX_ADC_CHANNEL_VALUE - HallChVal[ch];
|
||||
return MAX_ADC_CHANNEL_VALUE - hall_adc_values[ch];
|
||||
#else
|
||||
if (ch < 2)
|
||||
{
|
||||
return MAX_ADC_CHANNEL_VALUE - HallChVal[ch];
|
||||
return MAX_ADC_CHANNEL_VALUE - hall_adc_values[ch];
|
||||
}
|
||||
|
||||
return HallChVal[ch];
|
||||
return hall_adc_values[ch];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -175,11 +176,10 @@ void hall_stick_init(uint32_t baudrate)
|
||||
|
||||
void HallSendBuffer(uint8_t * buffer, uint32_t count)
|
||||
{
|
||||
for(int idx = 0; buffer != HallCmd && idx < count; idx++)
|
||||
for(uint32_t idx = 0; buffer != HallCmd && idx < count; idx++)
|
||||
{
|
||||
HallCmd[idx] = buffer[idx];
|
||||
}
|
||||
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
DMA_DeInit(HALL_DMA_Stream_TX);
|
||||
DMA_InitStructure.DMA_Channel = HALL_DMA_Channel;
|
||||
@@ -228,7 +228,7 @@ void reset_hall_stick( void )
|
||||
{
|
||||
unsigned short crc16 = 0xffff;
|
||||
|
||||
HallCmd[0] = 0x55;
|
||||
HallCmd[0] = HALL_PROTOLO_HEAD;
|
||||
HallCmd[1] = 0xD1;
|
||||
HallCmd[2] = 0x01;
|
||||
HallCmd[3] = 0x01;
|
||||
@@ -245,7 +245,7 @@ void get_hall_config( void )
|
||||
{
|
||||
unsigned short crc16 = 0xffff;
|
||||
|
||||
HallCmd[0] = 0x55;
|
||||
HallCmd[0] = HALL_PROTOLO_HEAD;
|
||||
HallCmd[1] = 0xD1;
|
||||
HallCmd[2] = 0x01;
|
||||
HallCmd[3] = 0x00;
|
||||
@@ -262,7 +262,7 @@ void get_hall_firmware_info()
|
||||
{
|
||||
unsigned short crc16 = 0xffff;
|
||||
|
||||
HallCmd[0] = 0x55;
|
||||
HallCmd[0] = HALL_PROTOLO_HEAD;
|
||||
HallCmd[1] = 0xA2;
|
||||
HallCmd[2] = 0x00;
|
||||
|
||||
@@ -278,7 +278,7 @@ void hallStickUpdatefwEnd( void )
|
||||
{
|
||||
unsigned short crc16 = 0xffff;
|
||||
|
||||
HallCmd[0] = 0x55;
|
||||
HallCmd[0] = HALL_PROTOLO_HEAD;
|
||||
HallCmd[1] = 0xA2;
|
||||
HallCmd[2] = 0x01;
|
||||
HallCmd[3] = 0x07;
|
||||
@@ -380,36 +380,36 @@ exit: parse_ps_state = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
#define ERROR_OFFSET 10
|
||||
void convert_hall_to_adcVaule( void )
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
for ( uint8_t i = 0; i < 4; i++ )
|
||||
for ( uint8_t channel = 0; channel < 4; channel++ )
|
||||
{
|
||||
if (Channel.channel[i] < StickCallbration[i].mid)
|
||||
if (hall_raw_values[channel] < hall_calibration[channel].mid)
|
||||
{
|
||||
value = StickCallbration[i].mid - StickCallbration[i].min;
|
||||
value = ( MIDDLE_ADC_CHANNLE_VALUE * (StickCallbration[i].mid - Channel.channel[i] ) ) / ( value );
|
||||
value = hall_calibration[channel].mid - (hall_calibration[channel].min+ERROR_OFFSET);
|
||||
value = ( MIDDLE_ADC_CHANNLE_VALUE * (hall_calibration[channel].mid - hall_raw_values[channel] ) ) / ( value );
|
||||
|
||||
if (value >= MIDDLE_ADC_CHANNLE_VALUE ) {
|
||||
value = MIDDLE_ADC_CHANNLE_VALUE;
|
||||
}
|
||||
|
||||
HallChVal[i] = MIDDLE_ADC_CHANNLE_VALUE - value;
|
||||
hall_adc_values[channel] = MIDDLE_ADC_CHANNLE_VALUE - value;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = StickCallbration[i].max - StickCallbration[i].mid;
|
||||
value = (hall_calibration[channel].max - ERROR_OFFSET) - hall_calibration[channel].mid;
|
||||
|
||||
value = ( MIDDLE_ADC_CHANNLE_VALUE * (Channel.channel[i] - StickCallbration[i].mid ) ) / (value );
|
||||
value = ( MIDDLE_ADC_CHANNLE_VALUE * (hall_raw_values[channel] - hall_calibration[channel].mid ) ) / (value );
|
||||
|
||||
if (value >= MIDDLE_ADC_CHANNLE_VALUE )
|
||||
{
|
||||
value = MIDDLE_ADC_CHANNLE_VALUE;
|
||||
}
|
||||
|
||||
HallChVal[i] = MIDDLE_ADC_CHANNLE_VALUE + value + 1;
|
||||
hall_adc_values[channel] = MIDDLE_ADC_CHANNLE_VALUE + value + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -494,7 +494,7 @@ void hallStick_GetTxDataFromUSB( void )
|
||||
break;
|
||||
|
||||
case TRANSFER_DIR_HALLSTICK:
|
||||
// onFlySkyUsbDownloadStart(TRANSFER_DIR_HALLSTICK);
|
||||
onFlySkyUsbDownloadStart(TRANSFER_DIR_HALLSTICK);
|
||||
|
||||
if ( 0xA2 == HallProtocolTx.hallID.ID )
|
||||
{
|
||||
@@ -513,17 +513,23 @@ void hallStick_GetTxDataFromUSB( void )
|
||||
break;
|
||||
|
||||
case TRANSFER_DIR_RFMODULE:
|
||||
// onFlySkyUsbDownloadStart(TRANSFER_DIR_RFMODULE);
|
||||
onFlySkyUsbDownloadStart(TRANSFER_DIR_RFMODULE);
|
||||
|
||||
if ( 0xAE == HallProtocolTx.hallID.ID && HallProtocolTx.length == 0 )
|
||||
{ // 55 AE 00 D3 47
|
||||
// onIntmoduleUsbDownloadStart(INTERNAL_MODULE);
|
||||
{
|
||||
setFlyskyState(INTERNAL_MODULE, FLYSKY_MODULE_STATE_UPDATE_RF_FIRMWARE);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( 0x0D == HallProtocolTx.hallID.hall_Id.packetID && HallProtocolTx.data[0] == 1 )
|
||||
{
|
||||
onFlySkyGetVersionInfoStart(INTERNAL_MODULE, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
//if ( isFlySkyUsbDownload() )
|
||||
{
|
||||
// intmoduleSendBufferDMA( pt, HallProtocolTx.length + 3 + 2 );
|
||||
intmoduleSendBuffer( pt, HallProtocolTx.length + 3 + 2 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -532,7 +538,7 @@ void hallStick_GetTxDataFromUSB( void )
|
||||
|
||||
if ( !usbPlugged() )
|
||||
{
|
||||
// onFlySkyUsbDownloadStart(0);
|
||||
onFlySkyUsbDownloadStart(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,19 +546,24 @@ void hallStick_GetTxDataFromUSB( void )
|
||||
/* Run it in 1ms timer routine */
|
||||
void hall_stick_loop(void)
|
||||
{
|
||||
unsigned char ch;
|
||||
static unsigned int getCfgTime = get_tmr10ms();
|
||||
uint32_t printf_log_now = 0;
|
||||
static uint8_t count = 0;
|
||||
static tmr10ms_t lastConfigTime = get_tmr10ms();
|
||||
bool log = 0;
|
||||
|
||||
hallStick_GetTxDataFromUSB();
|
||||
|
||||
hallstick_send_by_state();
|
||||
|
||||
while( HallGetByte(&ch) )
|
||||
if(count>10)
|
||||
{
|
||||
count = 0;
|
||||
hallstick_send_by_state();
|
||||
}
|
||||
count++;
|
||||
uint8_t byte;
|
||||
while(HallGetByte(&byte))
|
||||
{
|
||||
HallProtocol.index++;
|
||||
|
||||
Parse_Character(&HallProtocol, ch );
|
||||
Parse_Character(&HallProtocol, byte);
|
||||
|
||||
if ( HallProtocol.msg_OK )
|
||||
{
|
||||
@@ -562,46 +573,42 @@ void hall_stick_loop(void)
|
||||
switch ( HallProtocol.hallID.hall_Id.receiverID )
|
||||
{
|
||||
case TRANSFER_DIR_TXMCU:
|
||||
if ( 0x0e == HallProtocol.hallID.hall_Id.packetID )
|
||||
{
|
||||
memcpy(&StickCallbration, HallProtocol.data, sizeof(StickCallbration));
|
||||
if(HallProtocol.hallID.hall_Id.packetID == HALL_RESP_TYPE_CALIB) {
|
||||
memcpy(&hall_calibration, HallProtocol.data, sizeof(hall_calibration));
|
||||
}
|
||||
else if(HallProtocol.hallID.hall_Id.packetID == HALL_RESP_TYPE_VALUES) {
|
||||
memcpy(hall_raw_values, HallProtocol.data, sizeof(hall_raw_values));
|
||||
convert_hall_to_adcVaule();
|
||||
}
|
||||
else if ( 0x0c == HallProtocol.hallID.hall_Id.packetID )
|
||||
{
|
||||
memcpy(&Channel, HallProtocol.data, sizeof(Channel));
|
||||
|
||||
convert_hall_to_adcVaule();
|
||||
}
|
||||
break;
|
||||
|
||||
case TRANSFER_DIR_HOSTPC:
|
||||
if ( 0x01 == HallProtocol.length &&
|
||||
( 0x05 == HallProtocol.data[0] || 0x06 == HallProtocol.data[0]) )
|
||||
if (HallProtocol.length == 0x01 && (HallProtocol.data[0] == 0x05 || HallProtocol.data[0] == 0x06) )
|
||||
{
|
||||
hallStickSendState = HALLSTICK_SEND_STATE_IDLE;
|
||||
}
|
||||
case TRANSFER_DIR_HALLSTICK:
|
||||
HallProtocolCount++;
|
||||
uint8_t *pt = (uint8_t*)&HallProtocol;
|
||||
//HallProtocol.head = HALL_PROTOLO_HEAD;
|
||||
//TRACE("HALL: %02X %02X %02X ...%04X", pt[0], pt[1], pt[2], HallProtocol.checkSum);
|
||||
pt[HallProtocol.length + 3] = HallProtocol.checkSum & 0xFF;
|
||||
pt[HallProtocol.length + 4] = HallProtocol.checkSum >> 8;
|
||||
// usbDownloadTransmit( pt, HallProtocol.length + 5 );
|
||||
usbDownloadTransmit( pt, HallProtocol.length + 5 );
|
||||
break;
|
||||
}
|
||||
//printf_log_now = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((get_tmr10ms() - getCfgTime) > 200)
|
||||
//check periodically if calibration is correct
|
||||
if (get_tmr10ms() - lastConfigTime > 200)
|
||||
{
|
||||
if ( (0 == StickCallbration[0].max) && (0 == StickCallbration[0].mid) && (0== StickCallbration[0].min) )
|
||||
{
|
||||
get_hall_config();
|
||||
getCfgTime = get_tmr10ms();
|
||||
//invalid calibration
|
||||
if(hall_calibration[0].max - hall_calibration[0].min < 1024) {
|
||||
TRACE("GET HALL CONFIG");
|
||||
get_hall_config();
|
||||
lastConfigTime = get_tmr10ms();
|
||||
}
|
||||
|
||||
if ( printf_log_now != 0)
|
||||
if (log)
|
||||
{
|
||||
TRACE_NOCRLF("Hall(%0d):", FLYSKY_HALL_BAUDRATE);
|
||||
for (int idx = 0; idx < HallProtocol.length + 5; idx++)
|
||||
|
||||
@@ -46,10 +46,6 @@
|
||||
#define MIN_ADC_CHANNLE_VALUE ( 0 )
|
||||
#define MIDDLE_ADC_CHANNLE_VALUE ( 2047 )
|
||||
|
||||
|
||||
|
||||
extern unsigned short HallChVal[FLYSKY_HALL_CHANNEL_COUNT];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
signed short min;
|
||||
@@ -62,25 +58,20 @@ typedef struct
|
||||
STRUCT_STICK_CALIBRATION sticksCalibration[4];
|
||||
unsigned char reststate;
|
||||
unsigned short CRC16;
|
||||
}STRUCT_STICK_CALIBRATION_PACK;
|
||||
} STRUCT_STICK_CALIBRATION_PACK;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
signed short channel[4];
|
||||
}STRUCT_HALL_CHANNEL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
STRUCT_HALL_CHANNEL channel;
|
||||
unsigned char stickState;
|
||||
unsigned short CRC16;
|
||||
}STRUCT_CHANNEL_PACK;
|
||||
} STRUCT_CHANNEL_PACK;
|
||||
|
||||
typedef union
|
||||
{
|
||||
STRUCT_STICK_CALIBRATION_PACK channelPack;
|
||||
STRUCT_CHANNEL_PACK sticksCalibrationPack;
|
||||
}UNION_DATA;
|
||||
} UNION_DATA;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -103,14 +94,14 @@ typedef union
|
||||
{
|
||||
STRUCT_HALLID hall_Id;
|
||||
unsigned char ID;
|
||||
}STRUCT_ID;
|
||||
} STRUCT_ID;
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
STRUCT_HALLDATA halldat;
|
||||
unsigned char buffer[30];
|
||||
}UNION_HALLDATA;
|
||||
} UNION_HALLDATA;
|
||||
|
||||
|
||||
typedef struct
|
||||
@@ -159,7 +150,9 @@ enum TRANSFER_DIR_E {
|
||||
TRANSFER_DIR_RFMODULE,
|
||||
};
|
||||
|
||||
#define HALL_PROTOLO_HEAD ( 0x55 )
|
||||
#define HALL_PROTOLO_HEAD 0x55
|
||||
#define HALL_RESP_TYPE_CALIB 0x0e
|
||||
#define HALL_RESP_TYPE_VALUES 0x0c
|
||||
|
||||
#define HALL_SERIAL_USART UART4
|
||||
#define HALL_SERIAL_GPIO GPIOA
|
||||
@@ -192,6 +185,11 @@ enum TRANSFER_DIR_E {
|
||||
/***************************************************************************************************
|
||||
interface function
|
||||
***************************************************************************************************/
|
||||
extern unsigned short hall_adc_values[FLYSKY_HALL_CHANNEL_COUNT];
|
||||
extern signed short hall_raw_values[FLYSKY_HALL_CHANNEL_COUNT];
|
||||
extern STRUCT_STICK_CALIBRATION hall_calibration[FLYSKY_HALL_CHANNEL_COUNT];
|
||||
|
||||
|
||||
extern void reset_hall_stick( void );
|
||||
extern void get_hall_config( void );
|
||||
extern void hall_stick_init(uint32_t baudrate);
|
||||
|
||||
@@ -49,11 +49,10 @@ void hapticInit(void)
|
||||
HAPTIC_GPIO_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 10000 - 1;
|
||||
HAPTIC_GPIO_TIMER->CCMR1 = HAPTIC_TIMER_MODE; // PWM
|
||||
HAPTIC_GPIO_TIMER->CCER = HAPTIC_TIMER_OUTPUT_ENABLE;
|
||||
|
||||
hapticOff();
|
||||
|
||||
HAPTIC_GPIO_TIMER->EGR = 0;
|
||||
HAPTIC_GPIO_TIMER->CCR1 = 0;
|
||||
HAPTIC_GPIO_TIMER->EGR = TIM_EGR_UG;
|
||||
HAPTIC_GPIO_TIMER->CR1 = TIM_CR1_CEN; // counter enable
|
||||
HAPTIC_GPIO_TIMER->BDTR |= TIM_BDTR_MOE;
|
||||
}
|
||||
|
||||
void hapticDone(void)
|
||||
|
||||
@@ -22,31 +22,67 @@
|
||||
|
||||
uint32_t readKeys()
|
||||
{
|
||||
return 0;
|
||||
uint32_t result = 0;
|
||||
bool getKeys = true;
|
||||
#if defined(LUA)
|
||||
getKeys = (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT);
|
||||
#endif
|
||||
if (getKeys) {
|
||||
if (TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL)
|
||||
result |= 1 << KEY_PGDN;
|
||||
if (TRIMS_GPIO_REG_LHR & TRIMS_GPIO_PIN_LHR)
|
||||
result |= 1 << KEY_PGUP;
|
||||
if (TRIMS_GPIO_REG_LVD & TRIMS_GPIO_PIN_LVD)
|
||||
result |= 1 << KEY_TELEM;
|
||||
if (TRIMS_GPIO_REG_LVU & TRIMS_GPIO_PIN_LVU)
|
||||
result |= 1 << KEY_MENU;
|
||||
if (TRIMS_GPIO_REG_RVD & TRIMS_GPIO_PIN_RVD)
|
||||
result |= 1 << KEY_DOWN;
|
||||
if (TRIMS_GPIO_REG_RVU & TRIMS_GPIO_PIN_RVU)
|
||||
result |= 1 << KEY_UP;
|
||||
if (TRIMS_GPIO_REG_RHL & TRIMS_GPIO_PIN_RHL)
|
||||
result |= 1 << KEY_LEFT;
|
||||
if (TRIMS_GPIO_REG_RHR & TRIMS_GPIO_PIN_RHR)
|
||||
result |= 1 << KEY_RIGHT;
|
||||
if (TRIMS_GPIO_REG_RPRESS & TRIMS_GPIO_PIN_RPRESS)
|
||||
result |= 1 << KEY_ENTER;
|
||||
if (TRIMS_GPIO_REG_LPRESS & TRIMS_GPIO_PIN_LPRESS)
|
||||
result |= 1 << KEY_EXIT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t readTrims()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
bool getTrim = true;
|
||||
#if defined(LUA)
|
||||
if(luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) {
|
||||
getTrim = false;
|
||||
}
|
||||
#endif
|
||||
if(!getTrim) return result;
|
||||
if (TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL)
|
||||
result |= 0x01;
|
||||
result |= 1 << (TRM_LH_DWN - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_LHR & TRIMS_GPIO_PIN_LHR)
|
||||
result |= 0x02;
|
||||
result |= 1 << (TRM_LH_UP - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_LVD & TRIMS_GPIO_PIN_LVD)
|
||||
result |= 0x04;
|
||||
result |= 1 << (TRM_LV_DWN - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_LVU & TRIMS_GPIO_PIN_LVU)
|
||||
result |= 0x08;
|
||||
result |= 1 << (TRM_LV_UP - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_RVD & TRIMS_GPIO_PIN_RVD)
|
||||
result |= 0x10;
|
||||
result |= 1 << (TRM_RV_DWN - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_RVU & TRIMS_GPIO_PIN_RVU)
|
||||
result |= 0x20;
|
||||
result |= 1 << (TRM_RV_UP - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_RHL & TRIMS_GPIO_PIN_RHL)
|
||||
result |= 0x40;
|
||||
result |= 1 << (TRM_RH_DWN - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_RHR & TRIMS_GPIO_PIN_RHR)
|
||||
result |= 0x80;
|
||||
|
||||
// TRACE("readTrims(): result=0x%02x", result);
|
||||
result |= 1 << (TRM_RH_UP - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_RPRESS & TRIMS_GPIO_PIN_RPRESS)
|
||||
result |= 1 << (TRM_RIGHT_CLICK - TRM_BASE);
|
||||
if (TRIMS_GPIO_REG_LPRESS & TRIMS_GPIO_PIN_LPRESS)
|
||||
result |= 1 << (TRM_LEFT_CLICK - TRM_BASE);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -68,13 +104,13 @@ void readKeysAndTrims()
|
||||
|
||||
uint8_t index = 0;
|
||||
uint32_t in = readKeys();
|
||||
uint32_t trims = readTrims();
|
||||
for (i = 0; i < TRM_BASE; i++) {
|
||||
keys[index++].input(in & (1 << i));
|
||||
}
|
||||
|
||||
in = readTrims();
|
||||
for (i = 1; i <= 1 << (TRM_LAST-TRM_BASE); i <<= 1) {
|
||||
keys[index++].input(in & i);
|
||||
keys[index++].input(trims & i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -87,12 +87,9 @@ typedef unsigned int LcdReadIDFucPtr( void );
|
||||
|
||||
extern void GPIO_SetDirection( GPIO_TypeDef *GPIOx, unsigned char Pin, unsigned char IsInput );
|
||||
|
||||
extern void LCD_HX8357D_On( void );
|
||||
extern void LCD_ILI9481_On( void );
|
||||
extern void LCD_ILI9486_On( void );
|
||||
extern void LCD_ILI9488_On( void );
|
||||
extern void LCD_ST7796S_On( void );
|
||||
|
||||
extern lcdSpiInitFucPtr lcdInitFunction;
|
||||
extern lcdSpiInitFucPtr lcdOffFunction;
|
||||
extern lcdSpiInitFucPtr lcdOnFunction;
|
||||
|
||||
#define SET_IO_INPUT( PORT, PIN ) GPIO_SetDirection( PORT, PIN, 1 )
|
||||
#define SET_IO_OUTPUT( PORT, PIN ) GPIO_SetDirection( PORT, PIN, 0 )
|
||||
|
||||
@@ -124,6 +124,8 @@ enum LcdColorIndex
|
||||
BARGRAPH2_COLOR_INDEX,
|
||||
BARGRAPH_BGCOLOR_INDEX,
|
||||
SCROLLBOX_COLOR_INDEX,
|
||||
BATTERY_CHARGE_COLOR_INDEX,
|
||||
|
||||
LCD_COLOR_COUNT,
|
||||
|
||||
TABLE_HEADER_BGCOLOR_INDEX,
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
#include "pwr.h"
|
||||
#include "board.h"
|
||||
|
||||
uint32_t shutdownRequest; // Stores intentional shutdown to avoid reboot loop
|
||||
uint32_t shutdownReason; // Used for detecting unexpected reboots regardless of reason
|
||||
uint32_t powerupReason __NOINIT; // Stores power up reason beyond initialization for emergency mode activation
|
||||
uint32_t boardState __NOINIT;
|
||||
|
||||
void pwrInit()
|
||||
{
|
||||
@@ -41,11 +40,6 @@ void pwrInit()
|
||||
//GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_GPIO_PIN;
|
||||
//GPIO_Init(INTMODULE_PWR_GPIO, &GPIO_InitStructure);
|
||||
|
||||
//TODO move this elsewhere!
|
||||
GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_GPIO_PIN;
|
||||
GPIO_Init(EXTMODULE_PWR_GPIO, &GPIO_InitStructure);
|
||||
|
||||
//Bluetooth
|
||||
GPIO_SetBits(BLUETOOTH_ON_GPIO, BLUETOOTH_ON_GPIO_PIN);
|
||||
GPIO_InitStructure.GPIO_Pin = BLUETOOTH_ON_GPIO_PIN;
|
||||
@@ -55,38 +49,35 @@ void pwrInit()
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_Pin = PWR_SWITCH_GPIO_PIN;
|
||||
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// Init SD-DETECT PIN
|
||||
GPIO_ResetBits(SD_PRESENT_GPIO, SD_PRESENT_GPIO_PIN);
|
||||
GPIO_InitStructure.GPIO_Pin = SD_PRESENT_GPIO_PIN;
|
||||
GPIO_Init(SD_PRESENT_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// TODO move this elsewhere! (plus SD DETECT on other boards)
|
||||
// Init TRAINER DETECT PIN
|
||||
// GPIO_InitStructure.GPIO_Pin = TRAINER_DETECT_GPIO_PIN;
|
||||
// GPIO_Init(TRAINER_DETECT_GPIO, &GPIO_InitStructure);
|
||||
//turn power off
|
||||
GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
||||
//turn Bluetooth off
|
||||
GPIO_ResetBits(PWR_GPIO, BLUETOOTH_ON_GPIO_PIN);
|
||||
|
||||
pwrOn();
|
||||
boardState = BOARD_POWER_OFF;
|
||||
}
|
||||
|
||||
void pwrOn()
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = PWR_ON_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(PWR_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
||||
|
||||
shutdownRequest = NO_SHUTDOWN_REQUEST;
|
||||
shutdownReason = DIRTY_SHUTDOWN;
|
||||
boardState = BOARD_POWER_ON;
|
||||
}
|
||||
|
||||
void pwrSoftReboot(){
|
||||
boardState = BOARD_REBOOT;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
void pwrOff()
|
||||
{
|
||||
// Shutdown the Haptic
|
||||
hapticDone();
|
||||
|
||||
shutdownRequest = SHUTDOWN_REQUEST;
|
||||
shutdownReason = NORMAL_POWER_OFF;
|
||||
boardState = BOARD_POWER_OFF;
|
||||
GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN);
|
||||
}
|
||||
|
||||
@@ -97,36 +88,11 @@ bool pwrPressed()
|
||||
|
||||
void pwrResetHandler()
|
||||
{
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOJEN;
|
||||
|
||||
// these two NOPs are needed (see STM32F errata sheet) before the peripheral
|
||||
// register can be written after the peripheral clock was enabled
|
||||
__ASM volatile ("nop");
|
||||
__ASM volatile ("nop");
|
||||
|
||||
// We get here whether we are powering up normally, we had an unexpected reboot or we have just powered down normally.
|
||||
// We want:
|
||||
// - In the 2nd case, to power ON as soon as possible if an unexpected reboot happened
|
||||
// (we get there running on remaining capacitor charge, soft power having been cut by the RESET).
|
||||
// - In the 3rd case, NOT power on as that would prevent from turning the system off.
|
||||
// - The 1st case does not need to be handled here, but will be as a result of the handling for the 3rd case, see below.
|
||||
//
|
||||
// shutdownRequest is used to handle the 3rd case. If we really powered down on purpose this will still be set to SHUTDOWN_REQUEST
|
||||
// as we left it in pwrOff(). If however we had an unexpected reboot, it would be set to NO_SHUTDOWN_REQUEST as we set it in pwrOn().
|
||||
// Any other value (e.g. resulting from data corruption) would also keep power on for safety, so this variable can NOT be used
|
||||
// to detect an unexpected reboot (on a normal power on the contents of the variable are random).
|
||||
//
|
||||
// shutdownReason is used to differentiate between an unexpected reboot and a normal power on. We set it to DIRTY_SHUTDOWN in pwrOn()
|
||||
// in anticipation of a potential reboot. Should there be one the value should be preserved and signal below that we rebooted unexpectedly.
|
||||
// If it is NOT set to DIRTY_SHUTDOWN we likely had a normal boot and its contents are random. Due to the need to initialize it to detect a
|
||||
// potential failure ASAP we cannot use it to determine in the firmware why we got there, it has to be buffered.
|
||||
//
|
||||
// powerupReason is there to cater for that, and is what is used in the firmware to decide whether we have to enter emergency mode.
|
||||
// This variable needs to be in a RAM section that is not initialized or zeroed, since once we exit this pwrResetHandler() function the
|
||||
// C runtime would otherwise overwrite it during program init.
|
||||
// Only for X12, X10 power circuit causes inability to shut down on some samples.
|
||||
|
||||
if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) {
|
||||
pwrOn();
|
||||
if (boardState != BOARD_POWER_OFF) {
|
||||
powerupReason = boardState != BOARD_REBOOT && WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() ? DIRTY_SHUTDOWN : ~DIRTY_SHUTDOWN;
|
||||
RCC->CSR |= RCC_CSR_RMVF; //clear all flags
|
||||
}
|
||||
else {
|
||||
powerupReason = ~DIRTY_SHUTDOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x20030000; /* end of 192K RAM */
|
||||
_estack = 0x2002FFF0; /* end of 192K RAM */
|
||||
_heap_end = 0xC0800000; /* end of 8192K SDRAM */
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
@@ -35,7 +35,8 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
|
||||
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 65520
|
||||
NO_INIT (xrw) : ORIGIN = 0x1000FFF0, LENGTH = 16
|
||||
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
|
||||
SDRAM(xrw) : ORIGIN = 0xC0000000, LENGTH = 8192K
|
||||
}
|
||||
@@ -132,7 +133,8 @@ SECTIONS
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
*(.noinit)
|
||||
} >CCM
|
||||
} >NO_INIT
|
||||
|
||||
|
||||
/* collect all uninitialized .ccm sections */
|
||||
.ram (NOLOAD) :
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x10010000; /* end of 64K CCM */
|
||||
_heap_end = 0xC0800000; /* end of 8192K SDRAM */
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
@@ -35,11 +34,16 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
|
||||
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 65520
|
||||
NO_INIT (xrw) : ORIGIN = 0x1000FFF0, LENGTH = 16
|
||||
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
|
||||
SDRAM(xrw) : ORIGIN = 0xC0000000, LENGTH = 8192K
|
||||
}
|
||||
|
||||
/* Main stack end */
|
||||
_estack = 0x10000000 + LENGTH(CCM);
|
||||
_main_stack_start = _estack - _Main_Stack_Size;
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
@@ -52,6 +56,9 @@ SECTIONS
|
||||
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
|
||||
|
||||
|
||||
|
||||
_stext = .; /* Provide the name for the start of this section */
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
@@ -135,7 +142,8 @@ SECTIONS
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
*(.noinit)
|
||||
} >CCM
|
||||
} >NO_INIT
|
||||
|
||||
|
||||
/* collect all uninitialized .ccm sections */
|
||||
.ram (NOLOAD) :
|
||||
|
||||
@@ -20,26 +20,28 @@
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x10010000; /* end of 64K CCM */
|
||||
_heap_end = 0xC0800000; /* end of 8192K SDRAM */
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0; /* required amount of heap */
|
||||
_Main_Stack_Size = 1024; /* required amount of stack for interrupt stack (Main stack) */
|
||||
|
||||
/* Main stack end */
|
||||
_main_stack_start = _estack - _Main_Stack_Size;
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
|
||||
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||
CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 65520
|
||||
NO_INIT (xrw) : ORIGIN = 0x1000FFF0, LENGTH = 16
|
||||
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
|
||||
SDRAM(xrw) : ORIGIN = 0xC0000000, LENGTH = 8192K
|
||||
}
|
||||
|
||||
/* Main stack end */
|
||||
_estack = 0x10000000 + LENGTH(CCM);
|
||||
_main_stack_start = _estack - _Main_Stack_Size;
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
@@ -138,7 +140,7 @@ SECTIONS
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
*(.noinit)
|
||||
} >CCM
|
||||
} >NO_INIT
|
||||
|
||||
/* collect all uninitialized .ccm sections */
|
||||
.ram (NOLOAD) :
|
||||
|
||||
@@ -24,7 +24,6 @@ void trainerSendNextFrame();
|
||||
|
||||
void init_trainer_ppm()
|
||||
{
|
||||
#if 0
|
||||
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_OUT_GPIO_PinSource, TRAINER_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
@@ -38,8 +37,8 @@ void init_trainer_ppm()
|
||||
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
|
||||
TRAINER_TIMER->ARR = 45000;
|
||||
TRAINER_TIMER->CCR2 = GET_PPM_DELAY(TRAINER_MODULE)*2;
|
||||
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (g_model.moduleData[TRAINER_MODULE].ppm.pulsePol ? 0 : TIM_CCER_CC2P);
|
||||
TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY()*2;
|
||||
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P);
|
||||
TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_0; // Force O/P high
|
||||
TRAINER_TIMER->BDTR = TIM_BDTR_MOE;
|
||||
TRAINER_TIMER->EGR = 1;
|
||||
@@ -47,120 +46,96 @@ void init_trainer_ppm()
|
||||
TRAINER_TIMER->CCMR1 = TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
TRAINER_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
setupPulsesPPMTrainer();
|
||||
trainerSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(TRAINER_OUT_DMA_IRQn);
|
||||
NVIC_SetPriority(TRAINER_OUT_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
|
||||
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop_trainer_ppm()
|
||||
{
|
||||
#if 0
|
||||
NVIC_DisableIRQ(TRAINER_OUT_DMA_IRQn);
|
||||
NVIC_DisableIRQ(TRAINER_TIMER_IRQn);
|
||||
|
||||
TRAINER_OUT_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
TRAINER_TIMER->DIER = 0; // Stop Interrupt
|
||||
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_trainer_capture()
|
||||
{
|
||||
#if 0
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_IN_GPIO_PinSource, TRAINER_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = TRAINER_IN_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(TRAINER_GPIO, &GPIO_InitStructure);
|
||||
GPIO_PinAFConfig(TRAINER_GPIO, TRAINER_IN_GPIO_PinSource, TRAINER_GPIO_AF);
|
||||
|
||||
TRAINER_TIMER->ARR = 0xFFFF;
|
||||
TRAINER_TIMER->PSC = TRAINER_TIMER_FREQ / 2000000 - 1; // 0.5uS
|
||||
TRAINER_TIMER->CR2 = 0;
|
||||
TRAINER_TIMER->CCMR1 = TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_CC1S_0;
|
||||
TRAINER_TIMER->CCER = TIM_CCER_CC1E;
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags
|
||||
TRAINER_TIMER->CCMR1 = TRAINER_IN_CCMR1;
|
||||
TRAINER_TIMER->CCER = TRAINER_IN_CCER;
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF & ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear flags
|
||||
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE;
|
||||
TRAINER_TIMER->CR1 = TIM_CR1_CEN;
|
||||
|
||||
NVIC_EnableIRQ(TRAINER_TIMER_IRQn);
|
||||
NVIC_SetPriority(TRAINER_TIMER_IRQn, 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
void stop_trainer_capture()
|
||||
{
|
||||
#if 0
|
||||
NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt
|
||||
|
||||
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
|
||||
TRAINER_TIMER->DIER = 0; // Stop Interrupt
|
||||
#endif
|
||||
}
|
||||
short unsigned int* lastPulse = 0;
|
||||
|
||||
void trainerSendNextFrame()
|
||||
{
|
||||
#if 0
|
||||
TRAINER_TIMER->CCR2 = GET_PPM_DELAY(TRAINER_MODULE)*2;
|
||||
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (g_model.moduleData[TRAINER_MODULE].ppm.pulsePol ? 0 : TIM_CCER_CC2P);
|
||||
TRAINER_TIMER->CCR1 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
|
||||
setupPulsesPPMTrainer();
|
||||
TRAINER_TIMER->CCR2 = GET_TRAINER_PPM_DELAY() * 2;
|
||||
TRAINER_TIMER->CCER = TIM_CCER_CC2E | (GET_TRAINER_PPM_POLARITY() ? 0 : TIM_CCER_CC2P);
|
||||
lastPulse = trainerPulsesData.ppm.ptr;
|
||||
TRAINER_TIMER->CCR3 = *(trainerPulsesData.ppm.ptr - 1) - 4000; // 2mS in advance
|
||||
|
||||
TRAINER_OUT_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
TRAINER_OUT_DMA_STREAM->CR |= TRAINER_OUT_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
TRAINER_OUT_DMA_STREAM->PAR = CONVERT_PTR_UINT(&TRAINER_TIMER->ARR);
|
||||
TRAINER_OUT_DMA_STREAM->M0AR = CONVERT_PTR_UINT(trainerPulsesData.ppm.pulses);
|
||||
TRAINER_OUT_DMA_STREAM->NDTR = trainerPulsesData.ppm.ptr - trainerPulsesData.ppm.pulses;
|
||||
TRAINER_OUT_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
extern "C" void TRAINER_OUT_DMA_IRQHandler()
|
||||
{
|
||||
if (!DMA_GetITStatus(TRAINER_OUT_DMA_STREAM, TRAINER_OUT_DMA_FLAG_TC))
|
||||
return;
|
||||
|
||||
DMA_ClearITPendingBit(TRAINER_OUT_DMA_STREAM, TRAINER_OUT_DMA_FLAG_TC);
|
||||
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag
|
||||
TRAINER_TIMER->DIER |= TIM_DIER_CC1IE; // Enable this interrupt
|
||||
trainerPulsesData.ppm.ptr = trainerPulsesData.ppm.pulses;
|
||||
TRAINER_TIMER->DIER |= TIM_DIER_UDE;
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear this flag
|
||||
TRAINER_TIMER->DIER |= TIM_DIER_UIE; // Enable this interrupt
|
||||
}
|
||||
|
||||
extern "C" void TRAINER_TIMER_IRQHandler()
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_TRAINER);
|
||||
|
||||
uint16_t capture = 0;
|
||||
bool doCapture = false;
|
||||
|
||||
// What mode? in or out?
|
||||
|
||||
if ((TRAINER_TIMER->DIER & TIM_DIER_CC1IE) && (TRAINER_TIMER->SR & TIM_SR_CC1IF)) {
|
||||
// capture mode on trainer jack
|
||||
capture = TRAINER_TIMER->CCR1;
|
||||
capture = TRAINER_IN_COUNTER_REGISTER;
|
||||
if (TRAINER_CONNECTED() && currentTrainerMode == TRAINER_MODE_MASTER_TRAINER_JACK) {
|
||||
doCapture = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (doCapture) {
|
||||
captureTrainerPulses(capture);
|
||||
}
|
||||
|
||||
}
|
||||
// PPM out compare interrupt
|
||||
if ((TRAINER_TIMER->DIER & TIM_DIER_CC1IE) && (TRAINER_TIMER->SR & TIM_SR_CC1IF)) {
|
||||
if ((TRAINER_TIMER->DIER & TIM_DIER_CC3IE) && (TRAINER_TIMER->SR & TIM_SR_CC3IF)) {
|
||||
// compare interrupt
|
||||
TRAINER_TIMER->DIER &= ~TIM_DIER_CC1IE; // stop this interrupt
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_CC1IF; // Clear flag
|
||||
setupPulsesPPMTrainer();
|
||||
TRAINER_TIMER->DIER &= ~TIM_DIER_CC3IE; // stop this interrupt
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF; // Clear flag
|
||||
trainerSendNextFrame();
|
||||
}
|
||||
|
||||
if ((TRAINER_TIMER->DIER & TIM_DIER_UIE) && (TRAINER_TIMER->SR & TIM_SR_UIF)) {
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
|
||||
TRAINER_TIMER->ARR = *trainerPulsesData.ppm.ptr++;
|
||||
if (trainerPulsesData.ppm.ptr == lastPulse) {
|
||||
TRAINER_TIMER->SR &= ~TIM_SR_CC3IF; // Clear flag
|
||||
TRAINER_TIMER->DIER |= TIM_DIER_CC3IE; // Enable this interrupt
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
#define FLYSKY_FIXED_RX_VOLTAGE (uint8_t)(FLYSKY_SENSOR_RX_VOLTAGE + (uint8_t)0xA0)
|
||||
|
||||
#define MIN_SNR 8
|
||||
#define MAX_SNR 45
|
||||
|
||||
#define FIXED_PRECISION 15
|
||||
#define FIXED(val) (val << FIXED_PRECISION)
|
||||
#define DECIMAL(val) (val >> FIXED_PRECISION)
|
||||
#define R_DIV_G_MUL_10_Q15 UINT64_C(9591506)
|
||||
#define INV_LOG2_E_Q1DOT31 UINT64_C(0x58b90bfc) // Inverse log base 2 of e
|
||||
|
||||
struct FlyskyNv14Sensor {
|
||||
const uint16_t id;
|
||||
const uint8_t subId;
|
||||
const char * name;
|
||||
const TelemetryUnit unit;
|
||||
const uint8_t precision;
|
||||
const uint8_t offset;
|
||||
const uint8_t bytes;
|
||||
const bool issigned;
|
||||
};
|
||||
|
||||
|
||||
union nv14SensorData {
|
||||
uint8_t UINT8;
|
||||
uint16_t UINT16;
|
||||
int16_t INT16;
|
||||
uint32_t UINT32;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const FlyskyNv14Sensor Nv14Sensor[]=
|
||||
{
|
||||
{FLYSKY_FIXED_RX_VOLTAGE, 0, STR_SENSOR_A3, UNIT_VOLTS, 2, 0, 2, false},
|
||||
{FLYSKY_SENSOR_RX_SIGNAL, 0, STR_SENSOR_RX_QUALITY, UNIT_RAW, 0, 0, 2, false},
|
||||
{FLYSKY_SENSOR_RX_RSSI, 0, STR_SENSOR_RSSI, UNIT_DB, 0, 0, 2, true,},
|
||||
{FLYSKY_SENSOR_RX_NOISE, 0, STR_SENSOR_RX_NOISE, UNIT_DB, 0, 0, 2, true},
|
||||
{FLYSKY_SENSOR_RX_SNR, 0, STR_SENSOR_RX_SNR, UNIT_DB, 0, 0, 2, false},
|
||||
{FLYSKY_SENSOR_RX_SNR, 1, STR_SENSOR_RX_QUALITY, UNIT_PERCENT, 0, 0, 2, false},
|
||||
{FLYSKY_SENSOR_TEMP, 0, STR_SENSOR_TEMP1, UNIT_CELSIUS, 1, 0, 2, true},
|
||||
{FLYSKY_SENSOR_EXT_VOLTAGE,0, STR_SENSOR_A3, UNIT_VOLTS, 2, 0, 2, false},
|
||||
{FLYSKY_SENSOR_MOTO_RPM, 0, STR_SENSOR_RPM, UNIT_RPMS, 0, 0, 2, false},
|
||||
{FLYSKY_SENSOR_PRESURRE, 0, STR_SENSOR_PRES, UNIT_RAW, 1, 0, 2, false},
|
||||
{FLYSKY_SENSOR_PRESURRE, 1, STR_SENSOR_ALT, UNIT_METERS, 0, 0, 2, true},
|
||||
{FLYSKY_SENSOR_GPS, 1, STR_SENSOR_SATELLITES, UNIT_RAW, 0, 0, 1, false},
|
||||
{FLYSKY_SENSOR_GPS, 2, STR_SENSOR_GPS, UNIT_GPS_LATITUDE, 0, 1, 4, true},
|
||||
{FLYSKY_SENSOR_GPS, 3, STR_SENSOR_GPS, UNIT_GPS_LONGITUDE, 0, 5, 4, true},
|
||||
{FLYSKY_SENSOR_GPS, 4, STR_SENSOR_ALT, UNIT_METERS, 0, 8, 2, true},
|
||||
{FLYSKY_SENSOR_GPS, 5, STR_SENSOR_GSPD, UNIT_KMH, 1, 10, 2, false},
|
||||
{FLYSKY_SENSOR_GPS, 6, STR_SENSOR_HDG, UNIT_DEGREE, 3, 12, 2, false},
|
||||
|
||||
};
|
||||
|
||||
FlyskyNv14Sensor defaultNv14Sensor = {0, 0, "UNKNOWN", UNIT_RAW, 0, 0, 2, false};
|
||||
|
||||
const signed short tAltitude[225]=
|
||||
{
|
||||
20558, 20357, 20158, 19962, 19768, 19576, 19387, 19200, 19015, 18831, 18650, 18471, 18294, 18119, 17946, 17774,
|
||||
17604, 17436, 17269, 17105, 16941, 16780, 16619, 16461, 16304, 16148, 15993, 15841, 15689, 15539, 15390, 15242,
|
||||
15096, 14950, 14806, 14664, 14522, 14381, 14242, 14104, 13966, 13830, 13695, 13561, 13428, 13296, 13165, 13035,
|
||||
12906, 12777, 12650, 12524, 12398, 12273, 12150, 12027, 11904, 11783, 11663, 11543, 11424, 11306, 11189, 11072,
|
||||
10956, 10841, 10726, 10613, 10500, 10387, 10276, 10165, 10054, 9945, 9836, 9727, 9620, 9512, 9406, 9300,
|
||||
9195, 9090, 8986, 8882, 8779, 8677, 8575, 8474, 8373, 8273, 8173, 8074, 7975, 7877, 7779, 7682,
|
||||
7585, 7489, 7394, 7298, 7204, 7109, 7015, 6922, 6829, 6737, 6645, 6553, 6462, 6371, 6281, 6191,
|
||||
6102, 6012, 5924, 5836, 5748, 5660, 5573, 5487, 5400, 5314, 5229, 5144, 5059, 4974, 4890, 4807,
|
||||
4723, 4640, 4557, 4475, 4393, 4312, 4230, 4149, 4069, 3988, 3908, 3829, 3749, 3670, 3591, 3513,
|
||||
3435, 3357, 3280, 3202, 3125, 3049, 2972, 2896, 2821, 2745, 2670, 2595, 2520, 2446, 2372, 2298,
|
||||
2224, 2151, 2078, 2005, 1933, 1861, 1789, 1717, 1645, 1574, 1503, 1432, 1362, 1292, 1222, 1152,
|
||||
1082, 1013, 944, 875, 806, 738, 670, 602, 534, 467, 399, 332, 265, 199, 132, 66,
|
||||
0, -66, -131, -197, -262, -327, -392, -456, -521, -585, -649, -713, -776, -840, -903, -966,
|
||||
-1029,-1091, -1154, -1216, -1278, -1340, -1402, -1463, -1525, -1586, -1647, -1708, -1769, -1829, -1889, -1950,
|
||||
-2010
|
||||
};
|
||||
signed short CalculateAltitude( unsigned int Pressure, unsigned int SeaLevelPressure )
|
||||
{
|
||||
unsigned int Index;
|
||||
signed int Altitude1;
|
||||
signed int Altitude2;
|
||||
unsigned int Decimal;
|
||||
unsigned long Ratio;
|
||||
|
||||
Ratio = ( ( ( unsigned long long ) Pressure << 16 ) + ( SeaLevelPressure / 2 ) ) / SeaLevelPressure;
|
||||
if( Ratio < ( ( 1 << 16 ) * 250 / 1000 ) )// 0.250 inclusive
|
||||
{
|
||||
Ratio = ( 1 << 16 ) * 250 / 1000;
|
||||
}
|
||||
else if( Ratio > ( 1 << 16 ) * 1125 / 1000 - 1 ) // 1.125 non-inclusive
|
||||
{
|
||||
Ratio = ( 1 << 16 ) * 1125 / 1000 - 1;
|
||||
}
|
||||
|
||||
Ratio -= ( 1 << 16 ) * 250 / 1000; // from 0.000 (inclusive) to 0.875 (non-inclusive)
|
||||
Index = Ratio >> 8;
|
||||
Decimal = Ratio & ( ( 1 << 8 ) - 1 );
|
||||
Altitude1 = tAltitude[Index];
|
||||
Altitude2 = Altitude1 - tAltitude[Index + 1];
|
||||
Altitude1 = Altitude1 - ( Altitude2 * Decimal + ( 1 << 7 ) ) / ( 1 << 8 );
|
||||
if( Altitude1 >= 0 )
|
||||
{
|
||||
return( ( Altitude1 + 1 ) / 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( ( Altitude1 - 1 ) / 2 );
|
||||
}
|
||||
}
|
||||
|
||||
const FlyskyNv14Sensor* getFlyskyNv14Sensor(uint16_t id, uint8_t subId)
|
||||
{
|
||||
for(unsigned index = 0; index < *(&Nv14Sensor + 1) - Nv14Sensor; index++ ){
|
||||
if (Nv14Sensor[index].id == id && Nv14Sensor[index].subId == subId) {
|
||||
return &Nv14Sensor[index];
|
||||
}
|
||||
}
|
||||
return &defaultNv14Sensor;
|
||||
}
|
||||
|
||||
void flySkyNv14SetDefault(int index, uint8_t id, uint8_t subId, uint8_t instance)
|
||||
{
|
||||
TelemetrySensor & telemetrySensor = g_model.telemetrySensors[index];
|
||||
telemetrySensor.id = id;
|
||||
telemetrySensor.subId = subId;
|
||||
telemetrySensor.instance = instance;
|
||||
const FlyskyNv14Sensor* sensor = getFlyskyNv14Sensor(id, subId);
|
||||
telemetrySensor.init(sensor->name, sensor->unit, sensor->precision);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t GetSensorValueFlySkyNv14(const FlyskyNv14Sensor* sensor, const uint8_t * data){
|
||||
int32_t value = 0;
|
||||
const nv14SensorData* sensorData = reinterpret_cast<const nv14SensorData*>(data + sensor->offset);
|
||||
if(sensor->bytes == 1) value = sensorData->UINT8;
|
||||
else if(sensor->bytes == 2) value = sensor->issigned ? sensorData->INT16 : sensorData->UINT16;
|
||||
else if(sensor->bytes == 4) value = sensorData->UINT32;
|
||||
|
||||
if(sensor->id == FLYSKY_SENSOR_RX_RSSI) {
|
||||
if(value < -200) value = -200;
|
||||
#if defined (PCBNV14)
|
||||
if(!g_model.rssiAlarms.flysky_telemetry)
|
||||
#endif
|
||||
{
|
||||
value += 200;
|
||||
value /= 2;
|
||||
}
|
||||
telemetryData.rssi.set(value);
|
||||
}
|
||||
if(sensor->id == FLYSKY_SENSOR_PRESURRE && sensor->subId != 0){
|
||||
value = CalculateAltitude(value, 101325);
|
||||
value = (value+500)/1000;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void flySkyNv14ProcessTelemetryPacket(const uint8_t * ptr, uint8_t sensorID )
|
||||
{
|
||||
uint8_t instnace = *ptr++;
|
||||
if(sensorID == FLYSKY_SENSOR_RX_VOLTAGE) sensorID = FLYSKY_FIXED_RX_VOLTAGE;
|
||||
for (const FlyskyNv14Sensor sensor : Nv14Sensor) {
|
||||
if (sensor.id == sensorID) {
|
||||
int32_t value = GetSensorValueFlySkyNv14(&sensor, ptr);
|
||||
setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_NV14, sensor.id, sensor.subId, instnace, value, sensor.unit, sensor.precision);
|
||||
}
|
||||
}
|
||||
|
||||
telemetryStreaming = TELEMETRY_TIMEOUT10ms;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __FLYSKY_NV14_H__
|
||||
#define __FLYSKY_NV14_H__
|
||||
|
||||
enum FlySkySensorType_E {
|
||||
FLYSKY_SENSOR_RX_VOLTAGE,
|
||||
FLYSKY_SENSOR_RX_SIGNAL,
|
||||
FLYSKY_SENSOR_RX_RSSI,
|
||||
FLYSKY_SENSOR_RX_NOISE,
|
||||
FLYSKY_SENSOR_RX_SNR,
|
||||
FLYSKY_SENSOR_TEMP,
|
||||
FLYSKY_SENSOR_EXT_VOLTAGE,
|
||||
FLYSKY_SENSOR_MOTO_RPM,
|
||||
FLYSKY_SENSOR_PRESURRE,
|
||||
FLYSKY_SENSOR_GPS
|
||||
};
|
||||
typedef struct FLYSKY_GPS_INFO_S {
|
||||
uint8_t position_fix;
|
||||
uint8_t satell_cnt;
|
||||
uint8_t latitude[4];
|
||||
uint8_t longtitude[4];
|
||||
uint8_t altitude[4];
|
||||
uint8_t g_speed[2];
|
||||
uint8_t direction[2];
|
||||
} gps_info_t;
|
||||
typedef struct FLYSKY_SENSOR_DATA_S {
|
||||
uint8_t sensor_type;
|
||||
uint8_t sensor_id;
|
||||
uint8_t voltage[2];
|
||||
uint8_t signal;
|
||||
uint8_t rssi[2];
|
||||
uint8_t noise[2];
|
||||
uint8_t snr[2];
|
||||
uint8_t temp[2];
|
||||
uint8_t ext_voltage[2];
|
||||
uint8_t moto_rpm[2];
|
||||
uint8_t pressure_value[2];
|
||||
gps_info_t gps_info;
|
||||
} rx_sensor_t;
|
||||
|
||||
void flySkyNv14SetDefault(int index, uint8_t id, uint8_t subId, uint8_t instance);
|
||||
void flySkyNv14ProcessTelemetryPacket(const uint8_t * ptr, uint8_t SensorType );
|
||||
|
||||
#endif
|
||||
@@ -60,6 +60,31 @@ void checkTrainerSettings()
|
||||
init_trainer_capture();
|
||||
}
|
||||
}
|
||||
#elif defined(PCBNV14)
|
||||
void checkTrainerSettings()
|
||||
{
|
||||
uint8_t requiredTrainerMode = g_model.trainerData.mode;
|
||||
if (requiredTrainerMode != currentTrainerMode) {
|
||||
switch (currentTrainerMode) {
|
||||
case TRAINER_MODE_MASTER_TRAINER_JACK:
|
||||
stop_trainer_capture();
|
||||
break;
|
||||
case TRAINER_MODE_SLAVE:
|
||||
stop_trainer_ppm();
|
||||
break;
|
||||
}
|
||||
|
||||
currentTrainerMode = requiredTrainerMode;
|
||||
switch (requiredTrainerMode) {
|
||||
case TRAINER_MODE_SLAVE:
|
||||
init_trainer_ppm();
|
||||
break;
|
||||
case TRAINER_MODE_MASTER_TRAINER_JACK:
|
||||
init_trainer_capture();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void checkTrainerSettings()
|
||||
{
|
||||
|
||||
@@ -165,6 +165,9 @@ const char STR_BEEP_LENGTH[] = TR_BEEP_LENGTH;
|
||||
const char STR_CONTRAST[] = TR_CONTRAST;
|
||||
const char STR_ALARMS_LABEL[] = TR_ALARMS_LABEL;
|
||||
const char STR_BATTERY_RANGE[] = TR_BATTERY_RANGE;
|
||||
const char STR_BATTERYCHARGING[] = TR_BATTERYCHARGING;
|
||||
const char STR_BATTERYFULL[] = TR_BATTERYFULL;
|
||||
const char STR_BATTERYNONE[] = TR_BATTERYNONE;
|
||||
const char STR_BATTERYWARNING[] = TR_BATTERYWARNING;
|
||||
const char STR_INACTIVITYALARM[] = TR_INACTIVITYALARM;
|
||||
const char STR_MEMORYWARNING[] = TR_MEMORYWARNING;
|
||||
|
||||
@@ -286,6 +286,9 @@ extern const char STR_GYRO_MAX[];
|
||||
extern const char STR_CONTRAST[];
|
||||
extern const char STR_ALARMS_LABEL[];
|
||||
extern const char STR_BATTERY_RANGE[];
|
||||
extern const char STR_BATTERYCHARGING[];
|
||||
extern const char STR_BATTERYFULL[];
|
||||
extern const char STR_BATTERYNONE[];
|
||||
extern const char STR_BATTERYWARNING[];
|
||||
extern const char STR_INACTIVITYALARM[];
|
||||
extern const char STR_MEMORYWARNING[];
|
||||
|
||||
@@ -513,6 +513,9 @@
|
||||
#define TR_CONTRAST "对比度"
|
||||
#define TR_ALARMS_LABEL "警告"
|
||||
#define TR_BATTERY_RANGE TR("Batt. range", "电压测量范围")
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "低电压报警值"
|
||||
#define TR_INACTIVITYALARM "长时间无操作"
|
||||
#define TR_MEMORYWARNING "内存不足"
|
||||
|
||||
@@ -507,6 +507,9 @@
|
||||
#define TR_CONTRAST "Kontrast LCD"
|
||||
#define TR_ALARMS_LABEL "Alarmy"
|
||||
#define TR_BATTERY_RANGE TR("Ukazatel bat.", "Ukazatel baterie")
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Vybitá bat."
|
||||
#define TR_INACTIVITYALARM TR("Nečinnost", "Nečinnost rádia")
|
||||
#define TR_MEMORYWARNING "Plná pamět'"
|
||||
|
||||
@@ -512,6 +512,9 @@
|
||||
#define TR_CONTRAST "LCD-Kontrast"
|
||||
#define TR_ALARMS_LABEL "Alarme"
|
||||
#define TR_BATTERY_RANGE TR("Akku Bereich", "Akku Spannungsbereich") // Symbol Akku Ladezustand
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING TR("Akku Warnung", "Akkuspannungswarnung")
|
||||
#define TR_INACTIVITYALARM TR("Inaktivität", "Inaktivität nach")
|
||||
#define TR_MEMORYWARNING "Speicher voll"
|
||||
|
||||
@@ -510,6 +510,9 @@
|
||||
#define TR_CONTRAST "Contrast"
|
||||
#define TR_ALARMS_LABEL "Alarms"
|
||||
#define TR_BATTERY_RANGE TR("Batt. range", "Battery meter range")
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Battery low"
|
||||
#define TR_INACTIVITYALARM "Inactivity"
|
||||
#define TR_MEMORYWARNING "Memory low"
|
||||
|
||||
@@ -532,6 +532,9 @@
|
||||
#define TR_CONTRAST "Contraste"
|
||||
#define TR_ALARMS_LABEL "Alarmas"
|
||||
#define TR_BATTERY_RANGE TR("Rango bateria","Rango medidor Bater")
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Bateria Baja"
|
||||
#define TR_INACTIVITYALARM "Inactividad"
|
||||
#define TR_MEMORYWARNING "Memoria Baja"
|
||||
|
||||
@@ -524,6 +524,9 @@
|
||||
#define TR_CONTRAST "Contrast"
|
||||
#define TR_ALARMS_LABEL "Alarms"
|
||||
#define TR_BATTERY_RANGE TR("Battery range","Battery meter range")
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Battery Low"
|
||||
#define TR_INACTIVITYALARM "Inactivity"
|
||||
#define TR_MEMORYWARNING "Memory Low"
|
||||
|
||||
@@ -530,6 +530,9 @@
|
||||
#define TR_CONTRAST "Contraste"
|
||||
#define TR_ALARMS_LABEL "Alarmes"
|
||||
#define TR_BATTERY_RANGE "Plage batterie"
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING TR("Batterie", "Batterie faible")
|
||||
#define TR_INACTIVITYALARM "Inactivité"
|
||||
#define TR_MEMORYWARNING "Mémoire pleine"
|
||||
|
||||
@@ -535,6 +535,9 @@
|
||||
#define TR_CONTRAST "Contrasto"
|
||||
#define TR_ALARMS_LABEL "Allarmi"
|
||||
#define TR_BATTERY_RANGE TR("Int. Batt.", "Intervallo batteria")
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING TR(INDENT "Avv. Batt.", INDENT "Avviso Batteria")
|
||||
#define TR_INACTIVITYALARM INDENT "Inattività"
|
||||
#define TR_MEMORYWARNING TR(INDENT "Avv. Mem.", INDENT "Avviso Memoria")
|
||||
|
||||
@@ -512,7 +512,9 @@
|
||||
#define TR_CONTRAST "LCD-Kontrast"
|
||||
#define TR_ALARMS_LABEL "Alarm"
|
||||
#define TR_BATTERY_RANGE TR("Accu Bereik", "Accu Spngs-Bereik") // Symbol Akku Ladezustand
|
||||
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Accu laag"
|
||||
#define TR_INACTIVITYALARM TR("Inactiviteit", "Inactiviteit na")
|
||||
#define TR_MEMORYWARNING "Geheugen laag"
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
#define TR_CONTRAST "Kontrast"
|
||||
#define TR_ALARMS_LABEL "Alarmy"
|
||||
#define TR_BATTERY_RANGE TR("PokażPasBat.", "Pokaż pasek bateri")
|
||||
#define TR_BATTERYCHARGING "Ładowanie..."
|
||||
#define TR_BATTERYFULL "Bateria naładowana"
|
||||
#define TR_BATTERYNONE "Brak!"
|
||||
#define TR_BATTERYWARNING "Bateria rozładowana"
|
||||
#define TR_INACTIVITYALARM "Alarm bezczynności"
|
||||
#define TR_MEMORYWARNING "Pełna pamięć"
|
||||
|
||||
@@ -517,6 +517,9 @@
|
||||
#define TR_CONTRAST "Contraste"
|
||||
#define TR_ALARMS_LABEL "Alarmes"
|
||||
#define TR_BATTERY_RANGE "Battery Range"
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Bateria Baixa"
|
||||
#define TR_INACTIVITYALARM "Inactividade"
|
||||
#define TR_MEMORYWARNING "Memoria Baixa"
|
||||
|
||||
@@ -533,6 +533,9 @@
|
||||
#define TR_CONTRAST "Kontrast"
|
||||
#define TR_ALARMS_LABEL "Alarm"
|
||||
#define TR_BATTERY_RANGE "Batteri-MinMax"
|
||||
#define TR_BATTERYCHARGING "Charging..."
|
||||
#define TR_BATTERYFULL "Battery full"
|
||||
#define TR_BATTERYNONE "None!"
|
||||
#define TR_BATTERYWARNING "Batteri"
|
||||
#define TR_INACTIVITYALARM "Inaktivitet"
|
||||
#define TR_MEMORYWARNING "Lite Minne"
|
||||
|
||||
Reference in New Issue
Block a user