diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 81a0d2576..b9e65142e 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -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 }; diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 172351770..40e950455 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -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); diff --git a/radio/src/gui/colorlcd/colors.h b/radio/src/gui/colorlcd/colors.h index 60dc69deb..1394c8652 100644 --- a/radio/src/gui/colorlcd/colors.h +++ b/radio/src/gui/colorlcd/colors.h @@ -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_ diff --git a/radio/src/gui/colorlcd/themes/frsky.cpp b/radio/src/gui/colorlcd/themes/frsky.cpp index fe4c73827..e6eccce29 100644 --- a/radio/src/gui/colorlcd/themes/frsky.cpp +++ b/radio/src/gui/colorlcd/themes/frsky.cpp @@ -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 diff --git a/radio/src/pulses/afhds2.cpp b/radio/src/pulses/afhds2.cpp new file mode 100644 index 000000000..b3c201dd6 --- /dev/null +++ b/radio/src/pulses/afhds2.cpp @@ -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 +} + diff --git a/radio/src/pulses/afhds2.h b/radio/src/pulses/afhds2.h new file mode 100644 index 000000000..baa1caa06 --- /dev/null +++ b/radio/src/pulses/afhds2.h @@ -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 +#include +#include + +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_ */ diff --git a/radio/src/pulses/afhds3.cpp b/radio/src/pulses/afhds3.cpp new file mode 100644 index 000000000..c37dd4aa2 --- /dev/null +++ b/radio/src/pulses/afhds3.cpp @@ -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(rxBuffer); + AfhdsFrame* requestFrame = reinterpret_cast(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(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(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; +} + +} diff --git a/radio/src/pulses/afhds3.h b/radio/src/pulses/afhds3.h new file mode 100644 index 000000000..b88ddf3c3 --- /dev/null +++ b/radio/src/pulses/afhds3.h @@ -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 +#include + +#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(&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 commandQueue; +}; + +} +#endif /* PULSES_AFHDS3_H_ */ diff --git a/radio/src/pulses/flysky.cpp b/radio/src/pulses/flysky.cpp index 14d1ce6bb..0b69a4bc7 100644 --- a/radio/src/pulses/flysky.cpp +++ b/radio/src/pulses/flysky.cpp @@ -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(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(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]); } diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 1388f443c..1e6f7f5ef 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -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 ppm; diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index c7c70f977..0fb5b0c18 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -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() diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index 1bacbf374..881cfb885 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -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 diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 106734a2f..ef8792564 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -516,6 +516,6 @@ int main() return 0; } -#if defined(PCBHORUS) +#if defined(PCBHORUS) || defined(PCBNV14) void *__dso_handle = nullptr; #endif diff --git a/radio/src/targets/common/arm/stm32/flash_driver.cpp b/radio/src/targets/common/arm/stm32/flash_driver.cpp index 6fd4c1a29..8b55e9dab 100644 --- a/radio/src/targets/common/arm/stm32/flash_driver.cpp +++ b/radio/src/targets/common/arm/stm32/flash_driver.cpp @@ -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 diff --git a/radio/src/targets/common/arm/stm32/usbd_desc.c b/radio/src/targets/common/arm/stm32/usbd_desc.c index 527a6c0f5..cec340e69 100644 --- a/radio/src/targets/common/arm/stm32/usbd_desc.c +++ b/radio/src/targets/common/arm/stm32/usbd_desc.c @@ -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; } diff --git a/radio/src/targets/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index e75a7bcb1..909a195da 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -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) diff --git a/radio/src/targets/nv14/adc_driver.cpp b/radio/src/targets/nv14/adc_driver.cpp index a3db41634..60cc4a00b 100644 --- a/radio/src/targets/nv14/adc_driver.cpp +++ b/radio/src/targets/nv14/adc_driver.cpp @@ -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(); diff --git a/radio/src/targets/nv14/audio_spi_driver.cpp b/radio/src/targets/nv14/audio_spi_driver.cpp index c23d666c4..bf4a52fb5 100644 --- a/radio/src/targets/nv14/audio_spi_driver.cpp +++ b/radio/src/targets/nv14/audio_spi_driver.cpp @@ -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; isize * 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; } } diff --git a/radio/src/targets/nv14/backlight_driver.cpp b/radio/src/targets/nv14/backlight_driver.cpp index 90f7a13fe..5d2851497 100644 --- a/radio/src/targets/nv14/backlight_driver.cpp +++ b/radio/src/targets/nv14/backlight_driver.cpp @@ -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; } diff --git a/radio/src/targets/nv14/battery_driver.cpp b/radio/src/targets/nv14/battery_driver.cpp index 42050aabb..7c2acf81a 100644 --- a/radio/src/targets/nv14/battery_driver.cpp +++ b/radio/src/targets/nv14/battery_driver.cpp @@ -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); +} diff --git a/radio/src/targets/nv14/battery_driver.h b/radio/src/targets/nv14/battery_driver.h index 3e2c6c6f3..8f56ee30e 100644 --- a/radio/src/targets/nv14/battery_driver.h +++ b/radio/src/targets/nv14/battery_driver.h @@ -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 - - - - - - - - - - - - - - - - - diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index ccee7861d..2b1f3f8e3 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -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() -{ - -} \ No newline at end of file diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index 1c9385614..d07dc749a 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -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_ diff --git a/radio/src/targets/nv14/bootloader/boot_menu.cpp b/radio/src/targets/nv14/bootloader/boot_menu.cpp index 21338dae3..41d48140a 100644 --- a/radio/src/targets/nv14/bootloader/boot_menu.cpp +++ b/radio/src/targets/nv14/bootloader/boot_menu.cpp @@ -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); } } diff --git a/radio/src/targets/nv14/extmodule_driver.cpp b/radio/src/targets/nv14/extmodule_driver.cpp index 4cde18972..aacaf9cfd 100644 --- a/radio/src/targets/nv14/extmodule_driver.cpp +++ b/radio/src/targets/nv14/extmodule_driver.cpp @@ -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(); diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index 027da4cd2..977ed66ba 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -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 diff --git a/radio/src/targets/nv14/hallStick_driver.cpp b/radio/src/targets/nv14/hallStick_driver.cpp index d6103fbe0..4e0e8e044 100644 --- a/radio/src/targets/nv14/hallStick_driver.cpp +++ b/radio/src/targets/nv14/hallStick_driver.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "pulses/flysky.h" DMAFifo hallDMAFifo __DMA (HALL_DMA_Stream_RX); Fifo 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++) diff --git a/radio/src/targets/nv14/hallStick_driver.h b/radio/src/targets/nv14/hallStick_driver.h index efc156511..48de61cb1 100644 --- a/radio/src/targets/nv14/hallStick_driver.h +++ b/radio/src/targets/nv14/hallStick_driver.h @@ -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); diff --git a/radio/src/targets/nv14/haptic_driver.cpp b/radio/src/targets/nv14/haptic_driver.cpp index b4dc1db64..cd60bdb41 100644 --- a/radio/src/targets/nv14/haptic_driver.cpp +++ b/radio/src/targets/nv14/haptic_driver.cpp @@ -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) diff --git a/radio/src/targets/nv14/keys_driver.cpp b/radio/src/targets/nv14/keys_driver.cpp index a1cd25ff9..98512df67 100644 --- a/radio/src/targets/nv14/keys_driver.cpp +++ b/radio/src/targets/nv14/keys_driver.cpp @@ -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); } } diff --git a/radio/src/targets/nv14/lcd_driver.cpp b/radio/src/targets/nv14/lcd_driver.cpp index 70b8e48e3..c1b19906f 100644 --- a/radio/src/targets/nv14/lcd_driver.cpp +++ b/radio/src/targets/nv14/lcd_driver.cpp @@ -20,25 +20,22 @@ #include "opentx.h" - - uint8_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t LCD_BACKUP_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t currentLayer = LCD_FIRST_LAYER; -lcdSpiInitFucPtr lcdSpiInitFuc; +lcdSpiInitFucPtr lcdInitFunction; +lcdSpiInitFucPtr lcdOffFunction; +lcdSpiInitFucPtr lcdOnFunction; -volatile U8 LCD_ReadBuffer[24] = { 0, 0 }; +volatile uint8_t LCD_ReadBuffer[24] = { 0, 0 }; - -static void LCD_Delay( void ) -{ +static void LCD_Delay(void) { volatile unsigned int i; - for( i = 0; i < 20; i++ ) - { - ; + for (i = 0; i < 20; i++) { + ; } } @@ -85,21 +82,19 @@ void GPIO_SetDirection( GPIO_TypeDef *GPIOx, unsigned char Pin, unsigned char Is GPIOx->MODER = Register; //ExitCritical(); } - -static void LCD_AF_GPIOConfig(void) -{ +static void LCD_AF_GPIOConfig(void) { /* - ----------------------------------------------------------------------------- - LCD_CLK <-> PG.07 | LCD_HSYNC <-> PI.12 | LCD_R3 <-> PJ.02 | LCD_G5 <-> PK.00 - | LCD VSYNC <-> PI.13 | LCD_R4 <-> PJ.03 | LCD_G6 <-> PK.01 - | | LCD_R5 <-> PJ.04 | LCD_G7 <-> PK.02 - | | LCD_R6 <-> PJ.05 | LCD_B4 <-> PK.03 - | | LCD_R7 <-> PJ.06 | LCD_B5 <-> PK.04 - | | LCD_G2 <-> PJ.09 | LCD_B6 <-> PK.05 - | | LCD_G3 <-> PJ.10 | LCD_B7 <-> PK.06 - | | LCD_G4 <-> PJ.11 | LCD_DE <-> PK.07 - | | LCD_B3 <-> PJ.15 | - */ + ----------------------------------------------------------------------------- + LCD_CLK <-> PG.07 | LCD_HSYNC <-> PI.12 | LCD_R3 <-> PJ.02 | LCD_G5 <-> PK.00 + | LCD VSYNC <-> PI.13 | LCD_R4 <-> PJ.03 | LCD_G6 <-> PK.01 + | | LCD_R5 <-> PJ.04 | LCD_G7 <-> PK.02 + | | LCD_R6 <-> PJ.05 | LCD_B4 <-> PK.03 + | | LCD_R7 <-> PJ.06 | LCD_B5 <-> PK.04 + | | LCD_G2 <-> PJ.09 | LCD_B6 <-> PK.05 + | | LCD_G3 <-> PJ.10 | LCD_B7 <-> PK.06 + | | LCD_G4 <-> PJ.11 | LCD_DE <-> PK.07 + | | LCD_B3 <-> PJ.15 | + */ // GPIOG configuration GPIO_PinAFConfig(GPIOG, GPIO_PinSource7, GPIO_AF_LTDC); @@ -143,11 +138,9 @@ static void LCD_AF_GPIOConfig(void) GPIO_Init(GPIOK, &GPIO_InitStructure); } -static void lcdSpiConfig(void) -{ +static void lcdSpiConfig(void) { GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = LCD_SPI_SCK_GPIO_PIN | LCD_SPI_MOSI_GPIO_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; @@ -169,70 +162,57 @@ static void lcdSpiConfig(void) CLR_LCD_CS(); } -void lcdDelay() -{ +void lcdDelay() { delay_01us(1); } -unsigned char LCD_ReadByteOnFallingEdge( void ) -{ - unsigned int i; +unsigned char LCD_ReadByteOnFallingEdge(void) { + unsigned int i; unsigned char ReceiveData = 0; SET_LCD_DATA(); SET_LCD_DATA_INPUT(); - for( i = 0; i < 8; i++ ) - { - LCD_DELAY(); - SET_LCD_CLK(); - LCD_DELAY(); - LCD_DELAY(); - ReceiveData <<= 1; + for (i = 0; i < 8; i++) { + LCD_DELAY(); + SET_LCD_CLK(); + LCD_DELAY(); + LCD_DELAY(); + ReceiveData <<= 1; - CLR_LCD_CLK(); - LCD_DELAY(); - LCD_DELAY(); - if( READ_LCD_DATA_PIN() ) - { - ReceiveData |= 0x01; - } + CLR_LCD_CLK(); + LCD_DELAY(); + LCD_DELAY(); + if (READ_LCD_DATA_PIN()) { + ReceiveData |= 0x01; + } } SET_LCD_DATA_OUTPUT(); - return( ReceiveData ); + return (ReceiveData); } - -static void lcdWriteByte(uint8_t data_enable, uint8_t byte) -{ +static void lcdWriteByte(uint8_t data_enable, uint8_t byte) { LCD_SCK_LOW(); lcdDelay(); - if (data_enable) - { + if (data_enable) { LCD_MOSI_HIGH(); - } - else - { + } else { LCD_MOSI_LOW(); } LCD_SCK_HIGH(); lcdDelay(); - for ( int i = 0; i < 8; i++ ) - { + for (int i = 0; i < 8; i++) { LCD_SCK_LOW(); lcdDelay(); - if (byte & 0x80) - { + if (byte & 0x80) { LCD_MOSI_HIGH(); - } - else - { + } else { LCD_MOSI_LOW(); } @@ -245,433 +225,404 @@ static void lcdWriteByte(uint8_t data_enable, uint8_t byte) LCD_SCK_LOW(); } -unsigned char LCD_ReadByte( void ) -{ - unsigned int i; +unsigned char LCD_ReadByte(void) { + unsigned int i; unsigned char ReceiveData = 0; SET_LCD_DATA(); SET_LCD_DATA_INPUT(); - for( i = 0; i < 8; i++ ) - { - CLR_LCD_CLK(); - LCD_DELAY(); - LCD_DELAY(); - ReceiveData <<= 1; - SET_LCD_CLK(); - LCD_DELAY(); - LCD_DELAY(); - if( READ_LCD_DATA_PIN() ) - { - ReceiveData |= 0x01; - } + for (i = 0; i < 8; i++) { + CLR_LCD_CLK(); + LCD_DELAY(); + LCD_DELAY(); + ReceiveData <<= 1; + SET_LCD_CLK(); + LCD_DELAY(); + LCD_DELAY(); + if (READ_LCD_DATA_PIN()) { + ReceiveData |= 0x01; + } } CLR_LCD_CLK(); SET_LCD_DATA_OUTPUT(); - return( ReceiveData ); + return (ReceiveData); } - - -unsigned char LCD_ReadRegister( unsigned char Register ) -{ +unsigned char LCD_ReadRegister(unsigned char Register) { unsigned char ReadData = 0; - lcdWriteByte( 0, Register ); + lcdWriteByte(0, Register); LCD_DELAY(); LCD_DELAY(); ReadData = LCD_ReadByte(); - return( ReadData ); + return (ReadData); } -void lcdWriteCommand(uint8_t command) -{ +void lcdWriteCommand(uint8_t command) { lcdWriteByte(0, command); } -void lcdWriteData(uint8_t data) -{ +void lcdWriteData(uint8_t data) { lcdWriteByte(1, data); } -void LCD_HX8357D_Init( void ) -{ +void LCD_HX8357D_Init(void) { #if 0 -lcdWriteCommand(0x11); -delay_ms(200); + lcdWriteCommand(0x11); + delay_ms(200); -lcdWriteCommand(0xB9); -lcdWriteData(0xFF); -lcdWriteData(0x83); -lcdWriteData(0x57); + lcdWriteCommand(0xB9); + lcdWriteData(0xFF); + lcdWriteData(0x83); + lcdWriteData(0x57); -lcdWriteCommand(0xB1); -lcdWriteData(0x00); -lcdWriteData(0x14); -lcdWriteData(0x1C); -lcdWriteData(0x1C); -lcdWriteData(0xC7); -lcdWriteData(0x21); + lcdWriteCommand(0xB1); + lcdWriteData(0x00); + lcdWriteData(0x14); + lcdWriteData(0x1C); + lcdWriteData(0x1C); + lcdWriteData(0xC7); + lcdWriteData(0x21); -lcdWriteCommand(0xB3); -lcdWriteData(0x83); -lcdWriteData(0x00); -lcdWriteData(0x06); -lcdWriteData(0x06); + lcdWriteCommand(0xB3); + lcdWriteData(0x83); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x06); -lcdWriteCommand(0xB4); -lcdWriteData(0x11); -lcdWriteData(0x40); -lcdWriteData(0x00); -lcdWriteData(0x2A); -lcdWriteData(0x2A); -lcdWriteData(0x20); -lcdWriteData(0x4E); + lcdWriteCommand(0xB4); + lcdWriteData(0x11); + lcdWriteData(0x40); + lcdWriteData(0x00); + lcdWriteData(0x2A); + lcdWriteData(0x2A); + lcdWriteData(0x20); + lcdWriteData(0x4E); -lcdWriteCommand(0xB5); -lcdWriteData(0x03); -lcdWriteData(0x03); + lcdWriteCommand(0xB5); + lcdWriteData(0x03); + lcdWriteData(0x03); -lcdWriteCommand(0xB6); -lcdWriteData(0x38); + lcdWriteCommand(0xB6); + lcdWriteData(0x38); -lcdWriteCommand(0xC0); -lcdWriteData(0x24); -lcdWriteData(0x24); -lcdWriteData(0x00); -lcdWriteData(0x10); -lcdWriteData(0xc8); -lcdWriteData(0x08); + lcdWriteCommand(0xC0); + lcdWriteData(0x24); + lcdWriteData(0x24); + lcdWriteData(0x00); + lcdWriteData(0x10); + lcdWriteData(0xc8); + lcdWriteData(0x08); -lcdWriteCommand(0xC2); -lcdWriteData(0x00); -lcdWriteData(0x08); -lcdWriteData(0x04); + lcdWriteCommand(0xC2); + lcdWriteData(0x00); + lcdWriteData(0x08); + lcdWriteData(0x04); - -lcdWriteCommand(0xCC); -lcdWriteData(0x00); + lcdWriteCommand(0xCC); + lcdWriteData(0x00); //GAMMA 2.5" -lcdWriteCommand(0xE0); -lcdWriteData(0x00); -lcdWriteData(0x06); -lcdWriteData(0x0D); -lcdWriteData(0x18); -lcdWriteData(0x23); -lcdWriteData(0x3B); -lcdWriteData(0x45); -lcdWriteData(0x4D); -lcdWriteData(0x4D); -lcdWriteData(0x46); -lcdWriteData(0x40); -lcdWriteData(0x37); -lcdWriteData(0x34); -lcdWriteData(0x2F); -lcdWriteData(0x2B); -lcdWriteData(0x21); -lcdWriteData(0x00); -lcdWriteData(0x06); -lcdWriteData(0x0D); -lcdWriteData(0x18); -lcdWriteData(0x23); -lcdWriteData(0x3B); -lcdWriteData(0x45); -lcdWriteData(0x4D); -lcdWriteData(0x4D); -lcdWriteData(0x46); -lcdWriteData(0x40); -lcdWriteData(0x37); -lcdWriteData(0x34); -lcdWriteData(0x2F); -lcdWriteData(0x2B); -lcdWriteData(0x21); -lcdWriteData(0x00); -lcdWriteData(0x01); + lcdWriteCommand(0xE0); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x0D); + lcdWriteData(0x18); + lcdWriteData(0x23); + lcdWriteData(0x3B); + lcdWriteData(0x45); + lcdWriteData(0x4D); + lcdWriteData(0x4D); + lcdWriteData(0x46); + lcdWriteData(0x40); + lcdWriteData(0x37); + lcdWriteData(0x34); + lcdWriteData(0x2F); + lcdWriteData(0x2B); + lcdWriteData(0x21); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x0D); + lcdWriteData(0x18); + lcdWriteData(0x23); + lcdWriteData(0x3B); + lcdWriteData(0x45); + lcdWriteData(0x4D); + lcdWriteData(0x4D); + lcdWriteData(0x46); + lcdWriteData(0x40); + lcdWriteData(0x37); + lcdWriteData(0x34); + lcdWriteData(0x2F); + lcdWriteData(0x2B); + lcdWriteData(0x21); + lcdWriteData(0x00); + lcdWriteData(0x01); -lcdWriteCommand(0x3A); -lcdWriteData(0x66); + lcdWriteCommand(0x3A); + lcdWriteData(0x66); -lcdWriteCommand(0x36); -lcdWriteData(0x08); + lcdWriteCommand(0x36); + lcdWriteData(0x08); - -lcdWriteCommand(0x29); -delay_ms(10); + lcdWriteCommand(0x29); + delay_ms(10); #else - delay_ms(50); - lcdWriteCommand(0xB9); //EXTC - lcdWriteData(0xFF); //EXTC - lcdWriteData(0x83); //EXTC - lcdWriteData(0x57); //EXTC - delay_ms(5); + delay_ms(50); + lcdWriteCommand(0xB9); //EXTC + lcdWriteData(0xFF); //EXTC + lcdWriteData(0x83); //EXTC + lcdWriteData(0x57); //EXTC + delay_ms(5); + lcdWriteCommand(0x3A); + lcdWriteData(0x65); //262k - lcdWriteCommand(0x3A); - lcdWriteData(0x65); //262k + lcdWriteCommand(0xB3); //COLOR FORMAT + lcdWriteData(0x83); //SDO_EN,BYPASS,EPF[1:0],0,0,RM,DM //43 + lcdWriteCommand(0xB6); // + lcdWriteData(0x5a); //VCOMDC - lcdWriteCommand(0xB3); //COLOR FORMAT - lcdWriteData(0x83); //SDO_EN,BYPASS,EPF[1:0],0,0,RM,DM //43 + lcdWriteCommand(0x35); // TE ON + lcdWriteData(0x01); - lcdWriteCommand(0xB6); // - lcdWriteData(0x5a); //VCOMDC + lcdWriteCommand(0xB0); + lcdWriteData(0x68); //70Hz - lcdWriteCommand(0x35); // TE ON - lcdWriteData(0x01); + lcdWriteCommand(0xCC); // Set Panel + lcdWriteData(0x00); // + lcdWriteCommand(0xB1); // + lcdWriteData(0x00); // + lcdWriteData(0x11); //BT + lcdWriteData(0x1C); //VSPR + lcdWriteData(0x1C); //VSNR + lcdWriteData(0x83); //AP + lcdWriteData(0x48); //FS 0xAA - lcdWriteCommand(0xB0); - lcdWriteData(0x68); //70Hz + lcdWriteCommand(0xB4); // + lcdWriteData(0x02); //NW + lcdWriteData(0x40); //RTN + lcdWriteData(0x00); //DIV + lcdWriteData(0x2A); //DUM + lcdWriteData(0x2A); //DUM + lcdWriteData(0x0D); //GDON + lcdWriteData(0x78); //GDOFF 0x4F + lcdWriteCommand(0xC0); //STBA + lcdWriteData(0x50); //OPON + lcdWriteData(0x50); //OPON + lcdWriteData(0x01); // + lcdWriteData(0x3C); // + lcdWriteData(0x1E); // + lcdWriteData(0x08); //GEN - lcdWriteCommand(0xCC); // Set Panel - lcdWriteData(0x00); // - - lcdWriteCommand(0xB1); // - lcdWriteData(0x00); // - lcdWriteData(0x11); //BT - lcdWriteData(0x1C); //VSPR - lcdWriteData(0x1C); //VSNR - lcdWriteData(0x83); //AP - lcdWriteData(0x48); //FS 0xAA - - lcdWriteCommand(0xB4); // - lcdWriteData(0x02); //NW - lcdWriteData(0x40); //RTN - lcdWriteData(0x00); //DIV - lcdWriteData(0x2A); //DUM - lcdWriteData(0x2A); //DUM - lcdWriteData(0x0D); //GDON - lcdWriteData(0x78); //GDOFF 0x4F - lcdWriteCommand(0xC0); //STBA - lcdWriteData(0x50); //OPON - lcdWriteData(0x50); //OPON - lcdWriteData(0x01); // - lcdWriteData(0x3C); // - lcdWriteData(0x1E); // - lcdWriteData(0x08); //GEN - - /* - lcdWriteCommand(0xE0); // - lcdWriteData(0x02); //1 - lcdWriteData(0x06); //2 - lcdWriteData(0x09); //3 - lcdWriteData(0x1C); //4 - lcdWriteData(0x27); //5 - lcdWriteData(0x3C); //6 - lcdWriteData(0x48); //7 - lcdWriteData(0x50); //8 - lcdWriteData(0x49); //9 - lcdWriteData(0x42); //10 - lcdWriteData(0x3E); //11 - lcdWriteData(0x35); //12 - lcdWriteData(0x31); //13 - lcdWriteData(0x2A); //14 - lcdWriteData(0x28); //15 - lcdWriteData(0x03); //16 - lcdWriteData(0x02); //17 v1 - lcdWriteData(0x06); //18 - lcdWriteData(0x09); //19 - lcdWriteData(0x1C); //20 - lcdWriteData(0x27); //21 - lcdWriteData(0x3C); //22 - lcdWriteData(0x48); //23 - lcdWriteData(0x50); //24 - lcdWriteData(0x49); //25 - lcdWriteData(0x42); //26 - lcdWriteData(0x3E); //27 - lcdWriteData(0x35); //28 - lcdWriteData(0x31); //29 - lcdWriteData(0x2A); //30 - lcdWriteData(0x28); //31 - lcdWriteData(0x03); //32 - lcdWriteData(0x44); //33 - lcdWriteData(0x01); //34 - */ - lcdWriteCommand(0xE0); -lcdWriteData(0x00); -lcdWriteData(0x06); -lcdWriteData(0x0D); -lcdWriteData(0x18); -lcdWriteData(0x23); -lcdWriteData(0x3B); -lcdWriteData(0x45); -lcdWriteData(0x4D); -lcdWriteData(0x4D); -lcdWriteData(0x46); -lcdWriteData(0x40); -lcdWriteData(0x37); -lcdWriteData(0x34); -lcdWriteData(0x2F); -lcdWriteData(0x2B); -lcdWriteData(0x21); -lcdWriteData(0x00); -lcdWriteData(0x06); -lcdWriteData(0x0D); -lcdWriteData(0x18); -lcdWriteData(0x23); -lcdWriteData(0x3B); -lcdWriteData(0x45); -lcdWriteData(0x4D); -lcdWriteData(0x4D); -lcdWriteData(0x46); -lcdWriteData(0x40); -lcdWriteData(0x37); -lcdWriteData(0x34); -lcdWriteData(0x2F); -lcdWriteData(0x2B); -lcdWriteData(0x21); -lcdWriteData(0x00); -lcdWriteData(0x01); - lcdWriteCommand(0x36); - lcdWriteData(0x18); - - lcdWriteCommand(0x11); // SLPOUT - delay_ms(200); - - lcdWriteCommand(0x29); // Display On - delay_ms(25); - lcdWriteCommand(0x2C); + /* + lcdWriteCommand(0xE0); // + lcdWriteData(0x02); //1 + lcdWriteData(0x06); //2 + lcdWriteData(0x09); //3 + lcdWriteData(0x1C); //4 + lcdWriteData(0x27); //5 + lcdWriteData(0x3C); //6 + lcdWriteData(0x48); //7 + lcdWriteData(0x50); //8 + lcdWriteData(0x49); //9 + lcdWriteData(0x42); //10 + lcdWriteData(0x3E); //11 + lcdWriteData(0x35); //12 + lcdWriteData(0x31); //13 + lcdWriteData(0x2A); //14 + lcdWriteData(0x28); //15 + lcdWriteData(0x03); //16 + lcdWriteData(0x02); //17 v1 + lcdWriteData(0x06); //18 + lcdWriteData(0x09); //19 + lcdWriteData(0x1C); //20 + lcdWriteData(0x27); //21 + lcdWriteData(0x3C); //22 + lcdWriteData(0x48); //23 + lcdWriteData(0x50); //24 + lcdWriteData(0x49); //25 + lcdWriteData(0x42); //26 + lcdWriteData(0x3E); //27 + lcdWriteData(0x35); //28 + lcdWriteData(0x31); //29 + lcdWriteData(0x2A); //30 + lcdWriteData(0x28); //31 + lcdWriteData(0x03); //32 + lcdWriteData(0x44); //33 + lcdWriteData(0x01); //34 + */ + lcdWriteCommand(0xE0); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x0D); + lcdWriteData(0x18); + lcdWriteData(0x23); + lcdWriteData(0x3B); + lcdWriteData(0x45); + lcdWriteData(0x4D); + lcdWriteData(0x4D); + lcdWriteData(0x46); + lcdWriteData(0x40); + lcdWriteData(0x37); + lcdWriteData(0x34); + lcdWriteData(0x2F); + lcdWriteData(0x2B); + lcdWriteData(0x21); + lcdWriteData(0x00); + lcdWriteData(0x06); + lcdWriteData(0x0D); + lcdWriteData(0x18); + lcdWriteData(0x23); + lcdWriteData(0x3B); + lcdWriteData(0x45); + lcdWriteData(0x4D); + lcdWriteData(0x4D); + lcdWriteData(0x46); + lcdWriteData(0x40); + lcdWriteData(0x37); + lcdWriteData(0x34); + lcdWriteData(0x2F); + lcdWriteData(0x2B); + lcdWriteData(0x21); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteCommand(0x36); + lcdWriteData(0x18); + lcdWriteCommand(0x11); // SLPOUT + delay_ms(200); + lcdWriteCommand(0x29); // Display On + delay_ms(25); + lcdWriteCommand(0x2C); #endif } -void LCD_HX8357D_On( void ) -{ - //lcdWriteCommand( 0x29 ); +void LCD_HX8357D_On(void) { + lcdWriteCommand(0x29); + lcdWriteCommand(0x22); } -void LCD_HX8357D_Off( void ) -{ - //lcdWriteCommand( 0x28 ); +void LCD_HX8357D_Off(void) { + lcdWriteCommand(0x22); + lcdWriteCommand(0x28); } -unsigned int LCD_HX8357D_ReadID( void ) -{ +unsigned int LCD_HX8357D_ReadID(void) { int ID = 0; - - return( ID ); + return (ID); } +void LCD_ILI9481_Init(void) { + lcdWriteCommand(0x11); + delay_ms(120); -void LCD_ILI9481_Init( void ) -{ - lcdWriteCommand(0x11); - delay_ms(120); + lcdWriteCommand(0xE4); + lcdWriteData(0x0A); - lcdWriteCommand(0xE4); - lcdWriteData(0x0A); + lcdWriteCommand(0xF0); + lcdWriteData(0x01); - lcdWriteCommand(0xF0); - lcdWriteData(0x01); + lcdWriteCommand(0xF3); + lcdWriteData(0x02); + lcdWriteData(0x1A); - lcdWriteCommand(0xF3); - lcdWriteData(0x02); - lcdWriteData(0x1A); + lcdWriteCommand(0xD0); + lcdWriteData(0x07); + lcdWriteData(0x42); + lcdWriteData(0x1B); - lcdWriteCommand(0xD0); - lcdWriteData(0x07); - lcdWriteData(0x42); - lcdWriteData(0x1B); + lcdWriteCommand(0xD1); + lcdWriteData(0x00); + lcdWriteData(0x00); //04 + lcdWriteData(0x1A); - lcdWriteCommand(0xD1); - lcdWriteData(0x00); - lcdWriteData(0x00);//04 - lcdWriteData(0x1A); + lcdWriteCommand(0xD2); + lcdWriteData(0x01); + lcdWriteData(0x00); //11 - lcdWriteCommand(0xD2); - lcdWriteData(0x01); - lcdWriteData(0x00);//11 + lcdWriteCommand(0xC0); + lcdWriteData(0x10); + lcdWriteData(0x3B); // + lcdWriteData(0x00); // + lcdWriteData(0x02); + lcdWriteData(0x11); - lcdWriteCommand(0xC0); - lcdWriteData(0x10); - lcdWriteData(0x3B);// - lcdWriteData(0x00);// - lcdWriteData(0x02); - lcdWriteData(0x11); + lcdWriteCommand(0xC5); + lcdWriteData(0x03); - lcdWriteCommand(0xC5); - lcdWriteData(0x03); + lcdWriteCommand(0xC8); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0x47); + lcdWriteData(0x60); + lcdWriteData(0x04); + lcdWriteData(0x16); + lcdWriteData(0x03); + lcdWriteData(0x67); + lcdWriteData(0x67); + lcdWriteData(0x06); + lcdWriteData(0x0F); + lcdWriteData(0x00); - lcdWriteCommand(0xC8); - lcdWriteData(0x00); - lcdWriteData(0x01); - lcdWriteData(0x47); - lcdWriteData(0x60); - lcdWriteData(0x04); - lcdWriteData(0x16); - lcdWriteData(0x03); - lcdWriteData(0x67); - lcdWriteData(0x67); - lcdWriteData(0x06); - lcdWriteData(0x0F); - lcdWriteData(0x00); + lcdWriteCommand(0x36); + lcdWriteData(0x08); - lcdWriteCommand(0x36); - lcdWriteData(0x08); + lcdWriteCommand(0x3A); + lcdWriteData(0x66); //0x55=65k color, 0x66=262k color. - lcdWriteCommand(0x3A); - lcdWriteData(0x66); //0x55=65k color, 0x66=262k color. + lcdWriteCommand(0x2A); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0x3F); - lcdWriteCommand(0x2A); - lcdWriteData(0x00); - lcdWriteData(0x00); - lcdWriteData(0x01); - lcdWriteData(0x3F); + lcdWriteCommand(0x2B); + lcdWriteData(0x00); + lcdWriteData(0x00); + lcdWriteData(0x01); + lcdWriteData(0xE0); - lcdWriteCommand(0x2B); - lcdWriteData(0x00); - lcdWriteData(0x00); - lcdWriteData(0x01); - lcdWriteData(0xE0); + lcdWriteCommand(0xB4); + lcdWriteData(0x11); - lcdWriteCommand(0xB4); - lcdWriteData(0x11); + lcdWriteCommand(0xc6); + lcdWriteData(0x82); - lcdWriteCommand(0xc6); - lcdWriteData(0x82); + delay_ms(120); - delay_ms(120); - - lcdWriteCommand(0x21); - lcdWriteCommand(0x29); - lcdWriteCommand(0x2C); + lcdWriteCommand(0x21); + lcdWriteCommand(0x29); + lcdWriteCommand(0x2C); } -void LCD_ILI9481_On( void ) -{ - //lcdWriteCommand( 0x29 ); -} -/*================================================================================================== -Name: -Function: -Input: -Output: -==================================================================================================*/ -void LCD_ILI9481_Off( void ) -{ - //lcdWriteCommand( 0x28 ); +void LCD_ILI9481_On(void) { + lcdWriteCommand(0x29); } -unsigned int LCD_ILI9481_ReadID( void ) -{ +void LCD_ILI9481_Off(void) { + lcdWriteCommand(0x28); +} + +unsigned int LCD_ILI9481_ReadID(void) { int ID = 0; int Data; /* Have a issue here */ return 0; - lcdWriteByte( 0, 0xBF ); - + lcdWriteByte(0, 0xBF); Data = LCD_ReadByteOnFallingEdge(); Data = LCD_ReadByteOnFallingEdge(); - ID = LCD_ReadByteOnFallingEdge(); + ID = LCD_ReadByteOnFallingEdge(); ID <<= 8; ID |= LCD_ReadByteOnFallingEdge(); Data = LCD_ReadByteOnFallingEdge(); @@ -681,186 +632,174 @@ unsigned int LCD_ILI9481_ReadID( void ) LCD_DELAY(); LCD_DELAY(); - lcdWriteCommand( 0xC6 ); - lcdWriteData( 0x82 ); + lcdWriteCommand(0xC6); + lcdWriteData(0x82); //lcdWriteData( 0x9b ); - return( ID ); + return (ID); } +void LCD_ILI9486_On(void) { + lcdWriteCommand(0x29); +} -void LCD_ILI9486_Init( void ) -{ - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x00 ); +void LCD_ILI9486_Init(void) { + lcdWriteCommand(0XFB); + lcdWriteData(0x00); - lcdWriteCommand( 0xf2 ); - lcdWriteData( 0x18 ); - lcdWriteData( 0xa3 ); - lcdWriteData( 0x12 ); - lcdWriteData( 0x02 ); - lcdWriteData( 0xb2 ); - lcdWriteData( 0x12 ); - lcdWriteData( 0xff ); - lcdWriteData( 0x13 ); - lcdWriteData( 0x00 ); - lcdWriteCommand( 0xf1 ); - lcdWriteData( 0x36 ); - lcdWriteData( 0x04 ); - lcdWriteData( 0x00 ); - lcdWriteData( 0x3c ); - lcdWriteData( 0x0f ); - lcdWriteData( 0x8f ); - lcdWriteCommand( 0xf8 ); - lcdWriteData( 0x21 ); - lcdWriteData( 0x04 ); - lcdWriteCommand( 0xf9 ); - lcdWriteData( 0x00 ); - lcdWriteData( 0x08 ); - lcdWriteCommand( 0x36 ); - lcdWriteData( 0x18 ); - lcdWriteCommand( 0x3a ); - lcdWriteData( 0x65 ); - lcdWriteCommand( 0xc0 ); - lcdWriteData( 0x0f ); - lcdWriteData( 0x0f ); - lcdWriteCommand( 0xc1 ); - lcdWriteData( 0x41 ); + lcdWriteCommand(0xf2); + lcdWriteData(0x18); + lcdWriteData(0xa3); + lcdWriteData(0x12); + lcdWriteData(0x02); + lcdWriteData(0xb2); + lcdWriteData(0x12); + lcdWriteData(0xff); + lcdWriteData(0x13); + lcdWriteData(0x00); + lcdWriteCommand(0xf1); + lcdWriteData(0x36); + lcdWriteData(0x04); + lcdWriteData(0x00); + lcdWriteData(0x3c); + lcdWriteData(0x0f); + lcdWriteData(0x8f); + lcdWriteCommand(0xf8); + lcdWriteData(0x21); + lcdWriteData(0x04); + lcdWriteCommand(0xf9); + lcdWriteData(0x00); + lcdWriteData(0x08); + lcdWriteCommand(0x36); + lcdWriteData(0x18); + lcdWriteCommand(0x3a); + lcdWriteData(0x65); + lcdWriteCommand(0xc0); + lcdWriteData(0x0f); + lcdWriteData(0x0f); + lcdWriteCommand(0xc1); + lcdWriteData(0x41); - lcdWriteCommand( 0xc5 ); - lcdWriteData( 0x00 ); - lcdWriteData( 0x27 ); - lcdWriteData( 0x80 ); - lcdWriteCommand( 0xb6 ); - lcdWriteData( 0x22 ); - lcdWriteData( 0x02 ); - lcdWriteData( 0x3b ); - lcdWriteCommand( 0xb1 ); - lcdWriteData( 0xb0 ); - lcdWriteData( 0x11 ); - lcdWriteCommand( 0xb4 ); - lcdWriteData( 0x02 ); - lcdWriteCommand( 0xb7 ); - lcdWriteData( 0xC6 ); + lcdWriteCommand(0xc5); + lcdWriteData(0x00); + lcdWriteData(0x27); + lcdWriteData(0x80); + lcdWriteCommand(0xb6); + lcdWriteData(0xb2); + lcdWriteData(0x42); + lcdWriteData(0x3b); + lcdWriteCommand(0xb1); + lcdWriteData(0xb0); + lcdWriteData(0x11); + lcdWriteCommand(0xb4); + lcdWriteData(0x02); + lcdWriteCommand(0xb7); + lcdWriteData(0xC6); - lcdWriteCommand( 0xe0 ); - lcdWriteData( 0x0f ); - lcdWriteData( 0x1C ); - lcdWriteData( 0x18 ); - lcdWriteData( 0x0B ); - lcdWriteData( 0x0D ); - lcdWriteData( 0x06 ); - lcdWriteData( 0x48 ); - lcdWriteData( 0x87 ); - lcdWriteData( 0x3A ); - lcdWriteData( 0x09 ); - lcdWriteData( 0x15 ); - lcdWriteData( 0x08 ); - lcdWriteData( 0x0D ); - lcdWriteData( 0x04 ); - lcdWriteData( 0x00 ); + lcdWriteCommand(0xe0); + lcdWriteData(0x0f); + lcdWriteData(0x1C); + lcdWriteData(0x18); + lcdWriteData(0x0B); + lcdWriteData(0x0D); + lcdWriteData(0x06); + lcdWriteData(0x48); + lcdWriteData(0x87); + lcdWriteData(0x3A); + lcdWriteData(0x09); + lcdWriteData(0x15); + lcdWriteData(0x08); + lcdWriteData(0x0D); + lcdWriteData(0x04); + lcdWriteData(0x00); - lcdWriteCommand( 0xe1 ); - lcdWriteData( 0x0f ); - lcdWriteData( 0x37 ); - lcdWriteData( 0x34 ); - lcdWriteData( 0x0A ); - lcdWriteData( 0x0B ); - lcdWriteData( 0x03 ); - lcdWriteData( 0x4B ); - lcdWriteData( 0x31 ); - lcdWriteData( 0x39 ); - lcdWriteData( 0x03 ); - lcdWriteData( 0x0F ); - lcdWriteData( 0x03 ); - lcdWriteData( 0x22 ); - lcdWriteData( 0x1D ); - lcdWriteData( 0x00 ); + lcdWriteCommand(0xe1); + lcdWriteData(0x0f); + lcdWriteData(0x37); + lcdWriteData(0x34); + lcdWriteData(0x0A); + lcdWriteData(0x0B); + lcdWriteData(0x03); + lcdWriteData(0x4B); + lcdWriteData(0x31); + lcdWriteData(0x39); + lcdWriteData(0x03); + lcdWriteData(0x0F); + lcdWriteData(0x03); + lcdWriteData(0x22); + lcdWriteData(0x1D); + lcdWriteData(0x00); - lcdWriteCommand( 0x21 ); - lcdWriteCommand( 0x11 ); - delay_ms( 120 ); - lcdWriteCommand( 0x28 ); + lcdWriteCommand(0x21); + lcdWriteCommand(0x11); + delay_ms(120); + lcdWriteCommand(0x28); LCD_ILI9486_On(); } -/*================================================================================================== -Name: -Function: -Input: -Output: -==================================================================================================*/ -void LCD_ILI9486_On( void ) -{ - lcdWriteCommand( 0x29 ); -} -/*================================================================================================== -Name: -Function: -Input: -Output: -==================================================================================================*/ -void LCD_ILI9486_Off( void ) -{ - lcdWriteCommand( 0x28 ); + +void LCD_ILI9486_Off(void) { + lcdWriteCommand(0x28); } - -unsigned int LCD_ILI9486_ReadID( void ) -{ +unsigned int LCD_ILI9486_ReadID(void) { int ID = 0; - lcdWriteCommand( 0XF7 ); - lcdWriteData( 0xA9 ); - lcdWriteData( 0x51 ); - lcdWriteData( 0x2C ); - lcdWriteData( 0x82 ); - lcdWriteCommand( 0XB0 ); - lcdWriteData( 0X80 ); + lcdWriteCommand(0XF7); + lcdWriteData(0xA9); + lcdWriteData(0x51); + lcdWriteData(0x2C); + lcdWriteData(0x82); + lcdWriteCommand(0XB0); + lcdWriteData(0X80); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x00 ); - ID = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x00); + ID = LCD_ReadRegister(0xd3); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x01 ); - ID = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x01); + ID = LCD_ReadRegister(0xd3); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x02 ); - ID = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x02); + ID = LCD_ReadRegister(0xd3); ID <<= 8; - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x03 ); - ID |= LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x03); + ID |= LCD_ReadRegister(0xd3); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x00 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x00); - return( ID ); + return (ID); } -void LCD_ILI9488_Init( void ) -{ - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x00 ); +void LCD_ILI9488_On(void) { + lcdWriteCommand(0x29); + lcdWriteCommand(0x23); //all pixels on +} - lcdWriteCommand( 0XF7 ); - lcdWriteData( 0xA9 ); - lcdWriteData( 0x51 ); - lcdWriteData( 0x2C ); - lcdWriteData( 0x82 ); +void LCD_ILI9488_Init(void) { + lcdWriteCommand(0XFB); + lcdWriteData(0x00); - lcdWriteCommand( 0xC0 ); - lcdWriteData( 0x11 ); - lcdWriteData( 0x09 ); + lcdWriteCommand(0XF7); + lcdWriteData(0xA9); + lcdWriteData(0x51); + lcdWriteData(0x2C); + lcdWriteData(0x82); - lcdWriteCommand( 0xC1 ); - lcdWriteData( 0x41 ); + lcdWriteCommand(0xC0); + lcdWriteData(0x11); + lcdWriteData(0x09); - lcdWriteCommand( 0XC5 ); - lcdWriteData( 0x00 ); - lcdWriteData( 0x0A ); - lcdWriteData( 0x80 ); + lcdWriteCommand(0xC1); + lcdWriteData(0x41); + + lcdWriteCommand(0XC5); + lcdWriteData(0x00); + lcdWriteData(0x0A); + lcdWriteData(0x80); lcdWriteCommand(0xB1); lcdWriteData(0xB0); @@ -929,288 +868,110 @@ void LCD_ILI9488_Init( void ) LCD_ILI9488_On(); } -/*================================================================================================== -Name: -Function: -Input: -Output: -==================================================================================================*/ -void LCD_ILI9488_On( void ) -{ - lcdWriteCommand( 0x29 ); -} -/*================================================================================================== -Name: -Function: -Input: -Output: -==================================================================================================*/ -void LCD_ILI9488_Off( void ) -{ - lcdWriteCommand( 0x28 ); + +void LCD_ILI9488_Off(void) { + lcdWriteCommand(0x22); //all pixels off + lcdWriteCommand(0x28); } -void LCD_ILI9488_ReadDevice( void ) -{ - int Index = 0; - int Parameter = 0x80; +void LCD_ILI9488_ReadDevice(void) { + int Index = 0; + int Parameter = 0x80; - #if 1 +#if 1 - #if 1 - lcdWriteCommand(0XF7); - lcdWriteData(0xA9); - lcdWriteData(0x51); - lcdWriteData(0x2C); - lcdWriteData(0x82); +#if 1 + lcdWriteCommand(0XF7); + lcdWriteData(0xA9); + lcdWriteData(0x51); + lcdWriteData(0x2C); + lcdWriteData(0x82); - lcdWriteCommand(0XB0); - lcdWriteData(0X80); + lcdWriteCommand(0XB0); + lcdWriteData(0X80); - #endif - lcdWriteCommand(0XFB); - lcdWriteData( Parameter|0x00 ); - LCD_ReadBuffer[Index++]=LCD_ReadRegister( 0xd3 ); +#endif + lcdWriteCommand(0XFB); + lcdWriteData(Parameter | 0x00); + LCD_ReadBuffer[Index++] = LCD_ReadRegister(0xd3); - //lcdWriteCommand(0X2E); - lcdWriteCommand(0XFB); - lcdWriteData( Parameter|0x01 ); //Parameter2=0X88 - LCD_ReadBuffer[Index++]=LCD_ReadRegister( 0xd3 ); + //lcdWriteCommand(0X2E); + lcdWriteCommand(0XFB); + lcdWriteData(Parameter | 0x01); //Parameter2=0X88 + LCD_ReadBuffer[Index++] = LCD_ReadRegister(0xd3); + lcdWriteCommand(0XFB); + lcdWriteData(Parameter | 0x02); //Parameter2=0X88 + LCD_ReadBuffer[Index++] = LCD_ReadRegister(0xd3); - lcdWriteCommand(0XFB); - lcdWriteData( Parameter|0x02 ); //Parameter2=0X88 - LCD_ReadBuffer[Index++]=LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(Parameter | 0x03); //Parameter2=0X88 + LCD_ReadBuffer[Index++] = LCD_ReadRegister(0xd3); +#endif - - lcdWriteCommand(0XFB); - lcdWriteData( Parameter|0x03 ); //Parameter2=0X88 - LCD_ReadBuffer[Index++]=LCD_ReadRegister( 0xd3 ); - #endif - - #if 0 - lcdWriteCommand( 0XFB ); - lcdWriteData( Parameter|0x00 ); //Parameter3=0X94 - LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); - lcdWriteData( Parameter|0x01 ); //Parameter3=0X94 - LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); - lcdWriteCommand( 0XFB ); - lcdWriteData( Parameter|0x02 ); //Parameter3=0X94 - LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); - - lcdWriteCommand( 0XFB ); - lcdWriteData( Parameter|0x03 ); //Parameter4=0X88 - LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); - #else - //lcdWriteCommand( 0xd0 ); - //lcdWriteData( Parameter|0x03 ); //Parameter4=0X88 - //LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd0 ); - #endif -} - - -unsigned int LCD_ILI9488_ReadID( void ) -{ - int ID = 0; - - lcdWriteCommand( 0XF7 ); - lcdWriteData( 0xA9 ); - lcdWriteData( 0x51 ); - lcdWriteData( 0x2C ); - lcdWriteData( 0x82 ); - lcdWriteCommand( 0XB0 ); - lcdWriteData( 0X80 ); - - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x80|0x00 ); - ID = LCD_ReadRegister( 0xd3 ); - - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x80|0x01 ); - ID = LCD_ReadRegister( 0xd3 ); - - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x80|0x02 ); - ID = LCD_ReadRegister( 0xd3 ); - ID <<= 8; - - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x80|0x03 ); - ID |= LCD_ReadRegister( 0xd3 ); - - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x00 ); - return( ID ); -} - -void LCD_ST7796S_Init( void ) -{ +#if 0 lcdWriteCommand( 0XFB ); - lcdWriteData( 0x00 ); + lcdWriteData( Parameter|0x00 ); //Parameter3=0X94 + LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); + lcdWriteData( Parameter|0x01 );//Parameter3=0X94 + LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand( 0XFB ); + lcdWriteData( Parameter|0x02 );//Parameter3=0X94 + LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); - lcdWriteCommand( 0x11 ); - delay_ms( 120 ); - lcdWriteCommand( 0x13 ); - - lcdWriteCommand( 0xf0 ); - lcdWriteData( 0xc3 ); - lcdWriteCommand( 0xf0 ); - lcdWriteData( 0x96 ); - - lcdWriteCommand( 0x36 ); - - #if defined( LCD_DIRECTION ) && ( LCD_DIRECTION == LCD_VERTICAL ) - - lcdWriteData( 0x08 ); - - #else - #if defined( LCD_DEBUG ) && ( LCD_DEBUG == ON ) - lcdWriteData( 0xcc ); - #else - lcdWriteData( 0xb8 ); - #endif - - #endif - - lcdWriteCommand( 0x3A ); - lcdWriteData( 0x65 ); - - lcdWriteCommand( 0xB4 ); - lcdWriteData( 0x01 ); - - lcdWriteCommand( 0xb5 ); - lcdWriteData( VERTICAL_FRONT_PORCH ); - lcdWriteData( VERTICAL_BACK_PORCH + VERTICAL_SYNC_HEIGHT ); - lcdWriteData( 0x00 ); - lcdWriteData( HORIZONTAL_BACK_PORCH + 4 ); - - lcdWriteCommand( 0xb6 ); - lcdWriteData( 0xe0 ); - lcdWriteData( 0x42 ); - lcdWriteData( 0x3b ); - - lcdWriteCommand( 0xB7 ); - lcdWriteData( 0x66 ); - - lcdWriteCommand( 0xe8 ); - lcdWriteData( 0x40 ); - lcdWriteData( 0x8a ); - lcdWriteData( 0x00 ); - lcdWriteData( 0x00 ); - lcdWriteData( 0x29 ); - lcdWriteData( 0x19 ); - lcdWriteData( 0xa5 ); - lcdWriteData( 0x33 ); - - lcdWriteCommand( 0xc1 ); - lcdWriteData( 0x06 ); - - lcdWriteCommand( 0xc2 ); - lcdWriteData( 0xa7 ); - - lcdWriteCommand( 0xc5 ); - lcdWriteData( 0x18 ); - - lcdWriteCommand( 0xe0 ); //Positive Voltage Gamma Control - lcdWriteData( 0xf0 ); - lcdWriteData( 0x09 ); - lcdWriteData( 0x0b ); - lcdWriteData( 0x06 ); - lcdWriteData( 0x04 ); - lcdWriteData( 0x15 ); - lcdWriteData( 0x2f ); - lcdWriteData( 0x54 ); - lcdWriteData( 0x42 ); - lcdWriteData( 0x3c ); - lcdWriteData( 0x17 ); - lcdWriteData( 0x14 ); - lcdWriteData( 0x18 ); - lcdWriteData( 0x1b ); - - lcdWriteCommand( 0xe1 ); //Negative Voltage Gamma Control - lcdWriteData( 0xf0 ); - lcdWriteData( 0x09 ); - lcdWriteData( 0x0b ); - lcdWriteData( 0x06 ); - lcdWriteData( 0x04 ); - lcdWriteData( 0x03 ); - lcdWriteData( 0x2d ); - lcdWriteData( 0x43 ); - lcdWriteData( 0x42 ); - lcdWriteData( 0x3b ); - lcdWriteData( 0x16 ); - lcdWriteData( 0x14 ); - lcdWriteData( 0x17 ); - lcdWriteData( 0x1b ); - - lcdWriteCommand( 0xf0 ); - lcdWriteData( 0x3c ); - lcdWriteCommand( 0xf0 ); - lcdWriteData( 0x69 ); - - delay_ms( 5 ); - lcdWriteCommand( 0x28 ); - //lcdWriteCommand( 0x29 ); - lcdWriteCommand( 0x2C ); - - LCD_ST7796S_On(); + lcdWriteCommand( 0XFB ); + lcdWriteData( Parameter|0x03 );//Parameter4=0X88 + LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd3 ); +#else + //lcdWriteCommand( 0xd0 ); + //lcdWriteData( Parameter|0x03 ); //Parameter4=0X88 + //LCD_ReadBuffer[Index++] = LCD_ReadRegister( 0xd0 ); +#endif } -void LCD_ST7796S_On( void ) -{ - lcdWriteCommand( 0x29 ); -} -/*================================================================================================== -Name: -Function: -Input: -Output: -==================================================================================================*/ -void LCD_ST7796S_Off( void ) -{ - lcdWriteCommand( 0x28 ); -} - -unsigned int LCD_ST7796S_ReadID( void ) -{ +unsigned int LCD_ILI9488_ReadID(void) { int ID = 0; - lcdWriteCommand( 0XF7 ); - lcdWriteData( 0xA9 ); - lcdWriteData( 0x51 ); - lcdWriteData( 0x2C ); - lcdWriteData( 0x82 ); - lcdWriteCommand( 0XB0 ); - lcdWriteData( 0X80 ); + lcdWriteCommand(0XF7); + lcdWriteData(0xA9); + lcdWriteData(0x51); + lcdWriteData(0x2C); + lcdWriteData(0x82); + lcdWriteCommand(0XB0); + lcdWriteData(0X80); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x00 ); - ID = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x80 | 0x00); + ID = LCD_ReadRegister(0xd3); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x01 ); - ID = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x80 | 0x01); + ID = LCD_ReadRegister(0xd3); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x02 ); - ID = LCD_ReadRegister( 0xd3 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x80 | 0x02); + ID = LCD_ReadRegister(0xd3); ID <<= 8; - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x10|0x03 ); - ID |= LCD_ReadRegister( 0xd3 ); - lcdWriteCommand( 0XFB ); - lcdWriteData( 0x00 ); + lcdWriteCommand(0XFB); + lcdWriteData(0x80 | 0x03); + ID |= LCD_ReadRegister(0xd3); - return( ID ); + lcdWriteCommand(0XFB); + lcdWriteData(0x00); + return (ID); } +void LCD_ST7796S_On(void) { + lcdWriteCommand(0x29); +} +void LCD_ST7796S_Init(void) { + lcdWriteCommand(0XFB); + lcdWriteData(0x00); -static void lcdSpiInit() -{ lcdWriteCommand(0x11); - delay_ms( 120 ); + delay_ms(120); lcdWriteCommand(0x13); lcdWriteCommand(0xf0); @@ -1220,12 +981,18 @@ static void lcdSpiInit() lcdWriteCommand(0x36); -// #if defined( LCD_DIRECTION ) && ( LCD_DIRECTION == LCD_VERTICAL ) - lcdWriteData(0x08); -// #else - //lcdWriteData(0xf8); - //lcdWriteData(0xcc); -//#endif +#if defined( LCD_DIRECTION ) && ( LCD_DIRECTION == LCD_VERTICAL ) + + lcdWriteData( 0x08 ); + +#else +#if defined( LCD_DEBUG ) && ( LCD_DEBUG == ON ) + lcdWriteData( 0xcc ); +#else + lcdWriteData(0xb8); +#endif + +#endif lcdWriteCommand(0x3A); lcdWriteData(0x65); @@ -1234,10 +1001,10 @@ static void lcdSpiInit() lcdWriteData(0x01); lcdWriteCommand(0xb5); - lcdWriteData(VFP); - lcdWriteData(VBP + VSH); + lcdWriteData (VERTICAL_FRONT_PORCH); + lcdWriteData(VERTICAL_BACK_PORCH + VERTICAL_SYNC_HEIGHT); lcdWriteData(0x00); - lcdWriteData(HBP + 4); + lcdWriteData(HORIZONTAL_BACK_PORCH + 4); lcdWriteCommand(0xb6); lcdWriteData(0xe0); @@ -1305,14 +1072,50 @@ static void lcdSpiInit() delay_ms(5); lcdWriteCommand(0x28); + //lcdWriteCommand( 0x29 ); lcdWriteCommand(0x2C); - delay_ms(50); - lcdWriteCommand(0x29); // LCD ON + LCD_ST7796S_On(); } -static void lcdReset() -{ +void LCD_ST7796S_Off(void) { + lcdWriteCommand(0x28); +} + +unsigned int LCD_ST7796S_ReadID(void) { + int ID = 0; + + lcdWriteCommand(0XF7); + lcdWriteData(0xA9); + lcdWriteData(0x51); + lcdWriteData(0x2C); + lcdWriteData(0x82); + lcdWriteCommand(0XB0); + lcdWriteData(0X80); + + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x00); + ID = LCD_ReadRegister(0xd3); + + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x01); + ID = LCD_ReadRegister(0xd3); + + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x02); + ID = LCD_ReadRegister(0xd3); + ID <<= 8; + lcdWriteCommand(0XFB); + lcdWriteData(0x10 | 0x03); + ID |= LCD_ReadRegister(0xd3); + + lcdWriteCommand(0XFB); + lcdWriteData(0x00); + + return (ID); +} + +static void lcdReset() { LCD_NRST_HIGH(); delay_ms(1); @@ -1323,8 +1126,7 @@ static void lcdReset() delay_ms(100); } -void LCD_Init_LTDC() -{ +void LCD_Init_LTDC() { LTDC_InitTypeDef LTDC_InitStruct; /* Configure PLLSAI prescalers for LCD */ @@ -1333,7 +1135,7 @@ void LCD_Init_LTDC() /* PLLLCDCLK = PLLSAI_VCO Output/PLL_LTDC = 192/3 = 64 Mhz */ /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/4 = 16 Mhz */ RCC_PLLSAIConfig(192 * 2 / 3, 6, 3); - RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div4); + RCC_LTDCCLKDivConfig (RCC_PLLSAIDivR_Div4); /* Enable PLLSAI Clock */ RCC_PLLSAICmd(ENABLE); @@ -1396,16 +1198,15 @@ void LCD_Init_LTDC() #endif } -void LCD_LayerInit() -{ +void LCD_LayerInit() { LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct; /* Windowing configuration */ /* In this case all the active display area is used to display a picture then : - Horizontal start = horizontal synchronization + Horizontal back porch = 30 - Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1 - Vertical start = vertical synchronization + vertical back porch = 4 - Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */ + Horizontal start = horizontal synchronization + Horizontal back porch = 30 + Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1 + Vertical start = vertical synchronization + vertical back porch = 4 + Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */ LTDC_Layer_InitStruct.LTDC_HorizontalStart = HBP + 1; LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_W + HBP); LTDC_Layer_InitStruct.LTDC_VerticalStart = VBP + 1; @@ -1426,21 +1227,21 @@ void LCD_LayerInit() LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA; /* the length of one line of pixels in bytes + 3 then : - Line Lenth = Active high width x number of bytes per pixel + 3 - Active high width = LCD_W - number of bytes per pixel = 2 (pixel_format : RGB565) - */ + Line Lenth = Active high width x number of bytes per pixel + 3 + Active high width = LCD_W + number of bytes per pixel = 2 (pixel_format : RGB565) + */ LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_W * 2) + 3); /* the pitch is the increment from the start of one line of pixels to the - start of the next line in bytes, then : - Pitch = Active high width x number of bytes per pixel */ + start of the next line in bytes, then : + Pitch = Active high width x number of bytes per pixel */ LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_W * 2); /* Configure the number of lines */ LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_H; /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */ - LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)LCD_FIRST_FRAME_BUFFER; + LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t) LCD_FIRST_FRAME_BUFFER; /* Initialize LTDC layer 1 */ LTDC_LayerInit(LTDC_Layer1, <DC_Layer_InitStruct); @@ -1450,13 +1251,14 @@ void LCD_LayerInit() LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA; /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */ - LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)LCD_SECOND_FRAME_BUFFER; + LTDC_Layer_InitStruct.LTDC_CFBStartAdress = + (uint32_t) LCD_SECOND_FRAME_BUFFER; /* Initialize LTDC layer 2 */ LTDC_LayerInit(LTDC_Layer2, <DC_Layer_InitStruct); /* LTDC configuration reload */ - LTDC_ReloadConfig(LTDC_IMReload); + LTDC_ReloadConfig (LTDC_IMReload); LTDC_LayerCmd(LTDC_Layer1, ENABLE); LTDC_LayerCmd(LTDC_Layer2, ENABLE); @@ -1467,16 +1269,16 @@ void LCD_LayerInit() LTDC_DitherCmd(ENABLE); } -BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_FIRST_FRAME_BUFFER); -BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_SECOND_FRAME_BUFFER); +BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, + (uint16_t *) LCD_FIRST_FRAME_BUFFER); +BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H, + (uint16_t *) LCD_SECOND_FRAME_BUFFER); BitmapBuffer * lcd = &lcdBuffer1; -void LCD_SetLayer(uint32_t layer) -{ +void LCD_SetLayer(uint32_t layer) { if (layer == LCD_FIRST_LAYER) { lcd = &lcdBuffer1; - } - else { + } else { lcd = &lcdBuffer2; } currentLayer = layer; @@ -1486,15 +1288,16 @@ void LCD_SetTransparency(uint8_t transparency) { if (currentLayer == LCD_FIRST_LAYER) { LTDC_LayerAlpha(LTDC_Layer1, transparency); - } - else { + } else { LTDC_LayerAlpha(LTDC_Layer2, transparency); } - LTDC_ReloadConfig(LTDC_IMReload); + LTDC_ReloadConfig (LTDC_IMReload); } -void lcdInit() -{ +extern void loadFonts(); +void lcdInit(void) { + + loadFonts(); /* Configure the LCD SPI+RESET pins */ lcdSpiConfig(); @@ -1505,39 +1308,35 @@ void lcdInit() LCD_AF_GPIOConfig(); /* Send LCD initializaiton commands */ - if (LCD_ST7796S_ReadID() == LCD_ST7796S_ID) - { - lcdSpiInitFuc = LCD_ST7796S_Init; - } - else if (LCD_ILI9481_ReadID() == LCD_ILI9481_ID) - { - lcdSpiInitFuc = LCD_ILI9481_Init; - } - else if (LCD_ILI9486_ReadID() == LCD_ILI9486_ID) - { - lcdSpiInitFuc = LCD_ILI9486_Init; - } - else if (LCD_ILI9488_ReadID() == LCD_ILI9488_ID) - { - lcdSpiInitFuc = LCD_ILI9488_Init; - } - else if (LCD_HX8357D_ReadID() == LCD_HX8357D_ID) - { - lcdSpiInitFuc = LCD_HX8357D_Init; - } - - if (NULL != lcdSpiInitFuc) - { - lcdSpiInitFuc(); - } - else - { + if (LCD_ILI9481_ReadID() == LCD_ILI9481_ID) { + TRACE("LCD INIT: ILI9481"); + lcdInitFunction = LCD_ILI9481_Init; + lcdOffFunction = LCD_ILI9481_Off; + lcdOnFunction = LCD_ILI9481_On; + } else if (LCD_ILI9486_ReadID() == LCD_ILI9486_ID) { + TRACE("LCD INIT: ILI9486"); + lcdInitFunction = LCD_ILI9486_Init; + lcdOffFunction = LCD_ILI9486_Off; + lcdOnFunction = LCD_ILI9486_On; + } else if (LCD_ILI9488_ReadID() == LCD_ILI9488_ID) { + TRACE("LCD INIT: ILI9488"); + lcdInitFunction = LCD_ILI9488_Init; + lcdOffFunction = LCD_ILI9488_Off; + lcdOnFunction = LCD_ILI9488_On; + } else if (LCD_HX8357D_ReadID() == LCD_HX8357D_ID) { + lcdInitFunction = LCD_HX8357D_Init; + lcdOffFunction = LCD_HX8357D_Off; + lcdOnFunction = LCD_HX8357D_On; + TRACE("LCD INIT: HX8357D"); + } else { //if (LCD_ST7796S_ReadID() == LCD_ST7796S_ID) /* Default is ST7796S */ - lcdSpiInitFuc = LCD_ST7796S_Init; - lcdSpiInitFuc(); + TRACE("LCD INIT (default): ST7796S"); + lcdInitFunction = LCD_ST7796S_Init; + lcdOffFunction = LCD_ST7796S_Off; + lcdOnFunction = LCD_ST7796S_On; } - //lcdSpiInit(); + lcdInitFunction(); LCD_Init_LTDC(); @@ -1547,12 +1346,12 @@ void lcdInit() LTDC_Cmd(ENABLE); /* Set Background layer */ - LCD_SetLayer(LCD_FIRST_LAYER); + LCD_SetLayer (LCD_FIRST_LAYER); // lcdClear(); LCD_SetTransparency(0); /* Set Foreground layer */ - LCD_SetLayer(LCD_SECOND_LAYER); + LCD_SetLayer (LCD_SECOND_LAYER); lcd->clear(); LCD_SetTransparency(255); } diff --git a/radio/src/targets/nv14/lcd_driver.h b/radio/src/targets/nv14/lcd_driver.h index f8ac5dd1c..bc348984e 100644 --- a/radio/src/targets/nv14/lcd_driver.h +++ b/radio/src/targets/nv14/lcd_driver.h @@ -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 ) diff --git a/radio/src/targets/nv14/libopenui_config.h b/radio/src/targets/nv14/libopenui_config.h index 39021fb17..338b10055 100644 --- a/radio/src/targets/nv14/libopenui_config.h +++ b/radio/src/targets/nv14/libopenui_config.h @@ -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, diff --git a/radio/src/targets/nv14/pwr_driver.cpp b/radio/src/targets/nv14/pwr_driver.cpp index 522b536e6..b78cf7f3f 100644 --- a/radio/src/targets/nv14/pwr_driver.cpp +++ b/radio/src/targets/nv14/pwr_driver.cpp @@ -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; } } diff --git a/radio/src/targets/nv14/stm32_ramboot.ld b/radio/src/targets/nv14/stm32_ramboot.ld index 8b85c4005..b15c1aa04 100644 --- a/radio/src/targets/nv14/stm32_ramboot.ld +++ b/radio/src/targets/nv14/stm32_ramboot.ld @@ -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) : diff --git a/radio/src/targets/nv14/stm32f4_flash.ld b/radio/src/targets/nv14/stm32f4_flash.ld index 069d9d855..ac5c7ef74 100644 --- a/radio/src/targets/nv14/stm32f4_flash.ld +++ b/radio/src/targets/nv14/stm32f4_flash.ld @@ -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) : diff --git a/radio/src/targets/nv14/stm32f4_flash_bootloader.ld b/radio/src/targets/nv14/stm32f4_flash_bootloader.ld index 7892fe6dd..f27df4011 100644 --- a/radio/src/targets/nv14/stm32f4_flash_bootloader.ld +++ b/radio/src/targets/nv14/stm32f4_flash_bootloader.ld @@ -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) : diff --git a/radio/src/targets/nv14/trainer_driver.cpp b/radio/src/targets/nv14/trainer_driver.cpp index 7cb9b6757..2554b7259 100644 --- a/radio/src/targets/nv14/trainer_driver.cpp +++ b/radio/src/targets/nv14/trainer_driver.cpp @@ -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 diff --git a/radio/src/telemetry/flysky_nv14.cpp b/radio/src/telemetry/flysky_nv14.cpp new file mode 100644 index 000000000..5f75142a9 --- /dev/null +++ b/radio/src/telemetry/flysky_nv14.cpp @@ -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(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; +} + diff --git a/radio/src/telemetry/flysky_nv14.h b/radio/src/telemetry/flysky_nv14.h new file mode 100644 index 000000000..f338e5e3e --- /dev/null +++ b/radio/src/telemetry/flysky_nv14.h @@ -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 diff --git a/radio/src/trainer.cpp b/radio/src/trainer.cpp index d9e3f4a10..ddc69501f 100644 --- a/radio/src/trainer.cpp +++ b/radio/src/trainer.cpp @@ -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() { diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index f52354f4b..7fa789049 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -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; diff --git a/radio/src/translations.h b/radio/src/translations.h index ad2c9c66d..050827def 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -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[]; diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index 1d183accf..509c1efef 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -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 "内存不足" diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 5ce4e76d3..1ab2b72c5 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -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'" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 000b72c67..6c6ef7bbe 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -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" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index cc7438bae..a8159227d 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -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" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index bcf6504cb..ea5e9baa2 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -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" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index c4bf440a7..846ae55ee 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -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" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index ec90befaf..1d1c240cc 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -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" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 9ddfdd5ec..e96101a13 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -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") diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 1cd5ccbb2..0c64368bc 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -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" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 33cc0b5ed..01b7f3961 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -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ęć" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 270b493a1..255224f75 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -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" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index f07adefdf..e9b29a8d3 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -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"