feat(radio): Senduwing H17 support (#7764)
Co-authored-by: 3djc <3djc@gh.com> Co-authored-by: Risto <rotorman@users.noreply.github.com>
This commit is contained in:
@@ -143,6 +143,7 @@ body:
|
||||
- RadioMaster TX16S / TX16S Mark II
|
||||
- RadioMaster TX16S MK3
|
||||
- RadioMaster Zorro
|
||||
- Senduwing H17
|
||||
- Other (Please specify below)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -50,6 +50,7 @@ jobs:
|
||||
- t22
|
||||
- c14
|
||||
- v12
|
||||
- h17
|
||||
container:
|
||||
image: ghcr.io/edgetx/edgetx-dev:latest
|
||||
volumes:
|
||||
@@ -98,6 +99,7 @@ jobs:
|
||||
- t22
|
||||
- c14
|
||||
- v12
|
||||
- h17
|
||||
container:
|
||||
image: ghcr.io/edgetx/edgetx-dev:latest
|
||||
volumes:
|
||||
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
- id: color-4
|
||||
target: [nb4p, st16, pa01, c14]
|
||||
- id: color-5
|
||||
target: [t15pro, tx16smk3, gx15]
|
||||
target: [t15pro, tx16smk3, gx15, h17]
|
||||
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
|
||||
@@ -41,6 +41,7 @@ jobs:
|
||||
- tx15;gx15
|
||||
- t15pro
|
||||
- v12
|
||||
- h17
|
||||
container:
|
||||
image: ghcr.io/edgetx/edgetx-dev:latest
|
||||
volumes:
|
||||
|
||||
@@ -177,7 +177,7 @@ jobs:
|
||||
> If you are using a STM32 F2 based radio, *stop right now*, this release is not for you! EdgeTX v2.11 is the last release series to support these radios. Check [this list](https://hackmd.io/@edgetx/B12oQyQKye) if you are unsure if this affects you. Because of this, EdgeTX v2.11 will continue to be supported alongside 2.12, 3.0, etc., with a focus on bug fixes.
|
||||
|
||||
> [!WARNING]
|
||||
> Radios based on STM32H7 MCUs update differently to older radios. Do **not** use the "Flash via USB" option in EdgeTX Buddy with them (yet). To update radios such as the Flysky PA01 & ST16, Jumper T15 Pro, RM TX15, RM GX15 and RM TX16S MK3, please follow the instructions in the [EdgeTX Manual](https://manual.edgetx.org/installing-and-updating-edgetx/updating-your-stm32h7-radio).
|
||||
> Radios based on STM32H7 MCUs update differently to older radios. Do **not** use the "Flash via USB" option in EdgeTX Buddy with them (yet). To update radios such as the Flysky PA01 & ST16, Jumper T15 Pro, RM TX15, RM GX15, RM TX16S MK3 and Senduwing H17, please follow the instructions in the [EdgeTX Manual](https://manual.edgetx.org/installing-and-updating-edgetx/updating-your-stm32h7-radio).
|
||||
|
||||
> [!NOTE]
|
||||
> For MacOS users, Companion is now only compiled for MacOS 12 and above. Stay with v2.10.5 or earlier if you need support for an older version of MacOS.
|
||||
|
||||
@@ -339,6 +339,12 @@
|
||||
"displayName": "RadioMaster Zorro",
|
||||
"inherits": "firmware",
|
||||
"cacheVariables": { "PCB": "X7", "PCBREV": "ZORRO" }
|
||||
},
|
||||
{
|
||||
"name": "h17",
|
||||
"displayName": "Senduwing H17",
|
||||
"inherits": "firmware",
|
||||
"cacheVariables": { "PCB": "H17" }
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
|
||||
@@ -92,9 +92,11 @@ void BoardJson::afterLoadFixups(Board::Type board, InputsTable * inputs, Switche
|
||||
{
|
||||
// TODO json files do not contain gyro defs
|
||||
// Radio cmake directive IMU is currently used
|
||||
if (IS_TARANIS_XLITES(board) || IS_FAMILY_HORUS_OR_T16(board) ||
|
||||
IS_RADIOMASTER_TX15(board) || IS_RADIOMASTER_GX15(board) ||
|
||||
IS_RADIOMASTER_TX16SMK3(board) || IS_FLYSKY_PA01(board)) {
|
||||
// H17 has no IMU
|
||||
if ((IS_TARANIS_XLITES(board) || IS_FAMILY_HORUS_OR_T16(board) ||
|
||||
IS_RADIOMASTER_TX15(board) || IS_RADIOMASTER_GX15(board) ||
|
||||
IS_RADIOMASTER_TX16SMK3(board) || IS_FLYSKY_PA01(board)) &&
|
||||
!IS_SENDUWING_H17(board)) {
|
||||
if (getInputIndex(inputs, "TILT_X", Board::LVT_TAG) < 0) {
|
||||
InputDefn defn;
|
||||
defn.type = AIT_FLEX;
|
||||
|
||||
@@ -173,6 +173,8 @@ uint32_t Boards::getFourCC(Type board)
|
||||
return 0x4F78746F;
|
||||
case BOARD_HELLORADIOSKY_V16:
|
||||
return 0x4E78746F;
|
||||
case BOARD_SENDUWING_H17:
|
||||
return 0x5078746F;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -237,6 +239,7 @@ int Boards::getEEpromSize(Board::Type board)
|
||||
case BOARD_FLYSKY_NB4P:
|
||||
case BOARD_FLYSKY_ST16:
|
||||
case BOARD_IFLIGHT_COMMANDO14:
|
||||
case BOARD_SENDUWING_H17:
|
||||
case BOARD_FATFISH_F16:
|
||||
case BOARD_HELLORADIOSKY_V12:
|
||||
case BOARD_HELLORADIOSKY_V16:
|
||||
@@ -305,6 +308,7 @@ int Boards::getFlashSize(Type board)
|
||||
case BOARD_FLYSKY_NB4P:
|
||||
case BOARD_FLYSKY_ST16: // 8MB SDRAM
|
||||
case BOARD_IFLIGHT_COMMANDO14: // 8MB SDRAM
|
||||
case BOARD_SENDUWING_H17: // 8MB SDRAM
|
||||
case BOARD_FATFISH_F16:
|
||||
case BOARD_HELLORADIOSKY_V12: // 8MB SDRAM
|
||||
case BOARD_HELLORADIOSKY_V16:
|
||||
@@ -425,7 +429,8 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
IS_RADIOMASTER_ZORRO(board) || IS_RADIOMASTER_TX15(board) ||
|
||||
IS_JUMPER_T15PRO(board) || IS_FLYSKY_PA01(board) ||
|
||||
IS_FLYSKY_ST16(board) || IS_RADIOMASTER_TX16SMK3(board) ||
|
||||
IS_IFLIGHT_C14(board) || IS_RADIOMASTER_GX15(board));
|
||||
IS_IFLIGHT_C14(board) || IS_RADIOMASTER_GX15(board) ||
|
||||
IS_SENDUWING_H17(board));
|
||||
|
||||
default:
|
||||
return getBoardJson(board)->getCapability(capability);
|
||||
@@ -691,6 +696,8 @@ QString Boards::getBoardName(Board::Type board)
|
||||
return "iFlight Commando 8";
|
||||
case BOARD_IFLIGHT_COMMANDO14:
|
||||
return "iFlight Commando 14";
|
||||
case BOARD_SENDUWING_H17:
|
||||
return "Senduwing H17";
|
||||
case BOARD_FATFISH_F16:
|
||||
return "Fatfish F16";
|
||||
case BOARD_HELLORADIOSKY_V16:
|
||||
@@ -815,6 +822,7 @@ int Boards::getDefaultInternalModules(Board::Type board)
|
||||
case BOARD_RADIOMASTER_TX16SMK3:
|
||||
case BOARD_IFLIGHT_COMMANDO8:
|
||||
case BOARD_IFLIGHT_COMMANDO14:
|
||||
case BOARD_SENDUWING_H17:
|
||||
case BOARD_JUMPER_BUMBLEBEE:
|
||||
case BOARD_JUMPER_T12MAX:
|
||||
case BOARD_JUMPER_T14:
|
||||
@@ -914,6 +922,9 @@ void Boards::getBattRange(Board::Type board, int& vmin, int& vmax, unsigned int&
|
||||
case BOARD_FLYSKY_PA01:
|
||||
BR(70, 86, 80)
|
||||
break;
|
||||
case BOARD_SENDUWING_H17:
|
||||
BR(70, 86, 74)
|
||||
break;
|
||||
case BOARD_IFLIGHT_COMMANDO8:
|
||||
BR(30, 42, 32)
|
||||
break;
|
||||
|
||||
@@ -102,6 +102,7 @@ namespace Board {
|
||||
BOARD_HELLORADIOSKY_V14LCD,
|
||||
BOARD_IFLIGHT_COMMANDO14,
|
||||
BOARD_HELLORADIOSKY_V12,
|
||||
BOARD_SENDUWING_H17,
|
||||
BOARD_TYPE_COUNT,
|
||||
BOARD_TYPE_MAX = BOARD_TYPE_COUNT - 1
|
||||
};
|
||||
@@ -772,6 +773,11 @@ inline bool IS_IFLIGHT_C14(Board::Type board)
|
||||
return (board == Board::BOARD_IFLIGHT_COMMANDO14);
|
||||
}
|
||||
|
||||
inline bool IS_SENDUWING_H17(Board::Type board)
|
||||
{
|
||||
return (board == Board::BOARD_SENDUWING_H17);
|
||||
}
|
||||
|
||||
inline bool IS_FAMILY_PL18(Board::Type board)
|
||||
{
|
||||
return IS_FLYSKY_PL18(board) || IS_FLYSKY_PL18EV(board) || IS_FLYSKY_PL18U(board);
|
||||
@@ -858,7 +864,7 @@ inline bool IS_FAMILY_HORUS_OR_T16(Board::Type board)
|
||||
IS_FLYSKY_NV14(board)/*generally*/ || IS_FLYSKY_EL18(board)/*generally*/
|
||||
|| IS_FAMILY_PL18(board) || IS_FLYSKY_ST16(board)/*generally*/ ||
|
||||
IS_FLYSKY_PA01(board)/*generally*/ || IS_FLYSKY_NB4P(board)/*generally*/ ||
|
||||
IS_IFLIGHT_C14(board)/*generally*/;
|
||||
IS_IFLIGHT_C14(board)/*generally*/ || IS_SENDUWING_H17(board)/*generally*/;
|
||||
}
|
||||
|
||||
inline bool HAS_LARGE_LCD(Board::Type board)
|
||||
|
||||
@@ -93,7 +93,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
return id.contains("internalelrs") || IS_RADIOMASTER_TX12_MK2(board) ||
|
||||
IS_IFLIGHT_COMMANDO8(board) || IS_RADIOMASTER_BOXER(board) ||
|
||||
IS_RADIOMASTER_POCKET(board) || IS_JUMPER_T20(board) ||
|
||||
IS_RADIOMASTER_MT12(board) || IS_RADIOMASTER_TX15(board) || IS_RADIOMASTER_GX15(board) || IS_JUMPER_T15PRO(board) || IS_JUMPER_T22(board);
|
||||
IS_RADIOMASTER_MT12(board) || IS_RADIOMASTER_TX15(board) || IS_RADIOMASTER_GX15(board) || IS_JUMPER_T15PRO(board) || IS_JUMPER_T22(board) ||
|
||||
IS_SENDUWING_H17(board);
|
||||
case HasIntModuleFlySky:
|
||||
return id.contains("afhds2a") || id.contains("afhds3") ||
|
||||
IS_FLYSKY_NV14(board) || IS_FLYSKY_EL18(board) || IS_FAMILY_PL18(board);
|
||||
@@ -768,6 +769,12 @@ void registerOpenTxFirmwares()
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS2A + AFHDS3);
|
||||
|
||||
/* Senduwing H17 board */
|
||||
firmware = new OpenTxFirmware(FIRMWAREID("h17"), Firmware::tr("Senduwing H17"), BOARD_SENDUWING_H17);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
Firmware::sortRegisteredFirmwares();
|
||||
Firmware::setDefaultVariant(Firmware::getFirmwareForFlavour("tx16s"));
|
||||
Firmware::setCurrentVariant(Firmware::getDefaultVariant());
|
||||
|
||||
@@ -28,6 +28,7 @@ Selects the radio target.
|
||||
| `T15PRO` | Jumper T15 Pro |
|
||||
| `ST16` | Siyi ST16 |
|
||||
| `PA01` | FrSky PA01 |
|
||||
| `H17` | Senduwing H17 |
|
||||
|
||||
### `PCBREV`
|
||||
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
["RadioMaster TX15", "tx15-"],
|
||||
["RadioMaster TX16S / TX16S Mark II", "tx16s-"],
|
||||
["RadioMaster TX16S MK3", "tx16smk3-"],
|
||||
["RadioMaster Zorro","zorro-"]
|
||||
["RadioMaster Zorro","zorro-"],
|
||||
["Senduwing H17", "h17-"]
|
||||
],
|
||||
"changelog": "- Major initial bug fixes"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
include(CMakeForceCompiler)
|
||||
include(Bitmaps)
|
||||
|
||||
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S PL18 T15PRO ST16 PA01 TX15 GX15 TX16SMK3 T22 V12)
|
||||
set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S PL18 T15PRO ST16 PA01 TX15 GX15 TX16SMK3 T22 V12 H17)
|
||||
set(RADIO_LANGUAGES CN CZ DA DE EN ES FI FR HE HU IT JP KO NL PL PT RU SE SK TW UA)
|
||||
set(TTS_LANGUAGES CN CZ DA DE EN ES FI FR HE HU IT JP KO NL PL PT RU SE SK TW UA)
|
||||
|
||||
@@ -107,6 +107,8 @@ elseif(PCB STREQUAL GX15)
|
||||
include(targets/gx15/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL TX16SMK3)
|
||||
include(targets/tx16smk3/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL H17)
|
||||
include(targets/h17/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL T22)
|
||||
include(targets/t22/CMakeLists.txt)
|
||||
elseif(PCB STREQUAL STM32H7S78_DK)
|
||||
|
||||
@@ -0,0 +1,476 @@
|
||||
{
|
||||
"adc_inputs": {
|
||||
"adcs": [
|
||||
{
|
||||
"name": "MAIN",
|
||||
"adc": "ADC1",
|
||||
"dma": "DMA2",
|
||||
"dma_channel": "LL_DMAMUX1_REQ_ADC1",
|
||||
"dma_stream": "LL_DMA_STREAM_4",
|
||||
"dma_stream_irq": "DMA2_Stream4_IRQn",
|
||||
"dma_stream_irq_handler": "DMA2_Stream4_IRQHandler",
|
||||
"sample_time": "LL_ADC_SAMPLINGTIME_8CYCLES_5"
|
||||
},
|
||||
{
|
||||
"name": "EXT",
|
||||
"adc": "ADC3",
|
||||
"dma": "DMA2",
|
||||
"dma_channel": "LL_DMAMUX1_REQ_ADC3",
|
||||
"dma_stream": "LL_DMA_STREAM_0",
|
||||
"dma_stream_irq": "DMA2_Stream0_IRQn",
|
||||
"dma_stream_irq_handler": "DMA2_Stream0_IRQHandler",
|
||||
"sample_time": "LL_ADC_SAMPLINGTIME_8CYCLES_5"
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"name": "LH",
|
||||
"type": "STICK",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOA",
|
||||
"pin": "LL_GPIO_PIN_6",
|
||||
"channel": "LL_ADC_CHANNEL_3",
|
||||
"inverted": true
|
||||
},
|
||||
{
|
||||
"name": "LV",
|
||||
"type": "STICK",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_3",
|
||||
"channel": "LL_ADC_CHANNEL_13",
|
||||
"inverted": true
|
||||
},
|
||||
{
|
||||
"name": "RV",
|
||||
"type": "STICK",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_4",
|
||||
"channel": "LL_ADC_CHANNEL_4"
|
||||
},
|
||||
{
|
||||
"name": "RH",
|
||||
"type": "STICK",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_5",
|
||||
"channel": "LL_ADC_CHANNEL_8",
|
||||
"inverted": true
|
||||
},
|
||||
{
|
||||
"name": "P1",
|
||||
"type": "FLEX",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_1",
|
||||
"channel": "LL_ADC_CHANNEL_11",
|
||||
"label": "S1",
|
||||
"short_label": "1",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "SL1",
|
||||
"type": "FLEX",
|
||||
"adc": "EXT",
|
||||
"gpio": "GPIOH",
|
||||
"pin": "LL_GPIO_PIN_2",
|
||||
"channel": "LL_ADC_CHANNEL_13",
|
||||
"label": "S2",
|
||||
"short_label": "2",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "SL2",
|
||||
"type": "FLEX",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOA",
|
||||
"pin": "LL_GPIO_PIN_7",
|
||||
"channel": "LL_ADC_CHANNEL_7",
|
||||
"label": "S3",
|
||||
"short_label": "3",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "P3",
|
||||
"type": "FLEX",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOB",
|
||||
"pin": "LL_GPIO_PIN_1",
|
||||
"channel": "LL_ADC_CHANNEL_5",
|
||||
"label": "S4",
|
||||
"short_label": "4",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "P2",
|
||||
"type": "FLEX",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_2",
|
||||
"channel": "LL_ADC_CHANNEL_12",
|
||||
"default": "MULTIPOS",
|
||||
"label": "6POS",
|
||||
"short_label": "6"
|
||||
},
|
||||
{
|
||||
"name": "EXT1",
|
||||
"type": "FLEX",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOA",
|
||||
"pin": "LL_GPIO_PIN_1",
|
||||
"channel": "LL_ADC_CHANNEL_17",
|
||||
"default": "NONE",
|
||||
"label": "EXT1",
|
||||
"short_label": "E1"
|
||||
},
|
||||
{
|
||||
"name": "EXT2",
|
||||
"type": "FLEX",
|
||||
"adc": "MAIN",
|
||||
"gpio": "GPIOA",
|
||||
"pin": "LL_GPIO_PIN_0",
|
||||
"channel": "LL_ADC_CHANNEL_16",
|
||||
"default": "NONE",
|
||||
"label": "EXT2",
|
||||
"short_label": "E2"
|
||||
},
|
||||
{
|
||||
"name": "VBAT",
|
||||
"type": "VBAT",
|
||||
"adc": "EXT",
|
||||
"gpio": "GPIOH",
|
||||
"pin": "LL_GPIO_PIN_3",
|
||||
"channel": "LL_ADC_CHANNEL_14"
|
||||
},
|
||||
{
|
||||
"name": "RTC_BAT",
|
||||
"type": "RTC_BAT",
|
||||
"adc": "EXT",
|
||||
"gpio": null,
|
||||
"pin": null,
|
||||
"channel": "LL_ADC_CHANNEL_VBAT"
|
||||
}
|
||||
]
|
||||
},
|
||||
"switches": [
|
||||
{
|
||||
"name": "SA",
|
||||
"type": "3POS",
|
||||
"flags": 0,
|
||||
"inverted": true,
|
||||
"default": "2POS",
|
||||
"display": null,
|
||||
"gpio_high": "GPIOB",
|
||||
"pin_high": "LL_GPIO_PIN_0",
|
||||
"gpio_low": "GPIOE",
|
||||
"pin_low": "LL_GPIO_PIN_4",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SB",
|
||||
"type": "3POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "3POS",
|
||||
"display": null,
|
||||
"gpio_high": "GPIOD",
|
||||
"pin_high": "LL_GPIO_PIN_5",
|
||||
"gpio_low": "GPIOJ",
|
||||
"pin_low": "LL_GPIO_PIN_7",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SC",
|
||||
"type": "3POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "3POS",
|
||||
"display": null,
|
||||
"gpio_high": "GPIOD",
|
||||
"pin_high": "LL_GPIO_PIN_3",
|
||||
"gpio_low": "GPIOJ",
|
||||
"pin_low": "LL_GPIO_PIN_0",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SD",
|
||||
"type": "3POS",
|
||||
"flags": 0,
|
||||
"inverted": true,
|
||||
"default": "2POS",
|
||||
"display": null,
|
||||
"gpio_high": "GPIOD",
|
||||
"pin_high": "LL_GPIO_PIN_11",
|
||||
"gpio_low": "GPIOH",
|
||||
"pin_low": "LL_GPIO_PIN_15",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SE",
|
||||
"type": "3POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "3POS",
|
||||
"display": null,
|
||||
"gpio_high": "GPIOE",
|
||||
"pin_high": "LL_GPIO_PIN_6",
|
||||
"gpio_low": "GPIOE",
|
||||
"pin_low": "LL_GPIO_PIN_5",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SF",
|
||||
"type": "2POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "2POS",
|
||||
"display": null,
|
||||
"gpio": "GPIOB",
|
||||
"pin": "LL_GPIO_PIN_8",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SG",
|
||||
"type": "2POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "TOGGLE",
|
||||
"display": null,
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_6",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SH",
|
||||
"type": "2POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "TOGGLE",
|
||||
"display": null,
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_8",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SI",
|
||||
"type": "2POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "2POS",
|
||||
"display": null,
|
||||
"gpio": "GPIOH",
|
||||
"pin": "LL_GPIO_PIN_14",
|
||||
"is_cfs": false
|
||||
},
|
||||
{
|
||||
"name": "SJ",
|
||||
"type": "2POS",
|
||||
"flags": 0,
|
||||
"inverted": false,
|
||||
"default": "2POS",
|
||||
"display": null,
|
||||
"gpio": "GPIOH",
|
||||
"pin": "LL_GPIO_PIN_13",
|
||||
"is_cfs": false
|
||||
}
|
||||
],
|
||||
"keys": [
|
||||
{
|
||||
"gpio": "GPIOG",
|
||||
"pin": "LL_GPIO_PIN_3",
|
||||
"active_low": true,
|
||||
"key": "KEY_EXIT",
|
||||
"name": "EXIT",
|
||||
"label": "RTN"
|
||||
},
|
||||
{
|
||||
"gpio": "GPIOG",
|
||||
"pin": "LL_GPIO_PIN_12",
|
||||
"active_low": true,
|
||||
"key": "KEY_ENTER",
|
||||
"name": "ENTER",
|
||||
"label": "Enter"
|
||||
},
|
||||
{
|
||||
"gpio": "GPIOG",
|
||||
"pin": "LL_GPIO_PIN_7",
|
||||
"active_low": true,
|
||||
"key": "KEY_PAGEUP",
|
||||
"name": "PAGEUP",
|
||||
"label": "PAGE<"
|
||||
},
|
||||
{
|
||||
"gpio": "GPIOA",
|
||||
"pin": "LL_GPIO_PIN_8",
|
||||
"active_low": true,
|
||||
"key": "KEY_PAGEDN",
|
||||
"name": "PAGEDN",
|
||||
"label": "PAGE>"
|
||||
},
|
||||
{
|
||||
"gpio": "GPIOE",
|
||||
"pin": "LL_GPIO_PIN_3",
|
||||
"active_low": true,
|
||||
"key": "KEY_MODEL",
|
||||
"name": "MDL",
|
||||
"label": "MDL"
|
||||
},
|
||||
{
|
||||
"gpio": "GPIOI",
|
||||
"pin": "LL_GPIO_PIN_15",
|
||||
"active_low": true,
|
||||
"key": "KEY_TELE",
|
||||
"name": "TELE",
|
||||
"label": "TELE"
|
||||
},
|
||||
{
|
||||
"gpio": "GPIOB",
|
||||
"pin": "LL_GPIO_PIN_2",
|
||||
"active_low": true,
|
||||
"key": "KEY_SYS",
|
||||
"name": "SYS",
|
||||
"label": "SYS"
|
||||
}
|
||||
],
|
||||
"trims": [
|
||||
{
|
||||
"name": "T1",
|
||||
"dec": {
|
||||
"gpio": "GPIOG",
|
||||
"pin": "LL_GPIO_PIN_2",
|
||||
"active_low": true
|
||||
},
|
||||
"inc": {
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_9",
|
||||
"active_low": true
|
||||
},
|
||||
"active_low": true
|
||||
},
|
||||
{
|
||||
"name": "T2",
|
||||
"dec": {
|
||||
"gpio": "GPIOB",
|
||||
"pin": "LL_GPIO_PIN_12",
|
||||
"active_low": true
|
||||
},
|
||||
"inc": {
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_10",
|
||||
"active_low": true
|
||||
},
|
||||
"active_low": true
|
||||
},
|
||||
{
|
||||
"name": "T3",
|
||||
"dec": {
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_12",
|
||||
"active_low": true
|
||||
},
|
||||
"inc": {
|
||||
"gpio": "GPIOC",
|
||||
"pin": "LL_GPIO_PIN_11",
|
||||
"active_low": true
|
||||
},
|
||||
"active_low": true
|
||||
},
|
||||
{
|
||||
"name": "T4",
|
||||
"dec": {
|
||||
"gpio": "GPIOD",
|
||||
"pin": "LL_GPIO_PIN_2",
|
||||
"active_low": true
|
||||
},
|
||||
"inc": {
|
||||
"gpio": "GPIOI",
|
||||
"pin": "LL_GPIO_PIN_9",
|
||||
"active_low": true
|
||||
},
|
||||
"active_low": true
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"lcd_w": 480,
|
||||
"lcd_h": 272,
|
||||
"lcd_phys_w": 480,
|
||||
"lcd_phys_h": 272,
|
||||
"lcd_depth": 16,
|
||||
"oled_screen": false,
|
||||
"lcd_vertical_invert": true,
|
||||
"ltdc_irq_prio": 4,
|
||||
"dma_screen_irq_prio": 6
|
||||
},
|
||||
"backlight": {
|
||||
"backlight_gpio": "GPIO_PIN(GPIOA, 10)",
|
||||
"backlight_timer": "TIM1",
|
||||
"backlight_timer_channel": "LL_TIM_CHANNEL_CH3",
|
||||
"backlight_gpio_af": "GPIO_AF1",
|
||||
"backlight_timer_freq": "(PERI2_FREQUENCY * TIMER_MULT_APB2)"
|
||||
},
|
||||
"haptic": {
|
||||
"haptic_pwm": true,
|
||||
"haptic_gpio": "GPIO_PIN(GPIOC, 7)",
|
||||
"haptic_gpio_timer": "TIM3",
|
||||
"haptic_gpio_af": "GPIO_AF2",
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E | TIM_CCER_CC2NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
},
|
||||
"leds": {
|
||||
"status_leds": true,
|
||||
"gpio_led_gpio_on": "gpio_set",
|
||||
"gpio_led_gpio_off": "gpio_clear",
|
||||
"led_red_gpio": "GPIO_PIN(GPIOI, 8)",
|
||||
"led_green_gpio": "GPIO_PIN(GPIOI, 11)",
|
||||
"led_blue_gpio": "GPIO_PIN(GPIOI, 10)"
|
||||
},
|
||||
"timers": {
|
||||
"cpu_freq": 480000000,
|
||||
"peri1_frequency": 120000000,
|
||||
"peri2_frequency": 120000000,
|
||||
"timer_mult_apb1": 2,
|
||||
"timer_mult_apb2": 2,
|
||||
"ms_timer": "TIM14",
|
||||
"ms_timer_irqn": "TIM8_TRG_COM_TIM14_IRQn",
|
||||
"ms_timer_irqhandler": "TIM8_TRG_COM_TIM14_IRQHandler",
|
||||
"mixer_scheduler_timer": "TIM12",
|
||||
"mixer_scheduler_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)",
|
||||
"mixer_scheduler_timer_irqn": "TIM8_BRK_TIM12_IRQn",
|
||||
"mixer_scheduler_timer_irqhandler": "TIM8_BRK_TIM12_IRQHandler"
|
||||
},
|
||||
"rotenc": {
|
||||
"rotary_encoder_inverted": true,
|
||||
"rotary_encoder_gpio_a": "GPIOI",
|
||||
"rotary_encoder_gpio_pin_a": "LL_GPIO_PIN_7",
|
||||
"rotary_encoder_gpio_b": "GPIOJ",
|
||||
"rotary_encoder_gpio_pin_b": "LL_GPIO_PIN_8",
|
||||
"rotary_encoder_position": "(((ROTARY_ENCODER_GPIO_A->IDR >> 7) & 0x01)|((ROTARY_ENCODER_GPIO_B->IDR >> 7) & 0x02))",
|
||||
"rotary_encoder_exti_line1": "LL_EXTI_LINE_7",
|
||||
"rotary_encoder_exti_line2": "LL_EXTI_LINE_8",
|
||||
"exti": [
|
||||
{ "irq": "EXTI9_5_IRQ", "priority": 5 }
|
||||
],
|
||||
"rotary_encoder_exti_port_a": "LL_SYSCFG_EXTI_PORTI",
|
||||
"rotary_encoder_exti_port_b": "LL_SYSCFG_EXTI_PORTJ",
|
||||
"rotary_encoder_exti_sys_line1": "LL_SYSCFG_EXTI_LINE7",
|
||||
"rotary_encoder_exti_sys_line2": "LL_SYSCFG_EXTI_LINE8",
|
||||
"rotary_encoder_timer": "TIM17",
|
||||
"rotary_encoder_timer_irqn": "TIM17_IRQn",
|
||||
"rotary_encoder_timer_irqhandler": "TIM17_IRQHandler"
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
],
|
||||
"hardware": {
|
||||
"has_audio_mute": true,
|
||||
"has_ext_module_support": true,
|
||||
"has_int_module_support": true,
|
||||
"sport_max_baudrate": 400000,
|
||||
"surface": false,
|
||||
"cpu": "STM32H750xB",
|
||||
"cpu_type": "STM32H7"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_timer.h"
|
||||
#include "stm32_pulse_driver.h"
|
||||
|
||||
#include "edgetx_types.h"
|
||||
#include "board.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
static const stm32_pulse_timer_t _bl_timer = {
|
||||
.GPIO = (gpio_t)BACKLIGHT_GPIO,
|
||||
.GPIO_Alternate = BACKLIGHT_GPIO_AF,
|
||||
.TIMx = BACKLIGHT_TIMER,
|
||||
.TIM_Freq = BACKLIGHT_TIMER_FREQ,
|
||||
.TIM_Channel = BACKLIGHT_TIMER_CHANNEL,
|
||||
.TIM_IRQn = (IRQn_Type)-1,
|
||||
.DMAx = nullptr,
|
||||
.DMA_Stream = 0,
|
||||
.DMA_Channel = 0,
|
||||
.DMA_IRQn = (IRQn_Type)-1,
|
||||
.DMA_TC_CallbackPtr = nullptr,
|
||||
};
|
||||
|
||||
void backlightLowInit()
|
||||
{
|
||||
gpio_init(BACKLIGHT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_clear(BACKLIGHT_GPIO);
|
||||
}
|
||||
|
||||
void backlightInit()
|
||||
{
|
||||
stm32_pulse_init(&_bl_timer, 10000);
|
||||
stm32_pulse_config_output(&_bl_timer, true, LL_TIM_OCMODE_PWM1, 100);
|
||||
LL_TIM_SetAutoReload(_bl_timer.TIMx, 100);
|
||||
LL_TIM_EnableCounter(_bl_timer.TIMx);
|
||||
}
|
||||
|
||||
void backlightEnable(uint8_t dutyCycle)
|
||||
{
|
||||
stm32_pulse_set_cmp_val(&_bl_timer, dutyCycle);
|
||||
}
|
||||
|
||||
void lcdOff() {
|
||||
backlightEnable(0);
|
||||
}
|
||||
|
||||
void lcdOn(){
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX);
|
||||
}
|
||||
|
||||
bool boardBacklightOn;
|
||||
|
||||
bool isBacklightEnabled()
|
||||
{
|
||||
return boardBacklightOn;
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "stm32_adc.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_spi.h"
|
||||
|
||||
#include "flash_driver.h"
|
||||
#include "extflash_driver.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "boards/generic_stm32/module_ports.h"
|
||||
|
||||
#include "hal/adc_driver.h"
|
||||
#include "hal/flash_driver.h"
|
||||
#include "hal/trainer_driver.h"
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/abnormal_reboot.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
#include "hal/usb_driver.h"
|
||||
#include "hal/gpio.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "sdcard.h"
|
||||
#include "debug.h"
|
||||
#include "keys.h"
|
||||
#include "gyro.h"
|
||||
|
||||
#include "flysky_gimbal_driver.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#include "touch_driver.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// common ADC driver
|
||||
extern const etx_hal_adc_driver_t _adc_driver;
|
||||
|
||||
void INTERNAL_MODULE_ON()
|
||||
{
|
||||
gpio_set(INTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void INTERNAL_MODULE_OFF()
|
||||
{
|
||||
gpio_clear(INTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void EXTERNAL_MODULE_ON()
|
||||
{
|
||||
gpio_set(EXTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void EXTERNAL_MODULE_OFF()
|
||||
{
|
||||
gpio_clear(EXTMODULE_PWR_GPIO);
|
||||
}
|
||||
|
||||
void boardBLEarlyInit()
|
||||
{
|
||||
timersInit();
|
||||
#if defined(USB_CHARGER)
|
||||
usbChargerInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void boardBLPreJump()
|
||||
{
|
||||
ExtFLASH_Init();
|
||||
SDRAM_Init();
|
||||
|
||||
// Stop 1ms timer
|
||||
MS_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void boardBLInit()
|
||||
{
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
rotaryEncoderInit();
|
||||
#endif
|
||||
|
||||
ExtFLASH_Init();
|
||||
SDRAM_Init();
|
||||
|
||||
// register external FLASH for DFU
|
||||
usbRegisterDFUMedia((void*)extflash_dfu_media);
|
||||
|
||||
// register internal & external FLASH for UF2
|
||||
flashRegisterDriver(FLASH_BANK1_BASE, BOOTLOADER_SIZE, &stm32_flash_driver);
|
||||
flashRegisterDriver(QSPI_BASE, 8 * 1024 * 1024, &extflash_driver);
|
||||
}
|
||||
|
||||
void boardInit()
|
||||
{
|
||||
// enable interrupts
|
||||
__enable_irq();
|
||||
|
||||
ledInit();
|
||||
boardInitModulePorts();
|
||||
|
||||
pwrInit();
|
||||
delaysInit();
|
||||
timersInit();
|
||||
|
||||
#if !defined(POWER_LED_BLUE)
|
||||
ledBlue();
|
||||
#else
|
||||
ledGreen();
|
||||
#endif
|
||||
|
||||
ExtFLASH_InitRuntime();
|
||||
|
||||
// register internal & external FLASH for UF2
|
||||
flashRegisterDriver(FLASH_BANK1_BASE, BOOTLOADER_SIZE, &stm32_flash_driver);
|
||||
flashRegisterDriver(QSPI_BASE, QSPI_FLASH_SIZE, &extflash_driver);
|
||||
|
||||
#if defined(FLYSKY_GIMBAL)
|
||||
auto inittime = flysky_gimbal_init();
|
||||
if (inittime)
|
||||
TRACE("Serial gimbal detected in %d ms", inittime);
|
||||
else
|
||||
TRACE("No serial gimbal detected");
|
||||
#endif
|
||||
|
||||
usbInit();
|
||||
|
||||
#if !defined(DEBUG_SEGGER_RTT)
|
||||
// This is needed to prevent radio from starting when usb is plugged to charge
|
||||
if (!UNEXPECTED_SHUTDOWN() && usbPlugged()) {
|
||||
while (usbPlugged() && !pwrPressed()) {
|
||||
delay_ms(1000);
|
||||
}
|
||||
if (!pwrPressed()) {
|
||||
pwrOff();
|
||||
// Wait power to drain
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
keysInit();
|
||||
switchInit();
|
||||
rotaryEncoderInit();
|
||||
touchPanelInit();
|
||||
audioInit();
|
||||
adcInit(&_adc_driver);
|
||||
hapticInit();
|
||||
|
||||
rtcInit(); // RTC must be initialized before rambackupRestore() is called
|
||||
}
|
||||
|
||||
extern void rtcDisableBackupReg();
|
||||
|
||||
void boardOff()
|
||||
{
|
||||
lcdOff();
|
||||
|
||||
while (pwrPressed()) {
|
||||
WDG_RESET();
|
||||
}
|
||||
|
||||
SysTick->CTRL = 0; // turn off systick
|
||||
|
||||
// Shutdown the Haptic
|
||||
hapticDone();
|
||||
|
||||
rtcDisableBackupReg();
|
||||
|
||||
pwrOff();
|
||||
|
||||
// We reach here only in forced power situations, such as hw-debugging with external power
|
||||
// Enter STM32 stop mode / deep-sleep
|
||||
// Code snippet from ST Nucleo PWR_EnterStopMode example
|
||||
#define PDMode 0x00000000U
|
||||
#if defined(PWR_CR1_MRUDS) && defined(PWR_CR1_LPUDS) && defined(PWR_CR1_FPDS)
|
||||
MODIFY_REG(PWR->CR1, (PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_FPDS | PWR_CR1_LPUDS | PWR_CR1_MRUDS), PDMode);
|
||||
#elif defined(PWR_CR_MRLVDS) && defined(PWR_CR_LPLVDS) && defined(PWR_CR_FPDS)
|
||||
MODIFY_REG(PWR->CR1, (PWR_CR1_PDDS | PWR_CR1_LPDS | PWR_CR1_FPDS | PWR_CR1_LPLVDS | PWR_CR1_MRLVDS), PDMode);
|
||||
#else
|
||||
// MODIFY_REG(PWR->CR1, (PWR_CR1_P_PDDS| PWR_CR1_LPDS), PDMode);
|
||||
#endif /* PWR_CR_MRUDS && PWR_CR_LPUDS && PWR_CR_FPDS */
|
||||
|
||||
/* Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
|
||||
// To avoid HardFault at return address, end in an endless loop
|
||||
while (1) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include "definitions.h"
|
||||
#include "edgetx_constants.h"
|
||||
|
||||
#include "board_common.h"
|
||||
#include "hal.h"
|
||||
#include "hal/serial_port.h"
|
||||
#include "hal/watchdog_driver.h"
|
||||
|
||||
#define FLASHSIZE 0x1000000
|
||||
#define BOOTLOADER_SIZE 0x10000
|
||||
#define BOOTLOADER_ADDRESS 0x08000000
|
||||
#define FIRMWARE_ADDRESS 0x90000000
|
||||
#define FIRMWARE_LEN(fsize) (fsize)
|
||||
#define FIRMWARE_MAX_LEN FLASHSIZE
|
||||
#define APP_START_ADDRESS (uint32_t)(FIRMWARE_ADDRESS)
|
||||
|
||||
#define BOOTLOADER_KEYS 0x42
|
||||
|
||||
#define MB *1024*1024
|
||||
#define LUA_MEM_EXTRA_MAX (2 MB) // max allowed memory usage for Lua bitmaps (in bytes)
|
||||
#define LUA_MEM_MAX (6 MB) // max allowed memory usage for complete Lua (in bytes), 0 means unlimited
|
||||
|
||||
extern uint16_t sessionTimer;
|
||||
|
||||
#define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE)
|
||||
|
||||
// Board driver
|
||||
void boardInit();
|
||||
void boardOff();
|
||||
|
||||
// CPU Unique ID
|
||||
#define LEN_CPU_UID (3*8+2)
|
||||
void getCPUUniqueID(char * s);
|
||||
|
||||
// Flash Write driver
|
||||
#define FLASH_PAGESIZE 256
|
||||
void unlockFlash();
|
||||
void lockFlash();
|
||||
void flashWrite(uint32_t * address, const uint32_t * buffer);
|
||||
uint32_t isFirmwareStart(const uint8_t * buffer);
|
||||
uint32_t isBootloaderStart(const uint8_t * buffer);
|
||||
|
||||
// SDRAM driver
|
||||
extern "C" void SDRAM_Init();
|
||||
|
||||
// Pulses driver
|
||||
#if !defined(SIMU)
|
||||
|
||||
void INTERNAL_MODULE_ON();
|
||||
void INTERNAL_MODULE_OFF();
|
||||
void EXTERNAL_MODULE_ON();
|
||||
void EXTERNAL_MODULE_OFF();
|
||||
#define EXTERNAL_MODULE_PWR_OFF EXTERNAL_MODULE_OFF
|
||||
#define BLUETOOTH_MODULE_ON() gpio_clear(BLUETOOTH_ON_GPIO)
|
||||
#define BLUETOOTH_MODULE_OFF() gpio_set(BLUETOOTH_ON_GPIO)
|
||||
#define IS_INTERNAL_MODULE_ON() (false)
|
||||
#define IS_EXTERNAL_MODULE_ON() (gpio_read(EXTMODULE_PWR_GPIO) ? 1 : 0)
|
||||
|
||||
#else
|
||||
|
||||
#define INTERNAL_MODULE_OFF()
|
||||
#define INTERNAL_MODULE_ON()
|
||||
#define EXTERNAL_MODULE_ON()
|
||||
#define EXTERNAL_MODULE_OFF()
|
||||
#define BLUETOOTH_MODULE_ON()
|
||||
#define BLUETOOTH_MODULE_OFF()
|
||||
#define IS_INTERNAL_MODULE_ON() (false)
|
||||
#define IS_EXTERNAL_MODULE_ON() (false)
|
||||
|
||||
#endif // defined(SIMU)
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
#define NUM_FUNCTIONS_SWITCHES 6
|
||||
#define NUM_FUNCTIONS_GROUPS 3
|
||||
#define DEFAULT_FS_CONFIG \
|
||||
(SWITCH_2POS << 10) + (SWITCH_2POS << 8) + (SWITCH_2POS << 6) + \
|
||||
(SWITCH_2POS << 4) + (SWITCH_2POS << 2) + (SWITCH_2POS << 0)
|
||||
|
||||
#define DEFAULT_FS_GROUPS \
|
||||
(1 << 10) + (1 << 8) + (1 << 6) + (1 << 4) + (1 << 2) + \
|
||||
(1 << 0) // Set all FS to group 1 to act like a 6pos
|
||||
|
||||
#define DEFAULT_FS_STARTUP_CONFIG \
|
||||
((FS_START_PREVIOUS << 10) + (FS_START_PREVIOUS << 8) + \
|
||||
(FS_START_PREVIOUS << 6) + (FS_START_PREVIOUS << 4) + \
|
||||
(FS_START_PREVIOUS << 2) + \
|
||||
(FS_START_PREVIOUS << 0)) // keep last state by default
|
||||
|
||||
#else
|
||||
#define NUM_FUNCTIONS_SWITCHES 0
|
||||
#endif
|
||||
|
||||
#define NUM_TRIMS 8
|
||||
#define DEFAULT_STICK_DEADZONE 2
|
||||
|
||||
#define BATTERY_WARN 74 // 7.4V
|
||||
#define BATTERY_MIN 70 // 6.8V
|
||||
#define BATTERY_MAX 86 // 8.6V
|
||||
|
||||
// --- MOSFET ---- R1 --- MCU
|
||||
// |__ R2 --- GND
|
||||
//
|
||||
#define VBAT_DIV_R1 120 // kOhms
|
||||
#define VBAT_DIV_R2 39 // kOhms
|
||||
#define VBAT_MOSFET_DROP 0 // * 10mV
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Power driver
|
||||
#define SOFT_PWR_CTRL
|
||||
#define POWER_ON_DELAY 10 // 1s
|
||||
void pwrInit();
|
||||
void extModuleInit();
|
||||
uint32_t pwrCheck();
|
||||
uint32_t lowPowerCheck();
|
||||
|
||||
void pwrOn();
|
||||
void pwrSoftReboot();
|
||||
void pwrOff();
|
||||
void pwrResetHandler();
|
||||
bool pwrPressed();
|
||||
bool pwrOffPressed();
|
||||
#if defined(PWR_EXTRA_SWITCH_GPIO)
|
||||
bool pwrForcePressed();
|
||||
#else
|
||||
#define pwrForcePressed() false
|
||||
#endif
|
||||
uint32_t pwrPressedDuration();;
|
||||
|
||||
const etx_serial_port_t* auxSerialGetPort(int port_nr);
|
||||
#define AUX_SERIAL_POWER_ON()
|
||||
#define AUX_SERIAL_POWER_OFF()
|
||||
|
||||
// LED driver
|
||||
void ledInit();
|
||||
void ledOff();
|
||||
void ledRed();
|
||||
void ledBlue();
|
||||
void ledGreen();
|
||||
|
||||
// LCD driver
|
||||
void lcdSetInitalFrameBuffer(void* fbAddress);
|
||||
void lcdInit();
|
||||
void lcdCopy(void * dest, void * src);
|
||||
|
||||
void lcdOff();
|
||||
void lcdOn();
|
||||
|
||||
#define lcdRefreshWait(...)
|
||||
|
||||
// Backlight driver
|
||||
#define BACKLIGHT_LEVEL_MAX 100
|
||||
#define BACKLIGHT_FORCED_ON BACKLIGHT_LEVEL_MAX + 1
|
||||
#define BACKLIGHT_LEVEL_MIN 35
|
||||
|
||||
extern bool boardBacklightOn;
|
||||
void backlightLowInit( void );
|
||||
void backlightInit();
|
||||
void backlightEnable(uint8_t dutyCycle);
|
||||
void backlightFullOn();
|
||||
bool isBacklightEnabled();
|
||||
|
||||
#define BACKLIGHT_ENABLE() \
|
||||
{ \
|
||||
boardBacklightOn = true; \
|
||||
backlightEnable(BACKLIGHT_LEVEL_MAX - currentBacklightBright); \
|
||||
}
|
||||
|
||||
#define BACKLIGHT_DISABLE() \
|
||||
{ \
|
||||
boardBacklightOn = false; \
|
||||
backlightEnable(((g_eeGeneral.blOffBright == BACKLIGHT_LEVEL_MIN) && \
|
||||
(g_eeGeneral.backlightMode != e_backlight_mode_off)) \
|
||||
? 0 \
|
||||
: g_eeGeneral.blOffBright); \
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && !defined(SIMU)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Audio driver
|
||||
void audioInit();
|
||||
void audioConsumeCurrentBuffer();
|
||||
|
||||
#define audioDisableIrq() // interrupts must stay enabled on Horus
|
||||
#define audioEnableIrq() // interrupts must stay enabled on Horus
|
||||
#define setSampleRate(freq)
|
||||
void setScaledVolume(uint8_t volume);
|
||||
void setVolume(uint8_t volume);
|
||||
int32_t getVolume();
|
||||
#define VOLUME_LEVEL_MAX 23
|
||||
#define VOLUME_LEVEL_DEF 12
|
||||
|
||||
// Telemetry driver
|
||||
#define INTMODULE_FIFO_SIZE 512
|
||||
#define TELEMETRY_FIFO_SIZE 512
|
||||
|
||||
// Haptic driver
|
||||
void hapticInit();
|
||||
void hapticDone();
|
||||
void hapticOff();
|
||||
void hapticOn(uint32_t pwmPercent);
|
||||
|
||||
// Second serial port driver
|
||||
//#define AUX_SERIAL
|
||||
#define DEBUG_BAUDRATE 115200
|
||||
#define LUA_DEFAULT_BAUDRATE 115200
|
||||
|
||||
extern uint8_t currentTrainerMode;
|
||||
void checkTrainerSettings();
|
||||
|
||||
// Touch panel driver
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState touchPanelRead();
|
||||
struct TouchState getInternalTouchState();
|
||||
|
||||
// USB Charger
|
||||
#if defined(USB_CHARGER)
|
||||
void usbChargerInit();
|
||||
bool usbChargerLed();
|
||||
#endif
|
||||
|
||||
#endif // _BOARD_H_
|
||||
@@ -0,0 +1,154 @@
|
||||
#include "extflash_driver.h"
|
||||
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_qspi.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define QSPI_NOR_PAGE_SIZE 256
|
||||
|
||||
int32_t ExtFLASH_Init()
|
||||
{
|
||||
if (stm32_qspi_nor_init() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return stm32_qspi_nor_memory_mapped();
|
||||
}
|
||||
|
||||
void ExtFLASH_InitRuntime() { stm32_qspi_no_init_runtime(); }
|
||||
|
||||
//
|
||||
// ETX HAL flash interface
|
||||
//
|
||||
|
||||
static uint32_t extflash_get_size_kb()
|
||||
{
|
||||
return QSPI_FLASH_SIZE / 1024;
|
||||
}
|
||||
|
||||
static uint32_t extflash_get_sector(uint32_t address)
|
||||
{
|
||||
address -= QSPI_BASE;
|
||||
return address / (64 * 1024);
|
||||
}
|
||||
|
||||
static uint32_t extflash_get_sector_size(uint32_t sector)
|
||||
{
|
||||
(void)sector;
|
||||
return (64 * 1024);
|
||||
}
|
||||
|
||||
static int extflash_erase_sector(uint32_t address)
|
||||
{
|
||||
address -= QSPI_BASE;
|
||||
return stm32_qspi_nor_erase_sector(address);
|
||||
}
|
||||
|
||||
static int extflash_program(uint32_t address, void* data, uint32_t len)
|
||||
{
|
||||
address -= QSPI_BASE;
|
||||
|
||||
int ret = 0;
|
||||
while (len > 0) {
|
||||
uint32_t size = (len > QSPI_NOR_PAGE_SIZE) ? QSPI_NOR_PAGE_SIZE : len;
|
||||
ret = stm32_qspi_nor_program(address, data, size);
|
||||
if (ret != 0) break;
|
||||
len -= size;
|
||||
address += size;
|
||||
data = (uint8_t*)data + size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int extflash_read(uint32_t address, void* data, uint32_t len)
|
||||
{
|
||||
address -= QSPI_BASE;
|
||||
return stm32_qspi_nor_read(address, data, len);
|
||||
}
|
||||
|
||||
const etx_flash_driver_t extflash_driver = {
|
||||
.get_size_kb = extflash_get_size_kb,
|
||||
.get_sector = extflash_get_sector,
|
||||
.get_sector_size = extflash_get_sector_size,
|
||||
.erase_sector = extflash_erase_sector,
|
||||
.program = extflash_program,
|
||||
.read = extflash_read,
|
||||
};
|
||||
|
||||
#if defined(BOOT)
|
||||
//
|
||||
// USB DFU interface
|
||||
//
|
||||
#include "usbd_dfu.h"
|
||||
|
||||
#define MEDIA_DESC_STR "@External Flash /0x90000000/128*064Kg"
|
||||
|
||||
static uint16_t extflash_dfu_init()
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint16_t extflash_dfu_deinit()
|
||||
{
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint16_t extflash_dfu_erase(uint32_t address)
|
||||
{
|
||||
if (extflash_erase_sector(address) < 0) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint16_t extflash_dfu_write(uint8_t* src, uint8_t* dest, uint32_t len)
|
||||
{
|
||||
if (extflash_program((intptr_t)dest, (void*)src, len) < 0) {
|
||||
return USBD_FAIL;
|
||||
}
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint8_t* extflash_dfu_read(uint8_t* src, uint8_t* dest, uint32_t len)
|
||||
{
|
||||
if (extflash_read((intptr_t)src, (void*)dest, len) < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
static uint16_t extflash_dfu_get_status(uint32_t address, uint8_t cmd, uint8_t *buffer)
|
||||
{
|
||||
switch (cmd) {
|
||||
case DFU_MEDIA_PROGRAM:
|
||||
buffer[1] = 1;
|
||||
buffer[2] = 0;
|
||||
buffer[3] = 0;
|
||||
break;
|
||||
|
||||
case DFU_MEDIA_ERASE:
|
||||
default:
|
||||
buffer[1] = 20;
|
||||
buffer[2] = 0;
|
||||
buffer[3] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
const USBD_DFU_MediaTypeDef _extflash_dfu_media = {
|
||||
.pStrDesc = (uint8_t*)MEDIA_DESC_STR,
|
||||
.Init = extflash_dfu_init,
|
||||
.DeInit = extflash_dfu_deinit,
|
||||
.Erase = extflash_dfu_erase,
|
||||
.Write = extflash_dfu_write,
|
||||
.Read = extflash_dfu_read,
|
||||
.GetStatus = extflash_dfu_get_status,
|
||||
};
|
||||
|
||||
const void* extflash_dfu_media = &_extflash_dfu_media;
|
||||
|
||||
#endif // BOOT
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hal/flash_driver.h"
|
||||
|
||||
extern const etx_flash_driver_t extflash_driver;
|
||||
extern const void* extflash_dfu_media;
|
||||
|
||||
// init external FLASH hardware
|
||||
int32_t ExtFLASH_Init();
|
||||
|
||||
// init only runtime structures
|
||||
void ExtFLASH_InitRuntime();
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_timer.h"
|
||||
#include "stm32_pulse_driver.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define HAPTIC_TIMER_FREQ 200000000
|
||||
|
||||
static const stm32_pulse_timer_t _haptic_timer = {
|
||||
.GPIO = (gpio_t)HAPTIC_GPIO,
|
||||
.GPIO_Alternate = HAPTIC_GPIO_AF,
|
||||
.TIMx = HAPTIC_GPIO_TIMER,
|
||||
.TIM_Freq = HAPTIC_TIMER_FREQ,
|
||||
.TIM_Channel = LL_TIM_CHANNEL_CH2,
|
||||
.TIM_IRQn = (IRQn_Type)-1,
|
||||
.DMAx = nullptr,
|
||||
.DMA_Stream = 0,
|
||||
.DMA_Channel = 0,
|
||||
.DMA_IRQn = (IRQn_Type)-1,
|
||||
.DMA_TC_CallbackPtr = nullptr,
|
||||
};
|
||||
|
||||
void hapticInit(void)
|
||||
{
|
||||
stm32_pulse_init(&_haptic_timer, 10000);
|
||||
stm32_pulse_config_output(&_haptic_timer, true, LL_TIM_OCMODE_PWM1, 0);
|
||||
LL_TIM_SetAutoReload(_haptic_timer.TIMx, 100);
|
||||
LL_TIM_EnableCounter(_haptic_timer.TIMx);
|
||||
}
|
||||
|
||||
void hapticOn(uint32_t pwmPercent)
|
||||
{
|
||||
if (pwmPercent > 100) pwmPercent = 100;
|
||||
stm32_pulse_set_cmp_val(&_haptic_timer, pwmPercent);
|
||||
}
|
||||
|
||||
void hapticOff(void) { hapticOn(0); }
|
||||
void hapticDone(void) { hapticOff(); }
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/key_driver.h"
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "keys.h"
|
||||
|
||||
#include "stm32_keys.inc"
|
||||
#include "debug.h"
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "dma2d.h"
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "debug.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_driver.h"
|
||||
#include "board.h"
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_qspi.h"
|
||||
|
||||
uint8_t TouchControllerType = 0; // 0: other; 1: CST836U
|
||||
static volatile uint16_t lcd_phys_w = LCD_PHYS_W;
|
||||
static volatile uint16_t lcd_phys_h = LCD_PHYS_H;
|
||||
|
||||
static LTDC_HandleTypeDef hltdc;
|
||||
static void* initialFrameBuffer = nullptr;
|
||||
|
||||
static volatile uint8_t _frame_addr_reloaded = 0;
|
||||
|
||||
#if defined(LCD_VERTICAL_INVERT)
|
||||
// The H17 panel is mounted upside-down, exactly like the tx16s/horus panel.
|
||||
// LTDC cannot rotate, so we software-rotate every refreshed area 180 into a
|
||||
// dedicated back buffer and swap it in on the last flush of a frame. Mirrors
|
||||
// radio/src/targets/horus/lcd_driver.cpp.
|
||||
typedef uint16_t pixel_t;
|
||||
static pixel_t _LCD_BUF_1[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
static pixel_t _LCD_BUF_2[DISPLAY_BUFFER_SIZE] __SDRAM;
|
||||
|
||||
static pixel_t _line_buffer[LCD_W];
|
||||
|
||||
static uint16_t* _front_buffer = _LCD_BUF_1;
|
||||
static uint16_t* _back_buffer = _LCD_BUF_2;
|
||||
|
||||
// Copy 2 pixels at once to speed up a little
|
||||
static void _copy_rotate_180(uint16_t* dst, uint16_t* src, const rect_t& copy_area)
|
||||
{
|
||||
coord_t x1 = LCD_W - copy_area.w - copy_area.x;
|
||||
coord_t y1 = LCD_H - copy_area.h - copy_area.y;
|
||||
|
||||
src += copy_area.w - 2;
|
||||
dst += (y1 + copy_area.h - 1) * LCD_W + x1;
|
||||
|
||||
for (auto line = 0; line < copy_area.h; line++) {
|
||||
|
||||
// invert line into _line_buffer first (SRAM)
|
||||
auto px_dst = _line_buffer;
|
||||
|
||||
auto line_end = px_dst + (copy_area.w & ~1);
|
||||
while (px_dst != line_end) {
|
||||
uint32_t* px2_src = (uint32_t*)src;
|
||||
|
||||
*((uint32_t*)px_dst) = ((*px2_src & 0xFFFF0000) >> 16) | ((*px2_src & 0xFFFF) << 16);
|
||||
|
||||
src -= 2;
|
||||
px_dst += 2;
|
||||
}
|
||||
|
||||
if (copy_area.w & 1) {
|
||||
*px_dst = *(src+1);
|
||||
src--;
|
||||
}
|
||||
|
||||
// ... and DMA back into SDRAM
|
||||
DMACopyBitmap(dst, copy_area.w, 1, 0, 0,
|
||||
_line_buffer, copy_area.w, 1, 0, 0,
|
||||
copy_area.w, 1);
|
||||
|
||||
src += copy_area.w * 2;
|
||||
dst -= LCD_W;
|
||||
}
|
||||
}
|
||||
|
||||
static void _rotate_area_180(lv_area_t& area)
|
||||
{
|
||||
lv_coord_t tmp_coord;
|
||||
tmp_coord = area.y2;
|
||||
area.y2 = LCD_H - area.y1 - 1;
|
||||
area.y1 = LCD_H - tmp_coord - 1;
|
||||
tmp_coord = area.x2;
|
||||
area.x2 = LCD_W - area.x1 - 1;
|
||||
area.x1 = LCD_W - tmp_coord - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _update_frame_buffer_addr(uint16_t* buffer)
|
||||
{
|
||||
// given the data cache size, this is probably
|
||||
// faster than cleaning by address
|
||||
SCB_CleanDCache();
|
||||
|
||||
LTDC_Layer1->CFBAR = (uint32_t)buffer;
|
||||
// reload shadow registers on vertical blank
|
||||
_frame_addr_reloaded = 0;
|
||||
LTDC->SRCR = LTDC_SRCR_VBR;
|
||||
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
|
||||
// wait for reload
|
||||
// TODO: replace through some smarter mechanism without busy wait
|
||||
while(_frame_addr_reloaded == 0);
|
||||
}
|
||||
|
||||
static void startLcdRefresh(lv_disp_drv_t *disp_drv, uint16_t *buffer,
|
||||
const rect_t ©_area)
|
||||
{
|
||||
#if defined(LCD_VERTICAL_INVERT)
|
||||
_copy_rotate_180(_back_buffer, buffer, copy_area);
|
||||
|
||||
if (lv_disp_flush_is_last(disp_drv)) {
|
||||
|
||||
// swap back/front
|
||||
if (_front_buffer == _LCD_BUF_1) {
|
||||
_front_buffer = _LCD_BUF_2;
|
||||
_back_buffer = _LCD_BUF_1;
|
||||
} else {
|
||||
_front_buffer = _LCD_BUF_1;
|
||||
_back_buffer = _LCD_BUF_2;
|
||||
}
|
||||
|
||||
// Trigger async refresh
|
||||
_update_frame_buffer_addr(_front_buffer);
|
||||
|
||||
// Copy refreshed & rotated areas into new back buffer
|
||||
uint16_t* src = _front_buffer;
|
||||
uint16_t* dst = _back_buffer;
|
||||
|
||||
lv_disp_t* disp = _lv_refr_get_disp_refreshing();
|
||||
for(int i = 0; i < disp->inv_p; i++) {
|
||||
if(disp->inv_area_joined[i]) continue;
|
||||
|
||||
lv_area_t refr_area;
|
||||
lv_area_copy(&refr_area, &disp->inv_areas[i]);
|
||||
|
||||
_rotate_area_180(refr_area);
|
||||
|
||||
auto area_w = refr_area.x2 - refr_area.x1 + 1;
|
||||
auto area_h = refr_area.y2 - refr_area.y1 + 1;
|
||||
|
||||
DMACopyBitmap(dst, LCD_W, LCD_H, refr_area.x1, refr_area.y1,
|
||||
src, LCD_W, LCD_H, refr_area.x1, refr_area.y1,
|
||||
area_w, area_h);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)disp_drv;
|
||||
(void)copy_area;
|
||||
|
||||
_update_frame_buffer_addr(buffer);
|
||||
#endif
|
||||
|
||||
// Since #7483 the shared LVGL flush path (gui/colorlcd/lcd.cpp) no longer
|
||||
// signals completion after invoking the flush callback; the driver must call
|
||||
// lcdFlushed() itself, otherwise LVGL's flush stays pending forever and the
|
||||
// UI freezes on the first frame (e.g. stuck on the boot logo).
|
||||
lcdFlushed();
|
||||
}
|
||||
|
||||
// LTDC RGB666 data + sync lines (all on AF14). Layout matches the tx15/rm-h750
|
||||
// panel wiring: PI12-14 (HSYNC/VSYNC/CLK), PJ1-6 (R2-R7), PJ9-11 + PK0-2
|
||||
// (G2-G7), PJ14-15 + PK3-6 (B2-B7), PK7 (DE).
|
||||
gpio_t _lcd_af_gpios[] = {
|
||||
GPIO_PIN(GPIOI, 12), GPIO_PIN(GPIOI, 13), GPIO_PIN(GPIOI, 14),
|
||||
|
||||
GPIO_PIN(GPIOJ, 1), GPIO_PIN(GPIOJ, 2), GPIO_PIN(GPIOJ, 3),
|
||||
GPIO_PIN(GPIOJ, 4), GPIO_PIN(GPIOJ, 5), GPIO_PIN(GPIOJ, 6),
|
||||
GPIO_PIN(GPIOJ, 9), GPIO_PIN(GPIOJ, 10), GPIO_PIN(GPIOJ, 11),
|
||||
GPIO_PIN(GPIOJ, 14), GPIO_PIN(GPIOJ, 15),
|
||||
|
||||
GPIO_PIN(GPIOK, 0), GPIO_PIN(GPIOK, 1), GPIO_PIN(GPIOK, 2),
|
||||
GPIO_PIN(GPIOK, 3), GPIO_PIN(GPIOK, 4), GPIO_PIN(GPIOK, 5),
|
||||
GPIO_PIN(GPIOK, 6), GPIO_PIN(GPIOK, 7),
|
||||
};
|
||||
|
||||
static void LCD_AF_GPIOConfig(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(_lcd_af_gpios) / sizeof(_lcd_af_gpios[0]); i++) {
|
||||
gpio_init_af(_lcd_af_gpios[i], GPIO_AF14, GPIO_SPEED_FREQ_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
static void lcdResetConfig(void)
|
||||
{
|
||||
LL_GPIO_InitTypeDef GPIO_InitStructure;
|
||||
LL_GPIO_StructInit(&GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = LCD_RESET_GPIO_PIN;
|
||||
GPIO_InitStructure.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
GPIO_InitStructure.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStructure.Pull = LL_GPIO_PULL_NO;
|
||||
LL_GPIO_Init(LCD_RESET_GPIO, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
static void lcdReset() {
|
||||
LCD_NRST_HIGH();
|
||||
delay_ms(1);
|
||||
|
||||
LCD_NRST_LOW(); // RESET();
|
||||
delay_ms(10);
|
||||
|
||||
LCD_NRST_HIGH();
|
||||
delay_ms(100);
|
||||
}
|
||||
|
||||
void LCD_Init_LTDC() {
|
||||
hltdc.Instance = LTDC;
|
||||
|
||||
/* LTDC pixel clock is driven from PLL3R (see system_clock.c) */
|
||||
|
||||
/* LTDC Configuration *********************************************************/
|
||||
/* Polarity configuration */
|
||||
/* Initialize the horizontal synchronization polarity as active low */
|
||||
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
|
||||
/* Initialize the vertical synchronization polarity as active low */
|
||||
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
|
||||
/* Initialize the data enable polarity as active low */
|
||||
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
|
||||
/* Initialize the pixel clock polarity as input pixel clock.
|
||||
tx16s/horus drives this panel with IPC (non-inverted); jumper-h750 used
|
||||
IIPC for a different panel. */
|
||||
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
|
||||
|
||||
/* Configure R,G,B component values for LCD background color */
|
||||
hltdc.Init.Backcolor.Red = 0;
|
||||
hltdc.Init.Backcolor.Green = 0;
|
||||
hltdc.Init.Backcolor.Blue = 0;
|
||||
|
||||
/* Configure horizontal synchronization width */
|
||||
hltdc.Init.HorizontalSync = HSW-1;
|
||||
/* Configure vertical synchronization height */
|
||||
hltdc.Init.VerticalSync = VSH-1;
|
||||
/* Configure accumulated horizontal back porch */
|
||||
hltdc.Init.AccumulatedHBP = HSW+HBP-1;
|
||||
/* Configure accumulated vertical back porch */
|
||||
hltdc.Init.AccumulatedVBP = VSH+VBP-1;
|
||||
/* Configure accumulated active width */
|
||||
hltdc.Init.AccumulatedActiveW = lcd_phys_w + HBP+HSW-1;
|
||||
/* Configure accumulated active height */
|
||||
hltdc.Init.AccumulatedActiveH = lcd_phys_h + VBP+VSH-1;
|
||||
/* Configure total width */
|
||||
hltdc.Init.TotalWidth = lcd_phys_w + HBP + HFP + HSW -1;
|
||||
/* Configure total height */
|
||||
hltdc.Init.TotalHeigh = lcd_phys_h + VBP + VFP+VSH-1;
|
||||
|
||||
HAL_LTDC_Init(&hltdc);
|
||||
|
||||
// Configure IRQ (line)
|
||||
NVIC_SetPriority(LTDC_IRQn, LTDC_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(LTDC_IRQn);
|
||||
|
||||
// Trigger on last line
|
||||
HAL_LTDC_ProgramLineEvent(&hltdc, lcd_phys_h);
|
||||
__HAL_LTDC_ENABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
}
|
||||
|
||||
void LCD_LayerInit() {
|
||||
auto& layer = hltdc.LayerCfg[0];
|
||||
|
||||
/* Windowing configuration */
|
||||
layer.WindowX0 = 0;
|
||||
layer.WindowX1 = lcd_phys_w;
|
||||
layer.WindowY0 = 0;
|
||||
layer.WindowY1 = lcd_phys_h;
|
||||
|
||||
/* Pixel Format configuration*/
|
||||
layer.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
|
||||
|
||||
/* Alpha constant (255 totally opaque) */
|
||||
layer.Alpha = 255;
|
||||
|
||||
/* Default Color configuration (configure A,R,G,B component values) */
|
||||
layer.Backcolor.Blue = 0;
|
||||
layer.Backcolor.Green = 0;
|
||||
layer.Backcolor.Red = 0;
|
||||
layer.Alpha0 = 0;
|
||||
|
||||
/* Configure blending factors */
|
||||
layer.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
|
||||
layer.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
|
||||
|
||||
layer.ImageWidth = lcd_phys_w;
|
||||
layer.ImageHeight = lcd_phys_h;
|
||||
|
||||
/* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */
|
||||
#if defined(LCD_VERTICAL_INVERT)
|
||||
layer.FBStartAdress = (intptr_t)_LCD_BUF_1;
|
||||
#else
|
||||
layer.FBStartAdress = (intptr_t)initialFrameBuffer;
|
||||
#endif
|
||||
|
||||
/* Initialize LTDC layer 1 */
|
||||
HAL_LTDC_ConfigLayer(&hltdc, &hltdc.LayerCfg[0], 0);
|
||||
|
||||
/* dithering activation */
|
||||
HAL_LTDC_EnableDither(&hltdc);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
void lcdSetInitalFrameBuffer(void* fbAddress)
|
||||
{
|
||||
initialFrameBuffer = fbAddress;
|
||||
}
|
||||
|
||||
const char* boardLcdType = "";
|
||||
|
||||
extern "C"
|
||||
void lcdInit(void)
|
||||
{
|
||||
#if defined(LCD_VERTICAL_INVERT)
|
||||
// Clear buffers first
|
||||
memset(_LCD_BUF_1, 0, sizeof(_LCD_BUF_1));
|
||||
memset(_LCD_BUF_2, 0, sizeof(_LCD_BUF_2));
|
||||
#endif
|
||||
|
||||
/* Configure the LCD reset pin */
|
||||
lcdResetConfig();
|
||||
|
||||
/* Reset the LCD --------------------------------------------------------*/
|
||||
lcdReset();
|
||||
|
||||
/* Configure the LTDC RGB control pins */
|
||||
LCD_AF_GPIOConfig();
|
||||
|
||||
TRACE("LCD INIT: parallel RGB (LTDC)");
|
||||
boardLcdType = "RGB (LTDC)";
|
||||
|
||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||
|
||||
LCD_Init_LTDC();
|
||||
LCD_LayerInit();
|
||||
|
||||
// Enable LCD display
|
||||
__HAL_LTDC_ENABLE(&hltdc);
|
||||
|
||||
lcdSetFlushCb(startLcdRefresh);
|
||||
}
|
||||
|
||||
extern "C" void LTDC_IRQHandler(void)
|
||||
{
|
||||
__HAL_LTDC_CLEAR_FLAG(&hltdc, LTDC_FLAG_LI);
|
||||
__HAL_LTDC_DISABLE_IT(&hltdc, LTDC_IT_LI);
|
||||
_frame_addr_reloaded = 1;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 __LCD_DRIVER_H__
|
||||
#define __LCD_DRIVER_H__
|
||||
|
||||
// H17 uses a parallel RGB (LTDC) panel with no MCU-side SPI configuration bus.
|
||||
// Only the LTDC data/sync lines and the panel reset line (LCD_RESET_GPIO) are
|
||||
// wired, so the SPI bit-bang init/read path used by the RadioMaster boards is
|
||||
// intentionally absent here.
|
||||
|
||||
// Timings taken from the horus/tx16s driver, which drives this same panel.
|
||||
// Values are in this board's raw-porch convention (lcd_driver.cpp subtracts 1
|
||||
// and accumulates), and reproduce the exact LTDC register values horus programs:
|
||||
// HSync=2 AccHBP=42 AccActiveW=522 TotalWidth=525
|
||||
// VSync=10 AccVBP=12 AccActiveH=284 TotalHeigh=286
|
||||
#define HBP ( 40 )
|
||||
#define VBP ( 2 )
|
||||
|
||||
#define HSW ( 3 )
|
||||
#define VSH ( 11 )
|
||||
|
||||
#define HFP ( 3 )
|
||||
#define VFP ( 2 )
|
||||
|
||||
#define LCD_NRST_HIGH() LL_GPIO_SetOutputPin(LCD_RESET_GPIO, LCD_RESET_GPIO_PIN)
|
||||
#define LCD_NRST_LOW() LL_GPIO_ResetOutputPin(LCD_RESET_GPIO, LCD_RESET_GPIO_PIN)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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 "hal/gpio.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_hal_ll.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
|
||||
|
||||
#define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_3
|
||||
|
||||
#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
|
||||
|
||||
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
|
||||
|
||||
#define SDRAM_READBURST FMC_SDRAM_RBURST_DISABLE
|
||||
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
|
||||
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
|
||||
#define SDRAM_MODEREG_BURST_FULL_PAGE ((uint16_t)0x0007)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_1 ((uint16_t)0x0010)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
|
||||
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
|
||||
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
|
||||
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
|
||||
|
||||
#define GPIO_AF_FMC GPIO_AF12
|
||||
|
||||
extern "C" void SDRAM_GPIOConfig(void)
|
||||
{
|
||||
/*-- GPIOs Configuration -----------------------------------------------------*/
|
||||
/*
|
||||
*/
|
||||
|
||||
/* GPIOC configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOC, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH); // FMC_SDNWE (RAM_WE)
|
||||
|
||||
/* GPIOD configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 9), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 10), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOD, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
/* GPIOE configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 7), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 9), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 10), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 11), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 12), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 13), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOE, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
/* GPIOF configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 2), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 3), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 4), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 11), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 12), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 13), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 14), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOF, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
/* GPIOG configuration */
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 0), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 1), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 4), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 5), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 8), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOG, 15), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
// NB: PH5 is USB_VBUS on this board, NOT FMC_SDNWE (write-enable is on PC0).
|
||||
// Only PH6 (FMC_SDNE1 / RAM_CS) and PH7 (FMC_SDCKE1 / RAM_CKE) are FMC here.
|
||||
gpio_init_af(GPIO_PIN(GPIOH, 6), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
gpio_init_af(GPIO_PIN(GPIOH, 7), GPIO_AF_FMC, GPIO_PIN_SPEED_VERY_HIGH);
|
||||
|
||||
}
|
||||
|
||||
extern "C" void SDRAM_InitSequence(void)
|
||||
{
|
||||
FMC_SDRAM_CommandTypeDef FMC_SDRAMCommandStructure;
|
||||
uint32_t tmpr = 0;
|
||||
|
||||
/* Step 3 --------------------------------------------------------------------*/
|
||||
/* Configure a clock configuration enable command */
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 4 --------------------------------------------------------------------*/
|
||||
/* Insert 1 ms delay */
|
||||
delay_ms(100);
|
||||
|
||||
/* Step 5 --------------------------------------------------------------------*/
|
||||
/* Configure a PALL (precharge all) command */
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_PALL;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 6 --------------------------------------------------------------------*/
|
||||
/* Configure a Auto-Refresh command */
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 8;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = 0;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 7 --------------------------------------------------------------------*/
|
||||
/* Program the external memory mode register */
|
||||
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
|
||||
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
|
||||
SDRAM_MODEREG_CAS_LATENCY_3 |
|
||||
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
|
||||
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
|
||||
|
||||
/* Configure a load Mode register command*/
|
||||
FMC_SDRAMCommandStructure.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
|
||||
FMC_SDRAMCommandStructure.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
|
||||
FMC_SDRAMCommandStructure.AutoRefreshNumber = 1;
|
||||
FMC_SDRAMCommandStructure.ModeRegisterDefinition = tmpr;
|
||||
/* Send the command */
|
||||
FMC_SDRAM_SendCommand(FMC_Bank5_6_R, &FMC_SDRAMCommandStructure, 10);
|
||||
|
||||
/* Step 8 --------------------------------------------------------------------*/
|
||||
/* Set the refresh rate counter */
|
||||
/* (15.62 us x Freq) - 20 */
|
||||
/* Set the device refresh counter */
|
||||
FMC_SDRAM_SetAutoRefreshNumber(FMC_Bank5_6_R, 15);
|
||||
FMC_SDRAM_ProgramRefreshRate(FMC_Bank5_6_R, 2479);
|
||||
}
|
||||
|
||||
extern "C" void SDRAM_Init(void)
|
||||
{
|
||||
//delay funcion needed
|
||||
delaysInit();
|
||||
|
||||
/* GPIO configuration for FMC SDRAM bank */
|
||||
SDRAM_GPIOConfig();
|
||||
|
||||
/* Enable FMC clock */
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_FMC);
|
||||
|
||||
/* FMC Configuration ---------------------------------------------------------*/
|
||||
FMC_SDRAM_InitTypeDef FMC_SDRAMInitStructure;
|
||||
FMC_SDRAM_TimingTypeDef FMC_SDRAMTimingInitStructure;
|
||||
|
||||
/* FMC SDRAM Bank configuration */
|
||||
FMC_SDRAMTimingInitStructure.LoadToActiveDelay = 3; // tMRD
|
||||
FMC_SDRAMTimingInitStructure.ExitSelfRefreshDelay = 11; // tXSR = 70ns
|
||||
FMC_SDRAMTimingInitStructure.SelfRefreshTime = 7; // tRAS = 42ns
|
||||
FMC_SDRAMTimingInitStructure.RowCycleDelay = 10; // tRC = 60ns
|
||||
FMC_SDRAMTimingInitStructure.WriteRecoveryTime = 2; // tWR
|
||||
FMC_SDRAMTimingInitStructure.RPDelay = 3; // tRP = 18ns
|
||||
FMC_SDRAMTimingInitStructure.RCDDelay = 3; // tRCD = 18ns
|
||||
|
||||
/* FMC SDRAM control configuration */
|
||||
FMC_SDRAMInitStructure.SDBank = FMC_SDRAM_BANK2;
|
||||
FMC_SDRAMInitStructure.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
|
||||
FMC_SDRAMInitStructure.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
|
||||
FMC_SDRAMInitStructure.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
|
||||
FMC_SDRAMInitStructure.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
|
||||
FMC_SDRAMInitStructure.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
|
||||
FMC_SDRAMInitStructure.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
|
||||
FMC_SDRAMInitStructure.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
|
||||
FMC_SDRAMInitStructure.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
|
||||
FMC_SDRAMInitStructure.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
|
||||
|
||||
/* FMC SDRAM bank initialization */
|
||||
FMC_SDRAM_Init(FMC_Bank5_6_R, &FMC_SDRAMInitStructure);
|
||||
FMC_SDRAM_Timing_Init(FMC_Bank5_6_R, &FMC_SDRAMTimingInitStructure, FMC_SDRAM_BANK2);
|
||||
|
||||
__FMC_ENABLE();
|
||||
|
||||
/* FMC SDRAM device initialization sequence */
|
||||
SDRAM_InitSequence();
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "stm32h7xx_ll_pwr.h"
|
||||
#include "stm32h7xx_ll_rcc.h"
|
||||
#include "stm32h7xx_ll_system.h"
|
||||
#include "stm32h7xx_ll_bus.h"
|
||||
|
||||
#define BOOTSTRAP __attribute__((section(".bootstrap")))
|
||||
|
||||
BOOTSTRAP void SystemClock_Config(void)
|
||||
{
|
||||
/* Power Configuration */
|
||||
LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
|
||||
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
|
||||
while (LL_PWR_IsActiveFlag_VOS() == 0){
|
||||
}
|
||||
|
||||
/* Enable HSE oscillator */
|
||||
LL_RCC_HSE_Enable();
|
||||
while (LL_RCC_HSE_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Set FLASH latency */
|
||||
LL_FLASH_SetLatency(LL_FLASH_LATENCY_5);
|
||||
|
||||
/* Main PLL configuration and activation */
|
||||
LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
|
||||
LL_RCC_PLL1P_Enable();
|
||||
LL_RCC_PLL1Q_Enable();
|
||||
LL_RCC_PLL1R_Enable();
|
||||
LL_RCC_PLL1FRACN_Disable();
|
||||
LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4);
|
||||
LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
|
||||
// HSE = 48 MHz. M=12 -> 4 MHz PFD input (matches RANGE_2_4). VCO = 4*240 =
|
||||
// 960 MHz. Outputs unchanged from the previous (out-of-range M=3/N=60) config:
|
||||
// P=2 -> 480 MHz sysclk, Q=20 -> 48 MHz (USB/SPI), R=2 -> 480 MHz.
|
||||
LL_RCC_PLL1_SetM(12);
|
||||
LL_RCC_PLL1_SetN(240);
|
||||
LL_RCC_PLL1_SetP(2);
|
||||
LL_RCC_PLL1_SetQ(20);
|
||||
LL_RCC_PLL1_SetR(2);
|
||||
LL_RCC_PLL1_Enable();
|
||||
while (LL_RCC_PLL1_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Set Sys & AHB & APB1 & APB2 & APB4 prescaler */
|
||||
LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
|
||||
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
|
||||
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
|
||||
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
|
||||
LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
|
||||
|
||||
/* Set PLL1 as System Clock Source */
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
|
||||
}
|
||||
|
||||
/* Config & activate PLL2 */
|
||||
LL_RCC_PLL2P_Enable();
|
||||
LL_RCC_PLL2FRACN_Disable();
|
||||
LL_RCC_PLL2_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4);
|
||||
LL_RCC_PLL2_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
|
||||
LL_RCC_PLL2_SetM(24);
|
||||
LL_RCC_PLL2_SetN(96);
|
||||
LL_RCC_PLL2_SetP(17); // 11.294 MHz
|
||||
LL_RCC_PLL2_Enable();
|
||||
while (LL_RCC_PLL2_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Config & activate PLL3 */
|
||||
LL_RCC_PLL3P_Enable();
|
||||
LL_RCC_PLL3Q_Enable();
|
||||
LL_RCC_PLL3R_Enable();
|
||||
LL_RCC_PLL3FRACN_Disable();
|
||||
LL_RCC_PLL3_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_2_4);
|
||||
LL_RCC_PLL3_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
|
||||
// HSE = 48 MHz. Previous M=1 gave a 48 MHz PFD input (3x over the 16 MHz PLL
|
||||
// input max) so PLL3 could not lock -> no LTDC pixel clock. M=12 -> 4 MHz
|
||||
// input (matches RANGE_2_4). VCO = 4*48 = 192 MHz, identical to before:
|
||||
// P=2 -> 96 MHz, Q=2 -> 96 MHz, R=18 -> ~10.67 MHz LTDC pixel clock.
|
||||
LL_RCC_PLL3_SetM(12);
|
||||
LL_RCC_PLL3_SetN(48);
|
||||
LL_RCC_PLL3_SetP(2);
|
||||
LL_RCC_PLL3_SetQ(2);
|
||||
LL_RCC_PLL3_SetR(18);
|
||||
LL_RCC_PLL3_Enable();
|
||||
while (LL_RCC_PLL3_IsReady() != 1) {
|
||||
}
|
||||
|
||||
/* Enable SRAM1, SRAM2 & SRAM3 */
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_D2SRAM1 |
|
||||
LL_AHB2_GRP1_PERIPH_D2SRAM2 |
|
||||
LL_AHB2_GRP1_PERIPH_D2SRAM3);
|
||||
|
||||
/* Set periph clock sources */
|
||||
LL_RCC_SetSPIClockSource(LL_RCC_SPI123_CLKSOURCE_PLL1Q);
|
||||
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL1Q);
|
||||
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_CLKP);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void SystemClock_Config();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "touch.h"
|
||||
|
||||
extern void touchPanelDeInit();
|
||||
extern bool touchPanelInit();
|
||||
|
||||
struct TouchState touchPanelRead();
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState getInternalTouchState();
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "hal/gpio.h"
|
||||
#include "hal/i2c_driver.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
#include "stm32_exti_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "timers_driver.h"
|
||||
#include "tp_gt911.h"
|
||||
#include "delays_driver.h"
|
||||
|
||||
#include "os/sleep.h"
|
||||
#include "edgetx_types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TP_GT911_ID "911"
|
||||
|
||||
|
||||
bool touchGT911Flag = false;
|
||||
volatile static bool touchEventOccured = false;
|
||||
struct TouchData touchData;
|
||||
uint16_t touchGT911fwver = 0;
|
||||
uint32_t touchGT911hiccups = 0;
|
||||
|
||||
static tmr10ms_t downTime = 0;
|
||||
static tmr10ms_t tapTime = 0;
|
||||
static short tapCount = 0;
|
||||
|
||||
static TouchState internalTouchState = {};
|
||||
|
||||
static void _gt911_exti_isr(void)
|
||||
{
|
||||
touchEventOccured = true;
|
||||
}
|
||||
|
||||
void I2C_Init_Radio(void)
|
||||
{
|
||||
TRACE("GT911 I2C Init");
|
||||
|
||||
if (i2c_init(TOUCH_I2C_BUS) < 0) {
|
||||
TRACE("GT911 ERROR: i2c_init failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool I2C_GT911_WriteRegister(uint16_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t uAddrAndBuf[258];
|
||||
uAddrAndBuf[0] = (uint8_t)((reg & 0xFF00) >> 8);
|
||||
uAddrAndBuf[1] = (uint8_t)(reg & 0x00FF);
|
||||
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
uAddrAndBuf[i + 2] = buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (stm32_i2c_master_tx(TOUCH_I2C_BUS, GT911_I2C_ADDR, uAddrAndBuf, len + 2,
|
||||
100) < 0) {
|
||||
TRACE("I2C B1 ERROR: WriteRegister failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool I2C_GT911_ReadRegister(uint16_t reg, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t uRegAddr[2];
|
||||
uRegAddr[0] = (uint8_t)((reg & 0xFF00) >> 8);
|
||||
uRegAddr[1] = (uint8_t)(reg & 0x00FF);
|
||||
|
||||
if (stm32_i2c_master_tx(TOUCH_I2C_BUS, GT911_I2C_ADDR, uRegAddr, 2, 10) < 0) {
|
||||
TRACE("I2C B1 ERROR: ReadRegister write reg address failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stm32_i2c_master_rx(TOUCH_I2C_BUS, GT911_I2C_ADDR, buf, len, 100) < 0) {
|
||||
TRACE("I2C B1 ERROR: ReadRegister read reg address failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void touchPanelDeInit(void)
|
||||
{
|
||||
gpio_int_disable(TOUCH_INT_GPIO);
|
||||
touchGT911Flag = false;
|
||||
}
|
||||
|
||||
uint8_t tp_gt911_cfgVer = GT911_CFG_NUMBER;
|
||||
|
||||
bool touchPanelInit(void)
|
||||
{
|
||||
uint8_t tmp[4] = {0};
|
||||
|
||||
if (touchGT911Flag) {
|
||||
gpio_init_int(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_RISING, _gt911_exti_isr);
|
||||
return true;
|
||||
} else {
|
||||
TRACE("Touchpanel init start ...");
|
||||
|
||||
gpio_init(TOUCH_RST_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_init(TOUCH_INT_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
I2C_Init_Radio();
|
||||
|
||||
gpio_clear(TOUCH_RST_GPIO);
|
||||
gpio_set(TOUCH_INT_GPIO);
|
||||
delay_us(200);
|
||||
|
||||
gpio_set(TOUCH_RST_GPIO);
|
||||
delay_ms(6);
|
||||
|
||||
gpio_clear(TOUCH_INT_GPIO);
|
||||
delay_ms(55);
|
||||
|
||||
gpio_init(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_PIN_SPEED_LOW);
|
||||
|
||||
delay_ms(50);
|
||||
|
||||
TRACE("Reading Touch registry");
|
||||
if (!I2C_GT911_ReadRegister(GT911_PRODUCT_ID_REG, tmp, 4)) {
|
||||
TRACE("GT911 ERROR: Product ID read failed");
|
||||
}
|
||||
|
||||
if (strcmp((char *)tmp, TP_GT911_ID) == 0) {
|
||||
TRACE("GT911 chip detected");
|
||||
tmp[0] = 0X02;
|
||||
if (!I2C_GT911_WriteRegister(GT911_COMMAND_REG, tmp, 1)) {
|
||||
TRACE("GT911 ERROR: write to control register failed");
|
||||
}
|
||||
if (!I2C_GT911_ReadRegister(GT911_CONFIG_REG, tmp, 1)) {
|
||||
TRACE("GT911 ERROR: configuration register read failed");
|
||||
}
|
||||
|
||||
TRACE("Chip config Ver:%x", tmp[0]);
|
||||
if ((tp_gt911_cfgVer == 0) || (tmp[0] < tp_gt911_cfgVer)) { // Config ver
|
||||
TRACE("Sending new config %d", GT911_CFG_NUMBER);
|
||||
if (!I2C_GT911_ReadRegister(GT911_CONFIG_REG, tmp, 1)) {
|
||||
TRACE("GT911 ERROR: configuration register read failed");
|
||||
}
|
||||
tp_gt911_cfgVer = tmp[0];
|
||||
}
|
||||
|
||||
if (!I2C_GT911_ReadRegister(GT911_FIRMWARE_VERSION_REG, tmp, 2)) {
|
||||
TRACE("GT911 ERROR: reading firmware version failed");
|
||||
} else {
|
||||
touchGT911fwver = (tmp[1] << 8) + tmp[0];
|
||||
TRACE("GT911 FW version: %u", touchGT911fwver);
|
||||
}
|
||||
|
||||
delay_ms(10);
|
||||
tmp[0] = 0X00;
|
||||
if (!I2C_GT911_WriteRegister(GT911_COMMAND_REG, tmp, 1)) { // end reset
|
||||
TRACE("GT911 ERROR: write to command register failed");
|
||||
}
|
||||
touchGT911Flag = true;
|
||||
|
||||
gpio_init_int(TOUCH_INT_GPIO, GPIO_IN_PU, GPIO_RISING, _gt911_exti_isr);
|
||||
|
||||
return true;
|
||||
}
|
||||
TRACE("GT911 chip NOT FOUND");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool I2C_ReInit(void)
|
||||
{
|
||||
TRACE("I2C B1 ReInit");
|
||||
touchPanelDeInit();
|
||||
if (stm32_i2c_deinit(TOUCH_I2C_BUS) < 0)
|
||||
TRACE("I2C B1 ReInit - I2C DeInit failed");
|
||||
|
||||
// If DeInit fails, try to re-init anyway
|
||||
if (!touchPanelInit()) {
|
||||
TRACE("I2C B1 ReInit - touchPanelInit failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(SIMU) || defined(SEMIHOSTING) || defined(DEBUG)
|
||||
static const char *event2str(uint8_t ev)
|
||||
{
|
||||
switch (ev) {
|
||||
case TE_NONE:
|
||||
return "NONE";
|
||||
case TE_UP:
|
||||
return "UP";
|
||||
case TE_DOWN:
|
||||
return "DOWN";
|
||||
case TE_SLIDE_END:
|
||||
return "SLIDE_END";
|
||||
case TE_SLIDE:
|
||||
return "SLIDE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct TouchState touchPanelRead()
|
||||
{
|
||||
uint8_t state = 0;
|
||||
|
||||
if (!touchEventOccured) return internalTouchState;
|
||||
|
||||
touchEventOccured = false;
|
||||
|
||||
uint32_t startReadStatus = timersGetMsTick();
|
||||
do {
|
||||
if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG, &state, 1)) {
|
||||
touchGT911hiccups++;
|
||||
TRACE("GT911 I2C read XY error");
|
||||
if (!I2C_ReInit()) TRACE("I2C B1 ReInit failed");
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
if (state & 0x80u) {
|
||||
// ready
|
||||
break;
|
||||
}
|
||||
sleep_ms(1);
|
||||
} while (timersGetMsTick() - startReadStatus < GT911_TIMEOUT);
|
||||
|
||||
internalTouchState.deltaX = 0;
|
||||
internalTouchState.deltaY = 0;
|
||||
TRACE("touch state = 0x%x", state);
|
||||
if (state & 0x80u) {
|
||||
uint8_t pointsCount = (state & 0x0Fu);
|
||||
uint32_t now = timersGetMsTick();
|
||||
internalTouchState.tapCount = 0;
|
||||
|
||||
if (pointsCount > 0 && pointsCount <= GT911_MAX_TP) {
|
||||
if (!I2C_GT911_ReadRegister(GT911_READ_XY_REG + 1, touchData.data,
|
||||
pointsCount * sizeof(TouchPoint))) {
|
||||
touchGT911hiccups++;
|
||||
TRACE("GT911 I2C data read error");
|
||||
if (!I2C_ReInit()) TRACE("I2C B1 ReInit failed");
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
#if defined(LCD_VERTICAL_INVERT)
|
||||
// Panel (and thus the GT911) is mounted upside-down, matching the 180
|
||||
// display rotation in lcd_driver.cpp. Flip the reported coordinates so
|
||||
// touches line up with what is drawn.
|
||||
for (uint8_t i = 0; i < pointsCount; i++) {
|
||||
touchData.points[i].x = LCD_W - 1 - touchData.points[i].x;
|
||||
touchData.points[i].y = LCD_H - 1 - touchData.points[i].y;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (internalTouchState.event == TE_NONE ||
|
||||
internalTouchState.event == TE_UP ||
|
||||
internalTouchState.event == TE_SLIDE_END) {
|
||||
internalTouchState.event = TE_DOWN;
|
||||
internalTouchState.startX = internalTouchState.x =
|
||||
touchData.points[0].x;
|
||||
internalTouchState.startY = internalTouchState.y =
|
||||
touchData.points[0].y;
|
||||
downTime = now;
|
||||
} else {
|
||||
internalTouchState.deltaX =
|
||||
touchData.points[0].x - internalTouchState.x;
|
||||
internalTouchState.deltaY =
|
||||
touchData.points[0].y - internalTouchState.y;
|
||||
if (internalTouchState.event == TE_SLIDE ||
|
||||
abs(internalTouchState.deltaX) >= SLIDE_RANGE ||
|
||||
abs(internalTouchState.deltaY) >= SLIDE_RANGE) {
|
||||
internalTouchState.event = TE_SLIDE;
|
||||
internalTouchState.x = touchData.points[0].x;
|
||||
internalTouchState.y = touchData.points[0].y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (internalTouchState.event == TE_SLIDE) {
|
||||
internalTouchState.event = TE_SLIDE_END;
|
||||
} else if (internalTouchState.event == TE_DOWN) {
|
||||
internalTouchState.event = TE_UP;
|
||||
if (now - downTime <= GT911_TAP_TIME) {
|
||||
if (now - tapTime > GT911_TAP_TIME)
|
||||
tapCount = 1;
|
||||
else
|
||||
tapCount++;
|
||||
internalTouchState.tapCount = tapCount;
|
||||
tapTime = now;
|
||||
}
|
||||
} else {
|
||||
internalTouchState.event = TE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t zero = 0;
|
||||
if (!I2C_GT911_WriteRegister(GT911_READ_XY_REG, &zero, 1)) {
|
||||
TRACE("GT911 ERROR: clearing XY register failed");
|
||||
}
|
||||
|
||||
TRACE("touch event = %s", event2str(internalTouchState.event));
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
bool touchPanelEventOccured()
|
||||
{
|
||||
return touchEventOccured;
|
||||
}
|
||||
|
||||
TouchState getInternalTouchState()
|
||||
{
|
||||
return internalTouchState;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "touch.h"
|
||||
#include "definitions.h"
|
||||
|
||||
#define HAS_TOUCH_PANEL() (touchGT911Flag == true)
|
||||
|
||||
extern bool touchGT911Flag;
|
||||
extern uint16_t touchGT911fwver;
|
||||
extern uint32_t touchGT911hiccups;
|
||||
|
||||
extern void touchPanelDeInit();
|
||||
extern bool touchPanelInit();
|
||||
|
||||
struct TouchState touchPanelRead();
|
||||
bool touchPanelEventOccured();
|
||||
struct TouchState getInternalTouchState();
|
||||
|
||||
#define GT911_TIMEOUT 3 // 3ms
|
||||
#define GT911_TAP_TIME 250 // 250 ms
|
||||
|
||||
#define GT911_MAX_TP 5
|
||||
|
||||
#define GT911_CFG_NUMBER 0x6D
|
||||
|
||||
//I2C
|
||||
#define GT911_I2C_ADDR 0x14
|
||||
|
||||
//#define GT_CMD_WR 0x28
|
||||
//#define GT_CMD_RD 0x29
|
||||
//#define I2C_TIMEOUT_MAX 1000
|
||||
|
||||
#define GT911_COMMAND_REG 0x8040
|
||||
#define GT911_CONFIG_REG 0x8047
|
||||
#define GT911_COORDINATE_REG 0x804D
|
||||
#define GT911_CONFIG_CHECKSUM_REG 0x80FF
|
||||
|
||||
#define GT911_PRODUCT_ID_REG 0x8140
|
||||
#define GT911_FIRMWARE_VERSION_REG 0x8144
|
||||
#define GT911_VENDOR_ID_REG 0x814A
|
||||
#define GT911_READ_XY_REG 0x814E
|
||||
#define GT911_TP1_REG 0x8150
|
||||
#define GT911_TP2_REG 0x8158
|
||||
#define GT911_TP3_REG 0x8160
|
||||
#define GT911_TP4_REG 0x8168
|
||||
#define GT911_TP5_REG 0x8170
|
||||
|
||||
PACK(typedef struct {
|
||||
uint8_t track;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t size;
|
||||
uint8_t reserved;
|
||||
}) TouchPoint;
|
||||
|
||||
PACK(struct TouchData {
|
||||
union
|
||||
{
|
||||
TouchPoint points[GT911_MAX_TP];
|
||||
uint8_t data[GT911_MAX_TP * sizeof(TouchPoint)];
|
||||
};
|
||||
});
|
||||
@@ -82,6 +82,8 @@ static inline void check_struct()
|
||||
CHKSIZE(RadioData, 1183);
|
||||
#elif defined(RADIO_V12)
|
||||
CHKSIZE(RadioData, 1180);
|
||||
#elif defined(RADIO_H17)
|
||||
CHKSIZE(RadioData, 1060);
|
||||
#elif defined(COLORLCD)
|
||||
#if defined(IMU)
|
||||
CHKSIZE(RadioData, 1063);
|
||||
@@ -116,7 +118,7 @@ static inline void check_struct()
|
||||
CHKSIZE(ModelData, 7641);
|
||||
#elif defined(RADIO_V12)
|
||||
CHKSIZE(ModelData, 7640);
|
||||
#elif defined(PCBC14)
|
||||
#elif defined(PCBC14) || defined(RADIO_H17)
|
||||
CHKSIZE(ModelData, 7573);
|
||||
#elif defined(PCBPA01)
|
||||
CHKSIZE(ModelData, 7582);
|
||||
|
||||
@@ -438,6 +438,7 @@ void generalDefault()
|
||||
uint8_t defaultCalib[] = DEFAULT_6POS_CALIB;
|
||||
StepsCalibData* calib = (StepsCalibData*)&g_eeGeneral.calib[DEFAULT_6POS_IDX];
|
||||
|
||||
calib->count = XPOTS_MULTIPOS_COUNT - 1;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
calib->steps[i] = defaultCalib[i];
|
||||
}
|
||||
|
||||
@@ -156,6 +156,79 @@ rect_t ViewMainDecoration::getWidgetsZone(bool showTopBar) const
|
||||
return rect_t{x, y, w, h};
|
||||
}
|
||||
|
||||
#if defined(MAIN_VIEW_FLEX_SLOTS)
|
||||
|
||||
// Explicit slot -> flex input map, for targets whose flex order differs
|
||||
enum {
|
||||
SLOT_BOTTOM_LEFT = 0,
|
||||
SLOT_BOTTOM_CENTER,
|
||||
SLOT_BOTTOM_RIGHT,
|
||||
SLOT_LEFT,
|
||||
SLOT_RIGHT,
|
||||
SLOT_LEFT_2,
|
||||
SLOT_RIGHT_2,
|
||||
SLOT_COUNT
|
||||
};
|
||||
|
||||
static const int8_t _flex_slots[SLOT_COUNT] = MAIN_VIEW_FLEX_SLOTS;
|
||||
|
||||
static int slotPot(uint8_t slot)
|
||||
{
|
||||
int pot = _flex_slots[slot];
|
||||
if (pot < 0 || pot >= adcGetMaxInputs(ADC_INPUT_FLEX)) return -1;
|
||||
return IS_POT_AVAILABLE(pot) ? pot : -1;
|
||||
}
|
||||
|
||||
void ViewMainDecoration::createSliders(Window* ml, Window* mr, Window* bl, Window* bc, Window* br)
|
||||
{
|
||||
int pot;
|
||||
|
||||
if ((pot = slotPot(SLOT_BOTTOM_LEFT)) >= 0)
|
||||
sliders[pot] = new MainViewHorizontalSlider(bl, pot);
|
||||
|
||||
if ((pot = slotPot(SLOT_BOTTOM_CENTER)) >= 0) {
|
||||
if (IS_POT_MULTIPOS(pot)) {
|
||||
has6POS = true;
|
||||
sliders[pot] = new MainView6POS(bc, pot);
|
||||
} else {
|
||||
sliders[pot] = new MainViewHorizontalSlider(bc, pot);
|
||||
}
|
||||
}
|
||||
|
||||
if ((pot = slotPot(SLOT_BOTTOM_RIGHT)) >= 0)
|
||||
sliders[pot] = new MainViewHorizontalSlider(br, pot);
|
||||
|
||||
int left = slotPot(SLOT_LEFT);
|
||||
int right = slotPot(SLOT_RIGHT);
|
||||
int left2 = slotPot(SLOT_LEFT_2);
|
||||
int right2 = slotPot(SLOT_RIGHT_2);
|
||||
|
||||
if (left >= 0 || right >= 0 || left2 >= 0 || right2 >= 0) {
|
||||
hasVerticalSliders = true;
|
||||
|
||||
auto leftPots = layoutBox(ml, LV_ALIGN_LEFT_MID, LV_FLEX_FLOW_COLUMN);
|
||||
leftPots->setHeight(MainViewSlider::VERTICAL_SLIDERS_HEIGHT);
|
||||
|
||||
auto rightPots = layoutBox(mr, LV_ALIGN_RIGHT_MID, LV_FLEX_FLOW_COLUMN);
|
||||
rightPots->setHeight(MainViewSlider::VERTICAL_SLIDERS_HEIGHT);
|
||||
|
||||
coord_t lsh = (left2 >= 0) ? MainViewSlider::VERTICAL_SLIDERS_HEIGHT / 2 : MainViewSlider::VERTICAL_SLIDERS_HEIGHT;
|
||||
coord_t rsh = (right2 >= 0) ? MainViewSlider::VERTICAL_SLIDERS_HEIGHT / 2 : MainViewSlider::VERTICAL_SLIDERS_HEIGHT;
|
||||
|
||||
for (auto p : {left, left2}) {
|
||||
if (p >= 0)
|
||||
sliders[p] = new MainViewVerticalSlider(leftPots, rect_t{0, 0, MainViewSlider::SLIDER_BAR_SIZE, lsh}, p);
|
||||
}
|
||||
|
||||
for (auto p : {right, right2}) {
|
||||
if (p >= 0)
|
||||
sliders[p] = new MainViewVerticalSlider(rightPots, rect_t{0, 0, MainViewSlider::SLIDER_BAR_SIZE, rsh}, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ViewMainDecoration::createSliders(Window* ml, Window* mr, Window* bl, Window* bc, Window* br)
|
||||
{
|
||||
int pot = 0;
|
||||
@@ -238,6 +311,8 @@ void ViewMainDecoration::createSliders(Window* ml, Window* mr, Window* bl, Windo
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MAIN_VIEW_FLEX_SLOTS
|
||||
|
||||
void ViewMainDecoration::createTrims(Window* ml, Window* mr, Window* bl, Window* br)
|
||||
{
|
||||
// Trim order TRIM_LH, TRIM_LV, TRIM_RV, TRIM_RH
|
||||
|
||||
@@ -50,6 +50,8 @@ elseif(PCB STREQUAL TX15)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_gx15.cpp)
|
||||
elseif(PCB STREQUAL TX16SMK3)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tx16smk3.cpp)
|
||||
elseif(PCB STREQUAL H17)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_h17.cpp)
|
||||
elseif(PCB STREQUAL X7)
|
||||
if(PCBREV STREQUAL TPRO)
|
||||
set(YAML_GEN_OUTPUT storage/yaml/yaml_datastructs_tpro.cpp)
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#include "yaml_datastructs_tx16smk3.cpp"
|
||||
#elif defined(PCBV12)
|
||||
#include "yaml_datastructs_v12.cpp"
|
||||
#elif defined(PCBH17)
|
||||
#include "yaml_datastructs_h17.cpp"
|
||||
#elif defined(RADIO_T22)
|
||||
#include "yaml_datastructs_t22.cpp"
|
||||
#elif defined(PCBPL18)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -89,6 +89,29 @@ void audioUnmute()
|
||||
}
|
||||
#endif
|
||||
|
||||
// DAC output channel; a board on DAC1_OUT2 (PA5) sets AUDIO_DAC_CH 2 in hal.h
|
||||
#ifndef AUDIO_DAC_CH
|
||||
#define AUDIO_DAC_CH 1
|
||||
#endif
|
||||
|
||||
#define _AUDIO_DAC_CAT(a, b) a##b
|
||||
#define _AUDIO_DAC_XCAT(a, b) _AUDIO_DAC_CAT(a, b)
|
||||
|
||||
#define AUDIO_DAC_CHANNEL _AUDIO_DAC_XCAT(LL_DAC_CHANNEL_, AUDIO_DAC_CH)
|
||||
#define AUDIO_DAC_DHR12L _AUDIO_DAC_XCAT(DHR12L, AUDIO_DAC_CH)
|
||||
#define AUDIO_DAC_CR_EN _AUDIO_DAC_XCAT(DAC_CR_EN, AUDIO_DAC_CH)
|
||||
#define AUDIO_DAC_CR_TEN _AUDIO_DAC_XCAT(DAC_CR_TEN, AUDIO_DAC_CH)
|
||||
#define AUDIO_DAC_CR_DMAEN _AUDIO_DAC_XCAT(DAC_CR_DMAEN, AUDIO_DAC_CH)
|
||||
#define AUDIO_DAC_SR_DMAUDR _AUDIO_DAC_XCAT(DAC_SR_DMAUDR, AUDIO_DAC_CH)
|
||||
#define AUDIO_DAC_CLEAR_DMAUDR() _AUDIO_DAC_XCAT(LL_DAC_ClearFlag_DMAUDR, AUDIO_DAC_CH)(AUDIO_DAC)
|
||||
|
||||
// Channel-2 control/trigger bits sit 16 bits above the channel-1 ones
|
||||
#if AUDIO_DAC_CH == 2
|
||||
#define AUDIO_DAC_TRIGGER (DAC_TRIGGER << 16)
|
||||
#else
|
||||
#define AUDIO_DAC_TRIGGER DAC_TRIGGER
|
||||
#endif
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32H7RS)
|
||||
|
||||
#define DAC_TRIGGER LL_DAC_TRIG_EXT_TIM6_TRGO
|
||||
@@ -165,7 +188,7 @@ static void dac_dma_init()
|
||||
dmaInit.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD;
|
||||
dmaInit.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD;
|
||||
dmaInit.PeriphOrM2MSrcAddress = LL_DAC_DMA_GetRegAddr(
|
||||
DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED);
|
||||
AUDIO_DAC, AUDIO_DAC_CHANNEL, LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED);
|
||||
dmaInit.MemoryOrM2MDstAddress = (uintptr_t)_dma_buffer;
|
||||
dmaInit.NbData = DMA_BUFFER_LEN;
|
||||
#elif defined(STM32H7RS)
|
||||
@@ -215,10 +238,10 @@ static void dac_start_dma()
|
||||
LL_DMA_EnableStream(AUDIO_DMA, AUDIO_DMA_Stream);
|
||||
|
||||
// clear underrun flag
|
||||
LL_DAC_ClearFlag_DMAUDR1(AUDIO_DAC);
|
||||
AUDIO_DAC_CLEAR_DMAUDR();
|
||||
|
||||
// enable DAC
|
||||
AUDIO_DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1;
|
||||
AUDIO_DAC->CR |= AUDIO_DAC_CR_EN | AUDIO_DAC_CR_DMAEN;
|
||||
}
|
||||
|
||||
void audioConsumeCurrentBuffer()
|
||||
@@ -407,14 +430,14 @@ static void dac_periph_init()
|
||||
gpio_init_analog(AUDIO_OUTPUT_GPIO);
|
||||
|
||||
// set data registre to silence
|
||||
AUDIO_DAC->DHR12L1 = AUDIO_DATA_SILENCE;
|
||||
AUDIO_DAC->AUDIO_DAC_DHR12L = AUDIO_DATA_SILENCE;
|
||||
|
||||
// clear underrun flag
|
||||
AUDIO_DAC->SR = DAC_SR_DMAUDR1;
|
||||
AUDIO_DAC->SR = AUDIO_DAC_SR_DMAUDR;
|
||||
|
||||
// use TIM6 TRGO as trigger
|
||||
// enable DAC & channel 1 trigger
|
||||
AUDIO_DAC->CR = DAC_CR_TEN1 | DAC_CR_EN1 | DAC_TRIGGER;
|
||||
// enable DAC & channel trigger
|
||||
AUDIO_DAC->CR = AUDIO_DAC_CR_TEN | AUDIO_DAC_CR_EN | AUDIO_DAC_TRIGGER;
|
||||
}
|
||||
|
||||
// Configure DAC0
|
||||
|
||||
@@ -274,7 +274,11 @@ static DSTATUS sdio_initialize(BYTE lun)
|
||||
{
|
||||
#if defined(SD2_PRESENT_GPIO)
|
||||
/* Define active SD */
|
||||
if (gpio_read(SD2_PRESENT_GPIO) == 0) {
|
||||
// SD_SDIO2_ONLY: no internal SDMMC1 to fall back to, always use the reader
|
||||
#if !defined(SD_SDIO2_ONLY)
|
||||
if (gpio_read(SD2_PRESENT_GPIO) == 0)
|
||||
#endif
|
||||
{
|
||||
currentSD.periph = SDMMC2;
|
||||
currentSD.D0 = SD2_SDIO_PIN_D0;
|
||||
currentSD.AF_D0 = SD2_SDIO_AF_D0;
|
||||
@@ -391,7 +395,12 @@ static DSTATUS sdio_status(BYTE lun)
|
||||
{
|
||||
DSTATUS stat = RES_OK;
|
||||
|
||||
#if defined(SD2_PRESENT_GPIO)
|
||||
#if defined(SD_SDIO2_ONLY)
|
||||
// Single SDMMC2 reader: card-detect is just the present pin
|
||||
if (gpio_read(SD2_PRESENT_GPIO)) {
|
||||
stat |= STA_NODISK;
|
||||
}
|
||||
#elif defined(SD2_PRESENT_GPIO)
|
||||
if (currentSD.periph == SDMMC2 && gpio_read(SD2_PRESENT_GPIO)) {
|
||||
stat |= STA_NODISK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON)
|
||||
option(PXX1 "PXX1 protocol support" ON)
|
||||
option(PXX2 "PXX2 protocol support" ON)
|
||||
option(AFHDS3 "AFHDS3 TX Module" ON)
|
||||
option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON)
|
||||
option(GHOST "Ghost TX Module" ON)
|
||||
option(MODULE_SIZE_STD "Standard size TX Module" ON)
|
||||
option(LUA_MIXER "Enable LUA mixer/model scripts support" ON)
|
||||
option(DISK_CACHE "Enable SD card disk cache" ON)
|
||||
option(BLUETOOTH "FrSky BT module support" OFF)
|
||||
option(INTERNAL_GPS "Support for internal GPS" ON)
|
||||
|
||||
set(FIRMWARE_QSPI YES)
|
||||
set(FIRMWARE_FORMAT_UF2 YES)
|
||||
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
|
||||
set(CPU_TYPE STM32H7)
|
||||
set(HSE_VALUE 48000000)
|
||||
set(SDCARD YES)
|
||||
set(STORAGE_MODELSLIST YES)
|
||||
set(HAPTIC YES)
|
||||
set(GUI_DIR colorlcd)
|
||||
set(BITMAPS_DIR 480x272)
|
||||
set(TARGET_DIR h17)
|
||||
set(RTC_BACKUP_RAM YES)
|
||||
set(PPM_LIMITS_SYMETRICAL YES)
|
||||
set(USB_SERIAL ON CACHE BOOL "Enable USB serial (CDC)")
|
||||
set(HARDWARE_EXTERNAL_MODULE YES)
|
||||
set(INTERNAL_MODULE_AFHDS3 NO)
|
||||
set(ROTARY_ENCODER YES)
|
||||
set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
|
||||
|
||||
#option(STICK_DEAD_ZONE "Enable sticks dead zone" YES)
|
||||
|
||||
if(BLUETOOTH)
|
||||
set(AUX2_SERIAL OFF)
|
||||
else()
|
||||
set(AUX2_SERIAL ON)
|
||||
endif()
|
||||
|
||||
# for size report script
|
||||
set(CPU_TYPE_FULL STM32H750xB)
|
||||
set(TARGET_LINKER_DIR stm32h750_sdram)
|
||||
set(TARGET_EXTRAM_START 0xD0000000)
|
||||
set(SIZE_TARGET_MEM_DEFINE "MEM_SIZE_SDRAM1=8192")
|
||||
set(FIRMWARE_STRIP_BOOTLOADER YES)
|
||||
|
||||
add_definitions(-DPCBH17 -DPCBHORUS)
|
||||
add_definitions(-DSTM32_SUPPORT_32BIT_TIMERS)
|
||||
add_definitions(-DFIRMWARE_QSPI)
|
||||
add_definitions(-DFIRMWARE_FORMAT_UF2)
|
||||
add_definitions(-DUSE_CUSTOM_EXTI_IRQ)
|
||||
|
||||
set(FLAVOUR h17)
|
||||
add_definitions(-DRADIO_H17)
|
||||
add_definitions(-DMANUFACTURER_SENDUWING)
|
||||
|
||||
# defines existing internal modules
|
||||
set(INTERNAL_MODULES CRSF CACHE STRING "Internal modules")
|
||||
set(DEFAULT_INTERNAL_MODULE CROSSFIRE CACHE STRING "Default internal module")
|
||||
|
||||
set(BITMAPS_TARGET bm480_bitmaps)
|
||||
set(FONTS_TARGET x12_fonts)
|
||||
set(LCD_DRIVER lcd_driver.cpp)
|
||||
set(HARDWARE_TOUCH YES)
|
||||
set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET})
|
||||
set(FIRMWARE_DEPENDENCIES datacopy)
|
||||
set(SOFTWARE_KEYBOARD ON)
|
||||
set(FLYSKY_GIMBAL OFF)
|
||||
set(AUX_SERIAL YES)
|
||||
set(AUX2_SERIAL YES)
|
||||
|
||||
add_definitions(
|
||||
-DSTM32H750XBTx -DSTM32H750xx
|
||||
-DSDRAM -DCCMRAM
|
||||
-DHARDWARE_TOUCH -DHARDWARE_KEYS -DSOFTWARE_KEYBOARD
|
||||
)
|
||||
|
||||
set(SDRAM ON)
|
||||
|
||||
add_definitions(-DSOFTWARE_VOLUME)
|
||||
add_definitions(-DRTCLOCK)
|
||||
add_definitions(-DPWR_BUTTON_${PWR_BUTTON})
|
||||
add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE})
|
||||
|
||||
if(STICK_DEAD_ZONE)
|
||||
add_definitions(-DSTICK_DEAD_ZONE)
|
||||
endif()
|
||||
|
||||
if(NOT UNEXPECTED_SHUTDOWN)
|
||||
add_definitions(-DNO_UNEXPECTED_SHUTDOWN)
|
||||
endif()
|
||||
|
||||
if(DISK_CACHE)
|
||||
set(SRC ${SRC} disk_cache.cpp)
|
||||
add_definitions(-DDISK_CACHE)
|
||||
endif()
|
||||
|
||||
if(INTERNAL_GPS)
|
||||
message("-- Internal GPS enabled")
|
||||
add_definitions(-DINTERNAL_GPS)
|
||||
add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE})
|
||||
set(SRC ${SRC} gps.cpp gps_nmea.cpp gps_ubx.cpp)
|
||||
endif()
|
||||
|
||||
set(AFHDS3 ON)
|
||||
|
||||
# VCP CLI
|
||||
set(ENABLE_SERIAL_PASSTHROUGH ON CACHE BOOL "Enable serial passthrough")
|
||||
set(CLI ON CACHE BOOL "Enable CLI")
|
||||
|
||||
set(BOARD senduwing-h750)
|
||||
set(BOARD_SRC_DIR boards/${BOARD})
|
||||
include_directories(boards/${BOARD})
|
||||
|
||||
set(TARGET_SRC_DIR targets/${TARGET_DIR})
|
||||
|
||||
set(BOARD_COMMON_SRC
|
||||
${BOARD_SRC_DIR}/board.cpp
|
||||
${BOARD_SRC_DIR}/key_driver.cpp
|
||||
${BOARD_SRC_DIR}/lcd_driver.cpp
|
||||
${BOARD_SRC_DIR}/backlight_driver.cpp
|
||||
${BOARD_SRC_DIR}/haptic_driver.cpp
|
||||
${BOARD_SRC_DIR}/extflash_driver.cpp
|
||||
targets/common/arm/stm32/abnormal_reboot.cpp
|
||||
targets/common/arm/stm32/delays_driver.cpp
|
||||
targets/common/arm/stm32/dma2d.cpp
|
||||
targets/common/arm/stm32/flash_driver.cpp
|
||||
targets/common/arm/stm32/pwr_driver.cpp
|
||||
targets/common/arm/stm32/rotary_encoder_driver.cpp
|
||||
targets/common/arm/stm32/rtc_driver.cpp
|
||||
targets/common/arm/stm32/watchdog_driver.cpp
|
||||
)
|
||||
|
||||
# Bootloader board library
|
||||
add_library(board_bl OBJECT EXCLUDE_FROM_ALL
|
||||
${BOARD_COMMON_SRC}
|
||||
${BOARD_SRC_DIR}/sdram_driver.cpp
|
||||
${RADIO_SRC_DIR}/gui/colorlcd/boot_menu.cpp
|
||||
targets/common/arm/stm32/stm32_qspi.cpp
|
||||
targets/common/arm/stm32/stm32_pulse_driver.cpp
|
||||
)
|
||||
add_dependencies(board_bl minimal_board_lib)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC} $<TARGET_OBJECTS:board_bl>)
|
||||
|
||||
set(CMSIS_SRC ${BOARD_SRC_DIR}/system_clock.c)
|
||||
|
||||
# Firmware board library
|
||||
add_library(board OBJECT EXCLUDE_FROM_ALL
|
||||
${BOARD_COMMON_SRC}
|
||||
${BOARD_SRC_DIR}/tp_gt911.cpp
|
||||
targets/common/arm/stm32/audio_dac_driver.cpp
|
||||
targets/common/arm/stm32/heartbeat_driver.cpp
|
||||
targets/common/arm/stm32/mixer_scheduler_driver.cpp
|
||||
targets/common/arm/stm32/module_timer_driver.cpp
|
||||
targets/common/arm/stm32/stm32_pulse_driver.cpp
|
||||
targets/common/arm/stm32/stm32_softserial_driver.cpp
|
||||
targets/common/arm/stm32/stm32_qspi.cpp
|
||||
targets/common/arm/stm32/stm32_switch_driver.cpp
|
||||
targets/common/arm/stm32/trainer_driver.cpp
|
||||
)
|
||||
add_dependencies(board board_lib)
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} $<TARGET_OBJECTS:board>)
|
||||
|
||||
if(BLUETOOTH)
|
||||
target_sources(board PRIVATE targets/common/arm/stm32/bluetooth_driver.cpp)
|
||||
endif()
|
||||
|
||||
include_directories(${RADIO_SRC_DIR}/fonts/colorlcd gui/${GUI_DIR} gui/${GUI_DIR}/layouts)
|
||||
|
||||
if(BOOTLOADER)
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
../../bootloader/loadboot.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
${SRC}
|
||||
io/frsky_firmware_update.cpp
|
||||
io/multi_firmware_update.cpp
|
||||
)
|
||||
|
||||
if (MULTIMODULE)
|
||||
add_definitions(-DMULTI_PROTOLIST)
|
||||
set(SRC ${SRC}
|
||||
io/multi_protolist.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Make malloc() thread-safe
|
||||
add_definitions(-DTHREADSAFE_MALLOC)
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Senduwing H17 - STM32H750XBH6
|
||||
|
||||
Hardware notes (vs RadioMaster TX15, on which the display/LTDC wiring is based):
|
||||
- No I2C IO expander: switches, keys and trims are wired directly to GPIO
|
||||
(see boards/hw_defs/h17.json which is the source of truth for those).
|
||||
- Parallel RGB (LTDC) panel, no MCU-side SPI configuration bus.
|
||||
- Analog audio through DAC1 + external amplifier with hardware mute.
|
||||
|
||||
DMA1
|
||||
Stream0: AUDIO_DMA_Stream (DAC)
|
||||
Stream1: INTMODULE_DMA_STREAM
|
||||
Stream2:
|
||||
Stream3: TELEMETRY_DMA_Stream_RX
|
||||
Stream4:
|
||||
Stream5: INTMODULE_RX_DMA_STREAM
|
||||
Stream6: AUX2_SERIAL_DMA_RX_STREAM
|
||||
Stream7: TELEMETRY_DMA_Stream_TX
|
||||
|
||||
DMA2
|
||||
Stream0: ADC_EXT_DMA_STREAM (do not move)
|
||||
Stream1: AUX_SERIAL_DMA_TX_STREAM
|
||||
Stream2: AUX_SERIAL_DMA_RX_STREAM
|
||||
Stream3: EXTMODULE_TIMER_DMA_STREAM
|
||||
Stream4: ADC_DMA_STREAM (do not move)
|
||||
Stream5: EXTMODULE_USART_RX_DMA_STREAM
|
||||
Stream6: EXTMODULE_USART_TX_DMA_STREAM
|
||||
Stream7: AUX2_SERIAL_DMA_TX_STREAM
|
||||
|
||||
TIM1: BACKLIGHT_TIMER
|
||||
TIM3: HAPTIC_GPIO_TIMER
|
||||
TIM5: EXTMODULE_TIMER
|
||||
TIM6: AUDIO_TIMER
|
||||
TIM8: TRAINER_TIMER
|
||||
TIM12: MIXER_SCHEDULER_TIMER
|
||||
TIM14: MS_TIMER
|
||||
TIM17: ROTARY_ENCODER_TIMER
|
||||
*/
|
||||
|
||||
#ifndef _HAL_H_
|
||||
#define _HAL_H_
|
||||
|
||||
// Clocks, timers, LCD, backlight, haptic, status LEDs and rotenc: see h17.json
|
||||
#include "hal_settings.h"
|
||||
|
||||
// ADC
|
||||
#define ADC_VREF_PREC2 330
|
||||
|
||||
// P2 is an analog 6POS (FLEX_MULTIPOS), steps measured on H17 hardware.
|
||||
// DEFAULT_6POS_IDX = calib index 8 (4 sticks + flex idx 4).
|
||||
#define XPOS_CALIB_DEFAULT {0x5, 0xe, 0x17, 0x20, 0x29}
|
||||
#define DEFAULT_6POS_CALIB {5, 14, 23, 32, 41}
|
||||
#define DEFAULT_6POS_IDX 8
|
||||
|
||||
// Flex inputs are declared as S1,S2,S3,S4,6POS for the hardware pages; the
|
||||
// main view slots { BL, BC, BR, left, right, left2, right2 } map back here.
|
||||
#define MAIN_VIEW_FLEX_SLOTS { 0, 4, 3, 1, 2, 5, 6 }
|
||||
|
||||
// Power
|
||||
#define PWR_SWITCH_GPIO GPIO_PIN(GPIOA, 4) // PWR_BUTTON
|
||||
#define PWR_ON_GPIO GPIO_PIN(GPIOH, 12) // PWR_ON
|
||||
|
||||
// No USB charger on this board.
|
||||
|
||||
// S.Port update connector
|
||||
#define HAS_SPORT_UPDATE_CONNECTOR() (false)
|
||||
|
||||
// Telemetry (internal module S.PORT / CRSF telemetry line on PA9)
|
||||
#define TELEMETRY_SET_INPUT 0
|
||||
#define TELEMETRY_TX_GPIO GPIO_PIN(GPIOA, 9)
|
||||
#define TELEMETRY_RX_GPIO GPIO_UNDEF
|
||||
#define TELEMETRY_USART USART1
|
||||
#define TELEMETRY_USART_IRQn USART1_IRQn
|
||||
#define TELEMETRY_DMA DMA1
|
||||
#define TELEMETRY_DMA_Stream_TX LL_DMA_STREAM_7
|
||||
#define TELEMETRY_DMA_Channel_TX LL_DMAMUX1_REQ_USART1_TX
|
||||
#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream7_IRQn
|
||||
#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
|
||||
#define TELEMETRY_DMA_Stream_RX LL_DMA_STREAM_3
|
||||
#define TELEMETRY_DMA_Channel_RX LL_DMAMUX1_REQ_USART1_RX
|
||||
#define TELEMETRY_USART_IRQHandler USART1_IRQHandler
|
||||
|
||||
// Software IRQ (Prio 5 -> FreeRTOS compatible)
|
||||
#define TELEMETRY_USE_CUSTOM_EXTI
|
||||
#define CUSTOM_EXTI_IRQ_NAME ETH_WKUP_IRQ
|
||||
#define ETH_WKUP_IRQ_Priority 5
|
||||
#define CUSTOM_EXTI_IRQ_LINE 86
|
||||
#define TELEMETRY_RX_FRAME_EXTI_LINE CUSTOM_EXTI_IRQ_LINE
|
||||
|
||||
// USB
|
||||
#define USB_GPIO GPIOA
|
||||
#define USB_GPIO_VBUS GPIO_PIN(GPIOH, 5)
|
||||
#define USB_GPIO_DM GPIO_PIN(GPIOA, 11)
|
||||
#define USB_GPIO_DP GPIO_PIN(GPIOA, 12)
|
||||
#define USB_GPIO_AF GPIO_AF10
|
||||
|
||||
// LCD - parallel RGB (LTDC), no SPI configuration bus (see lcd_driver.cpp)
|
||||
#define LCD_RESET_GPIO GPIOJ
|
||||
#define LCD_RESET_GPIO_PIN LL_GPIO_PIN_12
|
||||
|
||||
// QSPI Flash
|
||||
#define QSPI_CLK_GPIO GPIO_PIN(GPIOF, 10)
|
||||
#define QSPI_CLK_GPIO_AF GPIO_AF9
|
||||
#define QSPI_CS_GPIO GPIO_PIN(GPIOG, 6)
|
||||
#define QSPI_CS_GPIO_AF GPIO_AF10
|
||||
#define QSPI_MISO_GPIO GPIO_PIN(GPIOF, 9)
|
||||
#define QSPI_MISO_GPIO_AF GPIO_AF10
|
||||
#define QSPI_MOSI_GPIO GPIO_PIN(GPIOF, 8)
|
||||
#define QSPI_MOSI_GPIO_AF GPIO_AF10
|
||||
#define QSPI_WP_GPIO GPIO_PIN(GPIOF, 7)
|
||||
#define QSPI_WP_GPIO_AF GPIO_AF9
|
||||
#define QSPI_HOLD_GPIO GPIO_PIN(GPIOF, 6)
|
||||
#define QSPI_HOLD_GPIO_AF GPIO_AF9
|
||||
#define QSPI_FLASH_SIZE 0x1000000
|
||||
|
||||
// SD (SDIO) - only the external reader on SDMMC2, no internal SDMMC1 device
|
||||
#define SD_SDIO2_ONLY
|
||||
|
||||
#define SD_SDIO SDMMC1
|
||||
#define SD_SDIO_CLK_DIV(fq) (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC) / (2 * fq))
|
||||
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) // Hz
|
||||
|
||||
#define SD2_PRESENT_GPIO GPIO_PIN(GPIOH, 8) // PH.08
|
||||
#define SD2_SDIO SDMMC2
|
||||
#define SD2_SDIO_PIN_D0 GPIO_PIN(GPIOB, 14)
|
||||
#define SD2_SDIO_AF_D0 GPIO_AF9
|
||||
#define SD2_SDIO_PIN_D1 GPIO_PIN(GPIOB, 15)
|
||||
#define SD2_SDIO_AF_D1 GPIO_AF9
|
||||
#define SD2_SDIO_PIN_D2 GPIO_PIN(GPIOG, 11)
|
||||
#define SD2_SDIO_AF_D2 GPIO_AF10
|
||||
#define SD2_SDIO_PIN_D3 GPIO_PIN(GPIOB, 4)
|
||||
#define SD2_SDIO_AF_D3 GPIO_AF9
|
||||
#define SD2_SDIO_PIN_CLK GPIO_PIN(GPIOD, 6)
|
||||
#define SD2_SDIO_AF_CLK GPIO_AF11
|
||||
#define SD2_SDIO_PIN_CMD GPIO_PIN(GPIOD, 7)
|
||||
#define SD2_SDIO_AF_CMD GPIO_AF11
|
||||
#define SD2_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000) // Hz
|
||||
|
||||
#define STORAGE_USE_SDIO
|
||||
|
||||
// AUDIO (analog, DAC1 channel 2 / PA5 + external amp with hardware mute)
|
||||
#define AUDIO_MUTE_GPIO GPIO_PIN(GPIOH, 10)
|
||||
#define AUDIO_MUTE_DELAY 200 // ms
|
||||
#define AUDIO_UNMUTE_DELAY 100 // ms
|
||||
#define AUDIO_OUTPUT_GPIO GPIO_PIN(GPIOA, 5) // DAC1_OUT2
|
||||
#define AUDIO_DAC DAC1
|
||||
#define AUDIO_DAC_CH 2
|
||||
#define AUDIO_DMA DMA1
|
||||
#define AUDIO_DMA_Stream LL_DMA_STREAM_0
|
||||
#define AUDIO_DMA_Channel LL_DMAMUX1_REQ_DAC1_CH2
|
||||
#define AUDIO_TIM_IRQn TIM6_DAC_IRQn
|
||||
#define AUDIO_TIM_IRQHandler TIM6_DAC_IRQHandler
|
||||
#define AUDIO_DMA_Stream_IRQn DMA1_Stream0_IRQn
|
||||
#define AUDIO_DMA_Stream_IRQHandler DMA1_Stream0_IRQHandler
|
||||
#define AUDIO_TIMER TIM6
|
||||
|
||||
// I2C Bus (touch)
|
||||
#define I2C_B1 I2C4
|
||||
#define I2C_B1_SDA_GPIO GPIO_PIN(GPIOD, 13) // PD.13
|
||||
#define I2C_B1_SCL_GPIO GPIO_PIN(GPIOD, 12) // PD.12
|
||||
#define I2C_B1_GPIO_AF LL_GPIO_AF_4
|
||||
#define I2C_B1_CLK_RATE 400000
|
||||
|
||||
// Internal Module (CRSF)
|
||||
#define INTMODULE_PWR_GPIO GPIO_PIN(GPIOB, 13) // PB.13
|
||||
#define INTMODULE_BOOTCMD_GPIO GPIO_PIN(GPIOH, 9) // PH.09
|
||||
#define INTMODULE_BOOTCMD_DEFAULT 0
|
||||
#define INTMODULE_TX_GPIO GPIO_PIN(GPIOG, 14)
|
||||
#define INTMODULE_RX_GPIO GPIO_PIN(GPIOG, 9)
|
||||
#define INTMODULE_USART USART6
|
||||
#define INTMODULE_GPIO_AF LL_GPIO_AF_7
|
||||
#define INTMODULE_USART_IRQn USART6_IRQn
|
||||
#define INTMODULE_USART_IRQHandler USART6_IRQHandler
|
||||
#define INTMODULE_DMA DMA1
|
||||
#define INTMODULE_DMA_STREAM LL_DMA_STREAM_1
|
||||
#define INTMODULE_DMA_STREAM_IRQ DMA1_Stream1_IRQn
|
||||
#define INTMODULE_DMA_FLAG_TC DMA_FLAG_TCIF1
|
||||
#define INTMODULE_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_TX
|
||||
#define INTMODULE_RX_DMA DMA1
|
||||
#define INTMODULE_RX_DMA_STREAM LL_DMA_STREAM_5
|
||||
#define INTMODULE_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART6_RX
|
||||
#define INTMODULE_RX_DMA_Stream_IRQn DMA1_Stream5_IRQn
|
||||
#define INTMODULE_RX_DMA_Stream_IRQHandler DMA1_Stream5_IRQHandler
|
||||
|
||||
// External Module
|
||||
#define EXTMODULE
|
||||
#define EXTMODULE_PULSES
|
||||
#define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOD, 4) // PD.04
|
||||
#define EXTMODULE_TX_GPIO GPIO_PIN(GPIOA, 2) // TIM5_CH3
|
||||
#define EXTMODULE_RX_GPIO GPIO_PIN(GPIOA, 3)
|
||||
#define EXTMODULE_TX_GPIO_AF LL_GPIO_AF_3 // TIM5_CH3
|
||||
#define EXTMODULE_TIMER TIM5
|
||||
#define EXTMODULE_TIMER_32BITS
|
||||
#define EXTMODULE_TIMER_Channel LL_TIM_CHANNEL_CH3
|
||||
#define EXTMODULE_TIMER_IRQn TIM5_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM5_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
#define EXTMODULE_TIMER_TX_GPIO_AF LL_GPIO_AF_2
|
||||
|
||||
//USART
|
||||
#define EXTMODULE_USART USART2
|
||||
#define EXTMODULE_USART_TX_DMA DMA2
|
||||
#define EXTMODULE_USART_TX_DMA_CHANNEL LL_DMAMUX1_REQ_USART2_TX
|
||||
#define EXTMODULE_USART_TX_DMA_STREAM LL_DMA_STREAM_6
|
||||
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMAMUX1_REQ_USART2_RX
|
||||
#define EXTMODULE_USART_RX_DMA_STREAM LL_DMA_STREAM_5
|
||||
#define EXTMODULE_USART_IRQHandler USART2_IRQHandler
|
||||
#define EXTMODULE_USART_IRQn USART2_IRQn
|
||||
|
||||
//TIMER
|
||||
#define EXTMODULE_TIMER_DMA_CHANNEL LL_DMAMUX1_REQ_TIM5_UP
|
||||
#define EXTMODULE_TIMER_DMA DMA2
|
||||
#define EXTMODULE_TIMER_DMA_STREAM LL_DMA_STREAM_3
|
||||
#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream3_IRQn
|
||||
#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream3_IRQHandler
|
||||
|
||||
// Trainer Port
|
||||
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA)
|
||||
|
||||
#define TRAINER_IN_GPIO GPIO_PIN(GPIOI, 6)
|
||||
#define TRAINER_IN_TIMER_Channel LL_TIM_CHANNEL_CH2
|
||||
|
||||
#define TRAINER_OUT_GPIO GPIO_PIN(GPIOI, 5)
|
||||
#define TRAINER_OUT_TIMER_Channel LL_TIM_CHANNEL_CH1
|
||||
|
||||
#define TRAINER_TIMER TIM8
|
||||
#define TRAINER_TIMER_IRQn TIM8_CC_IRQn
|
||||
#define TRAINER_TIMER_IRQHandler TIM8_CC_IRQHandler
|
||||
#define TRAINER_GPIO_AF LL_GPIO_AF_3
|
||||
#define TRAINER_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
|
||||
#define TRAINER_DETECT_GPIO GPIO_PIN(GPIOH, 4)
|
||||
|
||||
// AUX ports
|
||||
#define AUX_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 6) // PB.06
|
||||
#define AUX_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 5) // PB.05
|
||||
#define AUX_SERIAL_USART UART5
|
||||
#define AUX_SERIAL_USART_IRQHandler UART5_IRQHandler
|
||||
#define AUX_SERIAL_USART_IRQn UART5_IRQn
|
||||
#define AUX_SERIAL_DMA_TX DMA2
|
||||
#define AUX_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_1
|
||||
#define AUX_SERIAL_DMA_TX_CHANNEL LL_DMAMUX1_REQ_UART5_TX
|
||||
#define AUX_SERIAL_DMA_RX DMA2
|
||||
#define AUX_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_2
|
||||
#define AUX_SERIAL_DMA_RX_CHANNEL LL_DMAMUX1_REQ_UART5_RX
|
||||
#define AUX_SERIAL_PWR_GPIO GPIO_PIN(GPIOB, 7) // PB.07
|
||||
|
||||
#define AUX2_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 10) // PB.10
|
||||
#define AUX2_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 11) // PB.11
|
||||
#define AUX2_SERIAL_USART USART3
|
||||
#define AUX2_SERIAL_USART_IRQHandler USART3_IRQHandler
|
||||
#define AUX2_SERIAL_USART_IRQn USART3_IRQn
|
||||
#define AUX2_SERIAL_DMA_TX DMA2
|
||||
#define AUX2_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_7
|
||||
#define AUX2_SERIAL_DMA_TX_CHANNEL LL_DMAMUX1_REQ_USART3_TX
|
||||
#define AUX2_SERIAL_DMA_RX DMA1
|
||||
#define AUX2_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_6
|
||||
#define AUX2_SERIAL_DMA_RX_CHANNEL LL_DMAMUX1_REQ_USART3_RX
|
||||
#define AUX2_SERIAL_PWR_GPIO GPIO_PIN(GPIOC, 13) // PC.13
|
||||
|
||||
// Touch
|
||||
#define TOUCH_I2C_BUS I2C_Bus_1
|
||||
#define TOUCH_INT_GPIO GPIO_PIN(GPIOE, 2) // PE.02
|
||||
#define TOUCH_RST_GPIO GPIO_PIN(GPIOJ, 13) // PJ.13
|
||||
|
||||
// TOUCH_INT_EXTI IRQ
|
||||
#if !defined(USE_EXTI2_IRQ)
|
||||
#define USE_EXTI2_IRQ
|
||||
#define EXTI2_IRQ_Priority 9
|
||||
#endif
|
||||
|
||||
// No I2C IO-expander here, so the rotenc exti list carries USE_EXTI9_5_IRQ.
|
||||
|
||||
#define LANDSCAPE_LCD true
|
||||
#define PORTRAIT_LCD false
|
||||
#define LANDSCAPE_LCD_SML false
|
||||
#define LANDSCAPE_LCD_STD true
|
||||
#define LANDSCAPE_LCD_LRG false
|
||||
|
||||
#define LSE_DRIVE_STRENGTH RCC_LSEDRIVE_HIGH
|
||||
|
||||
#endif // _HAL_H_
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 _USB_DESCRIPTOR_H_
|
||||
#define _USB_DESCRIPTOR_H_
|
||||
|
||||
#define USB_NAME "Senduwing H17"
|
||||
#define USB_MANUFACTURER 'S', 'E', 'N', 'D', ' ', ' ', ' ', ' ' /* 8 bytes */
|
||||
#define USB_PRODUCT 'H', '1', '7', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */
|
||||
|
||||
#endif // _USB_DESCRIPTOR_H_
|
||||
@@ -262,6 +262,80 @@ LEGACY_NAMES = [
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": {"h17"},
|
||||
"inputs": {
|
||||
"LH": {
|
||||
"yaml": "Rud",
|
||||
"lua": "rud",
|
||||
"description": "Rudder"
|
||||
},
|
||||
"LV": {
|
||||
"yaml": "Ele",
|
||||
"lua": "ele",
|
||||
"description": "Elevator"
|
||||
},
|
||||
"RV": {
|
||||
"yaml": "Thr",
|
||||
"lua": "thr",
|
||||
"description": "Throttle"
|
||||
},
|
||||
"RH": {
|
||||
"yaml": "Ail",
|
||||
"lua": "ail",
|
||||
"description": "Aileron"
|
||||
},
|
||||
"P1": {
|
||||
"yaml": "S1",
|
||||
"lua": "s1",
|
||||
"label": "S1",
|
||||
"short_label": "1",
|
||||
"description": "Potentiometer S1"
|
||||
},
|
||||
"P2": {
|
||||
"yaml": "6POS",
|
||||
"lua": "6pos",
|
||||
"label": "6POS",
|
||||
"short_label": "6",
|
||||
"description": "Multipos Switch"
|
||||
},
|
||||
"P3": {
|
||||
"yaml": "S4",
|
||||
"lua": "s4",
|
||||
"label": "S4",
|
||||
"short_label": "4",
|
||||
"description": "Potentiometer S4"
|
||||
},
|
||||
"SL1": {
|
||||
"yaml": "S2",
|
||||
"lua": "s2",
|
||||
"label": "S2",
|
||||
"short_label": "2",
|
||||
"description": "Potentiometer S2"
|
||||
},
|
||||
"SL2": {
|
||||
"yaml": "S3",
|
||||
"lua": "s3",
|
||||
"label": "S3",
|
||||
"short_label": "3",
|
||||
"description": "Potentiometer S3"
|
||||
},
|
||||
"EXT1": {
|
||||
"yaml": "EXT1",
|
||||
"lua": "ext1",
|
||||
"label": "EXT1",
|
||||
"short_label": "E1",
|
||||
"description": "Ext 1"
|
||||
},
|
||||
"EXT2": {
|
||||
"yaml": "EXT2",
|
||||
"lua": "ext2",
|
||||
"label": "EXT2",
|
||||
"short_label": "E2",
|
||||
"description": "Ext 2"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"targets": {"x12s"},
|
||||
"inputs": {
|
||||
|
||||
@@ -170,6 +170,9 @@ get_target_build_options() {
|
||||
pa01)
|
||||
BUILD_OPTIONS+="-DPCB=PA01"
|
||||
;;
|
||||
h17)
|
||||
BUILD_OPTIONS+="-DPCB=H17"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown target: $target_name"
|
||||
return 1
|
||||
|
||||
@@ -226,7 +226,7 @@ else
|
||||
tx12mk2 zorro v14 v14lcd
|
||||
x7access x9dp2019 x9e
|
||||
# colour
|
||||
c14 el18 nb4p nv14 st16 pa01
|
||||
c14 el18 h17 nb4p nv14 st16 pa01
|
||||
pl18 pl18ev pl18u
|
||||
t15 t15pro t16 t18 t22
|
||||
tx15 gx15 tx16s tx16smk3 f16 v12 v16
|
||||
|
||||
@@ -9,7 +9,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
: "${SRCDIR:=$(dirname "$(pwd)/$0")/..}"
|
||||
|
||||
: ${FLAVOR:="nv14;el18;pl18;pl18ev;pl18u;nb4p;st16;c14;pa01;t12;t12max;t15;t15pro;t22;t16;t18;t8;zorro;pocket;commando8;tlite;tpro;tprov2;tpros;bumblebee;t20;t20v2;t14;lr3pro;mt12;gx12;tx12;tx12mk2;boxer;tx16s;tx16smk3;x10;x10express;x12s;x7;x7access;x9d;x9dp;x9dp2019;x9e;x9lite;x9lites;xlite;xlites;f16;v16;v14;v14lcd;v12;tx15;gx15"}
|
||||
: ${FLAVOR:="nv14;el18;pl18;pl18ev;pl18u;nb4p;st16;c14;pa01;t12;t12max;t15;t15pro;t22;t16;t18;t8;zorro;pocket;commando8;tlite;tpro;tprov2;tpros;bumblebee;t20;t20v2;t14;lr3pro;mt12;gx12;tx12;tx12mk2;boxer;tx16s;tx16smk3;x10;x10express;x12s;x7;x7access;x9d;x9dp;x9dp2019;x9e;x9lite;x9lites;xlite;xlites;f16;v16;v14;v14lcd;v12;tx15;gx15;h17"}
|
||||
: ${COMMON_OPTIONS:="-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_RULE_MESSAGES=OFF -Wno-dev -DCMAKE_MESSAGE_LOG_LEVEL=WARNING"}
|
||||
|
||||
# wipe build directory clean
|
||||
|
||||
@@ -11,7 +11,7 @@ if [[ -n ${GCC_ARM} ]] ; then
|
||||
export PATH=${GCC_ARM}:$PATH
|
||||
fi
|
||||
|
||||
: ${FLAVOR:="x10;t15;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;c14;pa01;tx15;gx15;t15pro;tx16smk3;t22;v12"}
|
||||
: ${FLAVOR:="x10;t15;pl18;nv14;pl18u;nb4p;x9d;x9dp2019;x9e;xlite;xlites;x7;tpro;t20;f16;gx12;st16;c14;pa01;tx15;gx15;t15pro;tx16smk3;t22;v12;h17"}
|
||||
: ${SRCDIR:="$(dirname "$SCRIPT_DIR")"}
|
||||
|
||||
: ${COMMON_OPTIONS:="-DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_RULE_MESSAGES=OFF -Wno-dev -DDISABLE_COMPANION=YES -DCMAKE_MESSAGE_LOG_LEVEL=WARNING"}
|
||||
|
||||
@@ -6535,5 +6535,181 @@
|
||||
"side": "R"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Senduwing H17",
|
||||
"wasm": "edgetx-h17-simulator.wasm",
|
||||
"display": {
|
||||
"w": 480,
|
||||
"h": 272,
|
||||
"depth": 16
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"name": "LH",
|
||||
"type": "STICK",
|
||||
"label": "LH"
|
||||
},
|
||||
{
|
||||
"name": "LV",
|
||||
"type": "STICK",
|
||||
"label": "LV"
|
||||
},
|
||||
{
|
||||
"name": "RV",
|
||||
"type": "STICK",
|
||||
"label": "RV"
|
||||
},
|
||||
{
|
||||
"name": "RH",
|
||||
"type": "STICK",
|
||||
"label": "RH"
|
||||
},
|
||||
{
|
||||
"name": "P1",
|
||||
"type": "FLEX",
|
||||
"label": "S1",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "SL1",
|
||||
"type": "FLEX",
|
||||
"label": "S2",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "SL2",
|
||||
"type": "FLEX",
|
||||
"label": "S3",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "P3",
|
||||
"type": "FLEX",
|
||||
"label": "S4",
|
||||
"default": "POT"
|
||||
},
|
||||
{
|
||||
"name": "P2",
|
||||
"type": "FLEX",
|
||||
"label": "6POS",
|
||||
"default": "MULTIPOS"
|
||||
},
|
||||
{
|
||||
"name": "EXT1",
|
||||
"type": "FLEX",
|
||||
"label": "EXT1",
|
||||
"default": "NONE"
|
||||
},
|
||||
{
|
||||
"name": "EXT2",
|
||||
"type": "FLEX",
|
||||
"label": "EXT2",
|
||||
"default": "NONE"
|
||||
}
|
||||
],
|
||||
"switches": [
|
||||
{
|
||||
"name": "SA",
|
||||
"type": "3POS",
|
||||
"default": "2POS"
|
||||
},
|
||||
{
|
||||
"name": "SB",
|
||||
"type": "3POS",
|
||||
"default": "3POS"
|
||||
},
|
||||
{
|
||||
"name": "SC",
|
||||
"type": "3POS",
|
||||
"default": "3POS"
|
||||
},
|
||||
{
|
||||
"name": "SD",
|
||||
"type": "3POS",
|
||||
"default": "2POS"
|
||||
},
|
||||
{
|
||||
"name": "SE",
|
||||
"type": "3POS",
|
||||
"default": "3POS"
|
||||
},
|
||||
{
|
||||
"name": "SF",
|
||||
"type": "2POS",
|
||||
"default": "2POS"
|
||||
},
|
||||
{
|
||||
"name": "SG",
|
||||
"type": "2POS",
|
||||
"default": "TOGGLE"
|
||||
},
|
||||
{
|
||||
"name": "SH",
|
||||
"type": "2POS",
|
||||
"default": "TOGGLE"
|
||||
},
|
||||
{
|
||||
"name": "SI",
|
||||
"type": "2POS",
|
||||
"default": "2POS"
|
||||
},
|
||||
{
|
||||
"name": "SJ",
|
||||
"type": "2POS",
|
||||
"default": "2POS"
|
||||
}
|
||||
],
|
||||
"trims": [
|
||||
{
|
||||
"name": "T1"
|
||||
},
|
||||
{
|
||||
"name": "T2"
|
||||
},
|
||||
{
|
||||
"name": "T3"
|
||||
},
|
||||
{
|
||||
"name": "T4"
|
||||
}
|
||||
],
|
||||
"keys": [
|
||||
{
|
||||
"key": "KEY_MODEL",
|
||||
"label": "MDL",
|
||||
"side": "R"
|
||||
},
|
||||
{
|
||||
"key": "KEY_SYS",
|
||||
"label": "SYS",
|
||||
"side": "L"
|
||||
},
|
||||
{
|
||||
"key": "KEY_PAGEUP",
|
||||
"label": "PAGE◀",
|
||||
"side": "L"
|
||||
},
|
||||
{
|
||||
"key": "KEY_PAGEDN",
|
||||
"label": "PAGE▶",
|
||||
"side": "R"
|
||||
},
|
||||
{
|
||||
"key": "KEY_TELE",
|
||||
"label": "TELE",
|
||||
"side": "R"
|
||||
},
|
||||
{
|
||||
"key": "KEY_EXIT",
|
||||
"label": "RTN",
|
||||
"side": "L"
|
||||
},
|
||||
{
|
||||
"key": "KEY_ENTER",
|
||||
"label": "Enter ⏎",
|
||||
"side": "R"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user