Bsongis/horus xjt external module (#3566)
* [Horus] PXX and DSM2 in external module * [Taranis] Pulses driver refactoring (uses DMA also for PPM in external module and saves 800bytes RAM) * Cosmetics (Pulses driver splitted)
This commit is contained in:
@@ -79,7 +79,7 @@ if(PCB STREQUAL HORUS)
|
||||
set(VIRTUAL_INPUTS YES)
|
||||
set(RAMBACKUP YES)
|
||||
option(DISK_CACHE "Enable SD card disk cache" YES)
|
||||
add_definitions(-DPCBHORUS -DCOLORLCD -DSTM32F429_439xx -DPPM_PIN_HW_SERIAL)
|
||||
add_definitions(-DPCBHORUS -DCOLORLCD -DSTM32F429_439xx -DPPM_PIN_UART -DPPM_PIN_TIMER)
|
||||
add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK)
|
||||
add_definitions(-DLUAINPUTS -DXCURVES -DVARIO)
|
||||
include_directories(${RADIO_SRC_DIRECTORY}/fonts/horus gui/${GUI_DIR} gui/${GUI_DIR}/layouts)
|
||||
@@ -111,7 +111,11 @@ if(PCB STREQUAL HORUS)
|
||||
set(SRC ${SRC} disk_cache.cpp)
|
||||
add_definitions(-DDISK_CACHE)
|
||||
endif()
|
||||
set(TARGET_SRC ${TARGET_SRC} board_horus.cpp)
|
||||
set(TARGET_SRC
|
||||
${TARGET_SRC}
|
||||
board_horus.cpp
|
||||
extmodule_driver.cpp
|
||||
)
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
sdio_sd.c
|
||||
@@ -181,12 +185,20 @@ elseif(PCB STREQUAL TARANIS)
|
||||
set(TARGET_DIR taranis)
|
||||
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} taranis_bitmaps)
|
||||
set(VIRTUAL_INPUTS YES)
|
||||
add_definitions(-DPCBTARANIS)
|
||||
add_definitions(-DPCBTARANIS -DPPM_PIN_TIMER)
|
||||
add_definitions(-DAUDIO -DVOICE -DRTCLOCK)
|
||||
add_definitions(-DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DVARIO)
|
||||
set(GUI_SRC ${GUI_SRC} bmp.cpp menu_model_inputs.cpp menu_model_mixes.cpp menu_model_display.cpp menu_general_diagkeys.cpp menu_general_diaganas.cpp menu_general_hardware.cpp view_channels.cpp view_telemetry.cpp view_text.cpp view_about.cpp)
|
||||
set(TARGET_SRC ${TARGET_SRC} board_taranis.cpp rtc_driver.cpp)
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC} loadboot.cpp)
|
||||
set(TARGET_SRC
|
||||
${TARGET_SRC}
|
||||
board_taranis.cpp
|
||||
extmodule_driver.cpp
|
||||
rtc_driver.cpp
|
||||
)
|
||||
set(FIRMWARE_SRC
|
||||
${FIRMWARE_SRC}
|
||||
loadboot.cpp
|
||||
)
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
lcd_driver.cpp
|
||||
@@ -244,7 +256,7 @@ elseif(PCB STREQUAL SKY9X OR PCB STREQUAL 9XRPRO OR PCB STREQUAL AR9X)
|
||||
set(GUI_DIR 9x)
|
||||
set(TARGET_DIR sky9x)
|
||||
set(FIRMWARE_DEPENDENCIES ${FIRMWARE_DEPENDENCIES} 9x_bitmaps)
|
||||
add_definitions(-DPCBSKY9X)
|
||||
add_definitions(-DPCBSKY9X -DPPM_PIN_SERIAL)
|
||||
add_definitions(-DAUDIO -DVOICE -DRTCLOCK -DVARIO)
|
||||
add_definitions(-DEEPROM_VARIANT=0)
|
||||
set(GUI_SRC ${GUI_SRC} ${9X_GUI_SRC} menu_general_hardware.cpp view_telemetry.cpp view_text.cpp view_about.cpp)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -18,7 +18,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#define DSM2_SEND_BIND (1 << 7)
|
||||
#define DSM2_SEND_RANGECHECK (1 << 5)
|
||||
@@ -35,17 +35,17 @@ uint8_t dsm2BindTimer = DSM2_BIND_TIMEOUT;
|
||||
|
||||
#define BITLEN_DSM2 (8*2) //125000 Baud => 8uS per bit
|
||||
|
||||
#if !defined(PPM_PIN_HW_SERIAL)
|
||||
#if !defined(PPM_PIN_SERIAL)
|
||||
void _send_1(uint8_t v)
|
||||
{
|
||||
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index == 0)
|
||||
v -= 2;
|
||||
else
|
||||
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1)
|
||||
v += 2;
|
||||
else
|
||||
v -= 2;
|
||||
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value += v;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.value;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index = (modulePulsesData[EXTERNAL_MODULE].dsm2.index+1) % 2;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index += 1;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.rest -= v;
|
||||
}
|
||||
|
||||
void sendByteDsm2(uint8_t b) //max 10 changes 0 10 10 10 10 1
|
||||
@@ -69,8 +69,10 @@ void sendByteDsm2(uint8_t b) //max 10 changes 0 10 10 10 10 1
|
||||
|
||||
void putDsm2Flush()
|
||||
{
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.ptr--; //remove last stopbits and
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = 44010; // Past the 44000 of the ARR
|
||||
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1)
|
||||
*(modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - 1) = modulePulsesData[EXTERNAL_MODULE].dsm2.rest;
|
||||
else
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.rest;
|
||||
}
|
||||
#else
|
||||
void putDsm2SerialBit(uint8_t bit)
|
||||
@@ -108,26 +110,20 @@ void putDsm2Flush()
|
||||
// This is the data stream to send, prepare after 19.5 mS
|
||||
// Send after 22.5 mS
|
||||
|
||||
//static uint8_t *Dsm2_pulsePtr = pulses2MHz.pbyte ;
|
||||
void setupPulsesDSM2(unsigned int port)
|
||||
void setupPulsesDSM2(uint8_t port)
|
||||
{
|
||||
static uint8_t dsmDat[2+6*2]={0xFF,0x00, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA};
|
||||
uint8_t dsmDat[14];
|
||||
|
||||
#if defined(PPM_PIN_HW_SERIAL)
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ;
|
||||
#else
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value = 0;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index = 1;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.rest = 44000;
|
||||
#endif
|
||||
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
|
||||
|
||||
#if !defined(PPM_PIN_HW_SERIAL)
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value = 100;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.value;
|
||||
#endif
|
||||
|
||||
switch (s_current_protocol[port]) {
|
||||
case PROTO_DSM2_LP45:
|
||||
dsmDat[0] = 0x00;
|
||||
@@ -140,13 +136,7 @@ void setupPulsesDSM2(unsigned int port)
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(PPM_PIN_HW_SERIAL)
|
||||
if (moduleFlag[port] == MODULE_BIND)
|
||||
dsmDat[0] |= DSM2_SEND_BIND;
|
||||
else if (moduleFlag[port] == MODULE_RANGECHECK)
|
||||
dsmDat[0] |= DSM2_SEND_RANGECHECK;
|
||||
#else
|
||||
#if defined(PCBSKY9X) // TODO needed?
|
||||
#if defined(PCBSKY9X)
|
||||
if (dsm2BindTimer > 0) {
|
||||
dsm2BindTimer--;
|
||||
if (switchState(SW_DSM2_BIND)) {
|
||||
@@ -154,14 +144,19 @@ void setupPulsesDSM2(unsigned int port)
|
||||
dsmDat[0] |= DSM2_SEND_BIND;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (moduleFlag[port] == MODULE_RANGECHECK) {
|
||||
else if (moduleFlag[port] == MODULE_RANGECHECK) {
|
||||
dsmDat[0] |= DSM2_SEND_RANGECHECK;
|
||||
}
|
||||
else {
|
||||
moduleFlag[port] = 0;
|
||||
}
|
||||
#else
|
||||
if (moduleFlag[port] == MODULE_BIND) {
|
||||
dsmDat[0] |= DSM2_SEND_BIND;
|
||||
}
|
||||
else if (moduleFlag[port] == MODULE_RANGECHECK) {
|
||||
dsmDat[0] |= DSM2_SEND_RANGECHECK;
|
||||
}
|
||||
#endif
|
||||
|
||||
dsmDat[1] = g_model.header.modelId[port]; // DSM2 Header second byte for model match
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#define BITLEN_MULTI (10*2) //100000 Baud => 10uS per bit
|
||||
|
||||
#if defined(PPM_PIN_HW_SERIAL)
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
static void sendByteMulti(uint8_t b)
|
||||
{
|
||||
uint8_t parity = 1;
|
||||
@@ -56,14 +56,14 @@ static void _send_level(uint8_t v)
|
||||
{
|
||||
/* Copied over from DSM, this looks doubious and in my logic analyzer
|
||||
output the low->high is about 2 ns late */
|
||||
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index == 0)
|
||||
v -= 2;
|
||||
else
|
||||
if (modulePulsesData[EXTERNAL_MODULE].dsm2.index & 1)
|
||||
v += 2;
|
||||
else
|
||||
v -= 2;
|
||||
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value += v;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.value;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index = (modulePulsesData[EXTERNAL_MODULE].dsm2.index+1) % 2;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = v;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index+=1;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.rest -=v;
|
||||
}
|
||||
|
||||
static void sendByteMulti(uint8_t b) //max 11 changes 0 10 10 10 10 P 1
|
||||
@@ -99,24 +99,18 @@ static void sendByteMulti(uint8_t b) //max 11 changes 0 10 10 10 10 P 1
|
||||
|
||||
#define MULTI_CHANS 16
|
||||
#define MULTI_CHAN_BITS 11
|
||||
void setupPulsesMultimodule(unsigned int port)
|
||||
void setupPulsesMultimodule(uint8_t port)
|
||||
{
|
||||
|
||||
#if defined(PPM_PIN_HW_SERIAL)
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.serialByte = 0 ;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.serialBitCount = 0 ;
|
||||
#else
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value = 0;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.rest = 44000;
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.index = 1;
|
||||
#endif
|
||||
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.ptr = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
modulePulsesData[EXTERNAL_MODULE].dsm2.value = 100;
|
||||
*modulePulsesData[EXTERNAL_MODULE].dsm2.ptr++ = modulePulsesData[EXTERNAL_MODULE].dsm2.value;
|
||||
#endif
|
||||
|
||||
// header, byte 0, always 0x55
|
||||
sendByteMulti(0x55);
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include "opentx.h"
|
||||
|
||||
void setupPulsesPPM(unsigned int port) // Don't enable interrupts through here
|
||||
void setupPulsesPPM(uint8_t port) // Don't enable interrupts through here
|
||||
{
|
||||
int16_t PPM_range = g_model.extendedLimits ? (512*LIMIT_EXT_PERCENT/100) * 2 : 512 * 2; //range of 0.7..1.7msec
|
||||
|
||||
@@ -43,23 +43,35 @@ void setupPulsesPPM(unsigned int port) // Don't enable interru
|
||||
#endif
|
||||
|
||||
PpmPulsesData * ppmPulsesData = (port == TRAINER_MODULE ? &trainerPulsesData.ppm : &modulePulsesData[port].ppm);
|
||||
uint16_t * ptr = ppmPulsesData->pulses;
|
||||
|
||||
#if defined(CPUSTM32)
|
||||
ppmPulsesData->ptr = ppmPulsesData->pulses;
|
||||
#else
|
||||
uint16_t * ptr = ppmPulsesData->pulses;
|
||||
ppmPulsesData->ptr = ptr;
|
||||
#endif
|
||||
|
||||
int32_t rest = 22500u * 2;
|
||||
rest += (int32_t(g_model.moduleData[port].ppm.frameLength)) * 1000;
|
||||
for (uint32_t i=firstCh; i<lastCh; i++) {
|
||||
int16_t v = limit((int16_t)-PPM_range, channelOutputs[i], (int16_t)PPM_range) + 2*PPM_CH_CENTER(i);
|
||||
rest -= v;
|
||||
#if defined(CPUSTM32)
|
||||
*ppmPulsesData->ptr++ = v; /* as Pat MacKenzie suggests */
|
||||
#else
|
||||
*ptr++ = v; /* as Pat MacKenzie suggests */
|
||||
#endif
|
||||
}
|
||||
if (rest > 65535) rest = 65535; /* prevents overflows */
|
||||
if (rest < 9000) rest = 9000; /* avoids that CCR2 is bigger than ARR which would cause reboot */
|
||||
#if defined(CPUSTM32)
|
||||
*ppmPulsesData->ptr++ = rest;
|
||||
#else
|
||||
*ptr = rest;
|
||||
*(ptr + 1) = 0;
|
||||
#endif
|
||||
|
||||
#if !defined(PCBSKY9X)
|
||||
#if defined(CPUSTM32)
|
||||
rest -= 1000;
|
||||
uint32_t ppmDelay = (g_model.moduleData[port].ppm.delay * 50 + 300) * 2;
|
||||
// set idle time, ppm delay and ppm polarity
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include "opentx.h"
|
||||
|
||||
uint8_t s_pulses_paused = 0;
|
||||
uint8_t s_current_protocol[NUM_MODULES] = { MODULES_INIT(255) };
|
||||
@@ -28,7 +28,7 @@ uint8_t moduleFlag[NUM_MODULES] = { 0 };
|
||||
ModulePulsesData modulePulsesData[NUM_MODULES] __DMA;
|
||||
TrainerPulsesData trainerPulsesData __DMA;
|
||||
|
||||
void setupPulses(unsigned int port)
|
||||
void setupPulses(uint8_t port)
|
||||
{
|
||||
uint8_t required_protocol;
|
||||
|
||||
@@ -202,9 +202,10 @@ void setupPulses(unsigned int port)
|
||||
}
|
||||
#endif
|
||||
#if defined(MULTIMODULE)
|
||||
case PROTO_MULTIMODULE:
|
||||
setupPulsesMultimodule(port);
|
||||
break;
|
||||
case PROTO_MULTIMODULE:
|
||||
setupPulsesMultimodule(port);
|
||||
scheduleNextMixerCalculation(port, 11);
|
||||
break;
|
||||
#endif
|
||||
case PROTO_PPM:
|
||||
setupPulsesPPM(port);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -27,17 +27,23 @@
|
||||
#define MODULES_INIT(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
#define pulse_duration_t uint32_t
|
||||
#else
|
||||
#define pulse_duration_t uint16_t
|
||||
#endif
|
||||
|
||||
extern uint8_t s_current_protocol[NUM_MODULES];
|
||||
extern uint8_t s_pulses_paused;
|
||||
extern uint16_t failsafeCounter[NUM_MODULES];
|
||||
|
||||
PACK(struct PpmPulsesData {
|
||||
uint16_t pulses[20];
|
||||
uint16_t * ptr;
|
||||
pulse_duration_t pulses[20];
|
||||
pulse_duration_t * ptr;
|
||||
});
|
||||
|
||||
#if defined(PPM_PIN_HW_SERIAL)
|
||||
PACK(struct PxxPulsesData {
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
PACK(struct PxxSerialPulsesData {
|
||||
uint8_t pulses[64];
|
||||
uint8_t *ptr;
|
||||
uint16_t pcmValue;
|
||||
@@ -46,26 +52,49 @@ PACK(struct PxxPulsesData {
|
||||
uint16_t serialByte;
|
||||
uint16_t serialBitCount;
|
||||
});
|
||||
PACK(struct Dsm2PulsesData {
|
||||
|
||||
PACK(struct Dsm2SerialPulsesData {
|
||||
uint8_t pulses[64];
|
||||
uint8_t *ptr;
|
||||
uint8_t serialByte ;
|
||||
uint8_t serialBitCount;
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(PPM_PIN_UART)
|
||||
PACK(struct PxxUartPulsesData {
|
||||
uint8_t pulses[64];
|
||||
uint8_t * ptr;
|
||||
uint16_t pcmCrc;
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(PPM_PIN_TIMER)
|
||||
/* PXX uses 20 bytes (as of Rev 1.1 document) with 8 changes per byte + stop bit ~= 162 max pulses */
|
||||
/* DSM2 uses 2 header + 12 channel bytes, with max 10 changes (8n2) per byte + 16 bits trailer ~= 156 max pulses */
|
||||
/* Multimodule uses 3 bytes header + 22 channel bytes with max 11 changes per byte (8e2) + 16 bits trailer ~= 291 max pulses */
|
||||
/* Multimodule reuses some of the DSM2 function and structs since the protocols are similar enough */
|
||||
#if defined(MULTIMODULE)
|
||||
#define NUM_TIMER_PULSES 300
|
||||
#else
|
||||
PACK(struct PxxPulsesData {
|
||||
uint16_t pulses[400];
|
||||
uint16_t *ptr;
|
||||
uint16_t pcmValue;
|
||||
#define NUM_TIMER_PULSES 200
|
||||
#endif
|
||||
|
||||
PACK(struct PxxTimerPulsesData {
|
||||
pulse_duration_t pulses[NUM_TIMER_PULSES];
|
||||
pulse_duration_t * ptr;
|
||||
uint16_t rest;
|
||||
uint16_t pcmCrc;
|
||||
uint32_t pcmOnesCount;
|
||||
});
|
||||
PACK(struct Dsm2PulsesData {
|
||||
uint16_t pulses[400];
|
||||
uint16_t *ptr;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
|
||||
PACK(struct Dsm2TimerPulsesData {
|
||||
pulse_duration_t pulses[NUM_TIMER_PULSES];
|
||||
pulse_duration_t * ptr;
|
||||
uint16_t rest;
|
||||
uint8_t index;
|
||||
});
|
||||
#undef NUM_TIMER_PULSES
|
||||
#endif
|
||||
|
||||
#define CROSSFIRE_BAUDRATE 400000
|
||||
@@ -77,8 +106,16 @@ PACK(struct CrossfirePulsesData {
|
||||
});
|
||||
|
||||
union ModulePulsesData {
|
||||
PxxPulsesData pxx;
|
||||
Dsm2PulsesData dsm2;
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
PxxSerialPulsesData pxx;
|
||||
Dsm2SerialPulsesData dsm2;
|
||||
#else
|
||||
PxxTimerPulsesData pxx;
|
||||
Dsm2TimerPulsesData dsm2;
|
||||
#endif
|
||||
#if defined(PPM_PIN_UART)
|
||||
PxxUartPulsesData pxx_uart;
|
||||
#endif
|
||||
PpmPulsesData ppm;
|
||||
CrossfirePulsesData crossfire;
|
||||
};
|
||||
@@ -91,11 +128,11 @@ extern ModulePulsesData modulePulsesData[NUM_MODULES];
|
||||
extern TrainerPulsesData trainerPulsesData;
|
||||
extern const uint16_t CRCTable[];
|
||||
|
||||
void setupPulses(unsigned int port);
|
||||
void setupPulsesDSM2(unsigned int port);
|
||||
void setupPulsesMultimodule(unsigned int port);
|
||||
void setupPulsesPXX(unsigned int port);
|
||||
void setupPulsesPPM(unsigned int port);
|
||||
void setupPulses(uint8_t port);
|
||||
void setupPulsesDSM2(uint8_t port);
|
||||
void setupPulsesMultimodule(uint8_t port);
|
||||
void setupPulsesPXX(uint8_t port);
|
||||
void setupPulsesPPM(uint8_t port);
|
||||
void sendByteDsm2(uint8_t b);
|
||||
void putDsm2Flush();
|
||||
void putDsm2SerialBit(uint8_t bit);
|
||||
|
||||
+154
-84
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -60,44 +60,50 @@ const uint16_t CRCTable[]=
|
||||
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
|
||||
};
|
||||
|
||||
void crc(uint8_t data, unsigned int port)
|
||||
{
|
||||
modulePulsesData[port].pxx.pcmCrc = (modulePulsesData[port].pxx.pcmCrc<<8) ^ (CRCTable[((modulePulsesData[port].pxx.pcmCrc>>8)^data) & 0xFF]);
|
||||
}
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
void putPcmPart(uint8_t byte, unsigned int port)
|
||||
#if defined(PPM_PIN_UART)
|
||||
inline void uartPutPcmPart(uint8_t port, uint8_t byte)
|
||||
{
|
||||
if (0x7E == byte) {
|
||||
*modulePulsesData[port].pxx.ptr++ = 0x7D;
|
||||
*modulePulsesData[port].pxx.ptr++ = 0x5E;
|
||||
*modulePulsesData[port].pxx_uart.ptr++ = 0x7D;
|
||||
*modulePulsesData[port].pxx_uart.ptr++ = 0x5E;
|
||||
}
|
||||
else if (0x7D == byte) {
|
||||
*modulePulsesData[port].pxx.ptr++ = 0x7D;
|
||||
*modulePulsesData[port].pxx.ptr++ = 0x5D;
|
||||
*modulePulsesData[port].pxx_uart.ptr++ = 0x7D;
|
||||
*modulePulsesData[port].pxx_uart.ptr++ = 0x5D;
|
||||
}
|
||||
else {
|
||||
*modulePulsesData[port].pxx.ptr++ = byte;
|
||||
*modulePulsesData[port].pxx_uart.ptr++ = byte;
|
||||
}
|
||||
}
|
||||
|
||||
void putPcmByte(uint8_t byte, unsigned int port)
|
||||
void uartPutPcmByte(uint8_t port, uint8_t byte)
|
||||
{
|
||||
crc(byte, port);
|
||||
putPcmPart(byte, port);
|
||||
modulePulsesData[port].pxx_uart.pcmCrc = (modulePulsesData[port].pxx_uart.pcmCrc<<8) ^ (CRCTable[((modulePulsesData[port].pxx_uart.pcmCrc>>8)^byte) & 0xFF]);
|
||||
uartPutPcmPart(port, byte);
|
||||
}
|
||||
|
||||
void putPcmHead(unsigned int port)
|
||||
void uartInitPcmArray(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].pxx_uart.ptr = modulePulsesData[port].pxx_uart.pulses;
|
||||
modulePulsesData[port].pxx_uart.pcmCrc = 0;
|
||||
}
|
||||
|
||||
void uartPutPcmHead(uint8_t port)
|
||||
{
|
||||
// send 7E, do not CRC
|
||||
*modulePulsesData[port].pxx.ptr++ = 0x7E;
|
||||
*modulePulsesData[port].pxx_uart.ptr++ = 0x7E;
|
||||
}
|
||||
|
||||
#define putPcmFlush(port)
|
||||
#define putPcmPreamble(port)
|
||||
#else
|
||||
#if defined(PPM_PIN_HW_SERIAL)
|
||||
void putPcmSerialBit(uint8_t bit, unsigned int port)
|
||||
void uartPutPcmCrc(uint8_t port)
|
||||
{
|
||||
uint16_t pulseValue = modulePulsesData[port].pxx_uart.pcmCrc;
|
||||
uartPutPcmByte(port, pulseValue >> 8);
|
||||
uartPutPcmByte(port, pulseValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
void pxxPutPcmSerialBit(uint8_t port, uint8_t bit)
|
||||
{
|
||||
modulePulsesData[port].pxx.serialByte >>= 1;
|
||||
if (bit & 1) {
|
||||
@@ -110,103 +116,169 @@ void putPcmSerialBit(uint8_t bit, unsigned int port)
|
||||
}
|
||||
|
||||
// 8uS/bit 01 = 0, 001 = 1
|
||||
void putPcmPart(uint8_t value, unsigned int port)
|
||||
void pxxPutPcmPart(uint8_t port, uint8_t value)
|
||||
{
|
||||
putPcmSerialBit(0, port);
|
||||
pxxPutPcmSerialBit(port, 0);
|
||||
if (value) {
|
||||
putPcmSerialBit(0, port);
|
||||
pxxPutPcmSerialBit(port, 0);
|
||||
}
|
||||
putPcmSerialBit(1, port);
|
||||
pxxPutPcmSerialBit(port, 1);
|
||||
}
|
||||
|
||||
void putPcmFlush(unsigned int port)
|
||||
void pxxPutPcmTail(uint8_t port)
|
||||
{
|
||||
while (modulePulsesData[port].pxx.serialBitCount != 0) {
|
||||
putPcmSerialBit(1, port);
|
||||
pxxPutPcmSerialBit(port, 1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void putPcmPart(uint8_t value, unsigned int port)
|
||||
void pxxPutPcmPart(uint8_t port, uint8_t value)
|
||||
{
|
||||
modulePulsesData[port].pxx.pcmValue += 18 ; // Output 1 for this time
|
||||
*modulePulsesData[port].pxx.ptr++ = modulePulsesData[port].pxx.pcmValue ;
|
||||
modulePulsesData[port].pxx.pcmValue += 14 ;
|
||||
if (value) {
|
||||
modulePulsesData[port].pxx.pcmValue += 16 ;
|
||||
}
|
||||
*modulePulsesData[port].pxx.ptr++ = modulePulsesData[port].pxx.pcmValue ; // Output 0 for this time
|
||||
pulse_duration_t duration = value ? 48 : 32;
|
||||
*modulePulsesData[port].pxx.ptr++ = duration;
|
||||
modulePulsesData[port].pxx.rest -= duration + 1;
|
||||
}
|
||||
|
||||
void putPcmFlush(unsigned int port)
|
||||
void pxxPutPcmTail(uint8_t port)
|
||||
{
|
||||
*modulePulsesData[port].pxx.ptr++ = 18010 ; // Past the 18000 of the ARR
|
||||
*(modulePulsesData[port].pxx.ptr-1) += modulePulsesData[port].pxx.rest;
|
||||
}
|
||||
#endif
|
||||
|
||||
void putPcmBit(uint8_t bit, unsigned int port)
|
||||
void pxxPutPcmBit(uint8_t port, uint8_t bit)
|
||||
{
|
||||
if (bit) {
|
||||
modulePulsesData[port].pxx.pcmOnesCount += 1;
|
||||
putPcmPart(1, port);
|
||||
pxxPutPcmPart(port, 1);
|
||||
if (++modulePulsesData[port].pxx.pcmOnesCount == 5) {
|
||||
modulePulsesData[port].pxx.pcmOnesCount = 0;
|
||||
pxxPutPcmPart(port, 0); // Stuff a 0 bit in
|
||||
}
|
||||
}
|
||||
else {
|
||||
pxxPutPcmPart(port, 0);
|
||||
modulePulsesData[port].pxx.pcmOnesCount = 0;
|
||||
putPcmPart(0, port);
|
||||
}
|
||||
if (modulePulsesData[port].pxx.pcmOnesCount >= 5) {
|
||||
putPcmBit(0, port); // Stuff a 0 bit in
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void putPcmByte(uint8_t byte, unsigned int port)
|
||||
void pxxPutPcmByte(uint8_t port, uint8_t byte)
|
||||
{
|
||||
crc(byte, port);
|
||||
modulePulsesData[port].pxx.pcmCrc = (modulePulsesData[port].pxx.pcmCrc<<8) ^ (CRCTable[((modulePulsesData[port].pxx.pcmCrc>>8)^byte) & 0xFF]);
|
||||
for (uint8_t i=0; i<8; i++) {
|
||||
putPcmBit(byte & 0x80, port);
|
||||
pxxPutPcmBit(port, byte & 0x80);
|
||||
byte <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void putPcmHead(unsigned int port)
|
||||
void pxxInitPcmArray(uint8_t port)
|
||||
{
|
||||
modulePulsesData[port].pxx.ptr = modulePulsesData[port].pxx.pulses;
|
||||
#if defined(PPM_PIN_SERIAL)
|
||||
modulePulsesData[port].pxx.pcmValue = 0;
|
||||
#else
|
||||
modulePulsesData[port].pxx.rest = 18000;
|
||||
#endif
|
||||
modulePulsesData[port].pxx.pcmCrc = 0;
|
||||
modulePulsesData[port].pxx.pcmOnesCount = 0;
|
||||
}
|
||||
|
||||
void pxxPutPcmHead(uint8_t port)
|
||||
{
|
||||
// send 7E, do not CRC
|
||||
// 01111110
|
||||
putPcmPart(0, port);
|
||||
putPcmPart(1, port);
|
||||
putPcmPart(1, port);
|
||||
putPcmPart(1, port);
|
||||
putPcmPart(1, port);
|
||||
putPcmPart(1, port);
|
||||
putPcmPart(1, port);
|
||||
putPcmPart(0, port);
|
||||
pxxPutPcmPart(port, 0);
|
||||
pxxPutPcmPart(port, 1);
|
||||
pxxPutPcmPart(port, 1);
|
||||
pxxPutPcmPart(port, 1);
|
||||
pxxPutPcmPart(port, 1);
|
||||
pxxPutPcmPart(port, 1);
|
||||
pxxPutPcmPart(port, 1);
|
||||
pxxPutPcmPart(port, 0);
|
||||
}
|
||||
|
||||
void putPcmPreamble(unsigned int port)
|
||||
void pxxPutPcmCrc(uint8_t port)
|
||||
{
|
||||
putPcmPart(0, port);
|
||||
putPcmPart(0, port);
|
||||
putPcmPart(0, port);
|
||||
putPcmPart(0, port);
|
||||
uint16_t pulseValue = modulePulsesData[port].pxx.pcmCrc;
|
||||
pxxPutPcmByte(port, pulseValue >> 8);
|
||||
pxxPutPcmByte(port, pulseValue);
|
||||
}
|
||||
|
||||
#if defined(PPM_PIN_UART)
|
||||
inline void initPcmArray(uint8_t port)
|
||||
{
|
||||
if (IS_UART_MODULE(port))
|
||||
uartInitPcmArray(port);
|
||||
else
|
||||
pxxInitPcmArray(port);
|
||||
}
|
||||
|
||||
inline void putPcmHead(uint8_t port)
|
||||
{
|
||||
if (IS_UART_MODULE(port))
|
||||
uartPutPcmHead(port);
|
||||
else
|
||||
pxxPutPcmHead(port);
|
||||
}
|
||||
|
||||
inline void putPcmByte(uint8_t port, uint8_t byte)
|
||||
{
|
||||
if (IS_UART_MODULE(port))
|
||||
uartPutPcmByte(port, byte);
|
||||
else
|
||||
pxxPutPcmByte(port, byte);
|
||||
}
|
||||
|
||||
inline void putPcmCrc(uint8_t port)
|
||||
{
|
||||
if (IS_UART_MODULE(port))
|
||||
uartPutPcmCrc(port);
|
||||
else
|
||||
pxxPutPcmCrc(port);
|
||||
}
|
||||
|
||||
inline void putPcmTail(uint8_t port)
|
||||
{
|
||||
if (!IS_UART_MODULE(port))
|
||||
pxxPutPcmTail(port);
|
||||
}
|
||||
#else
|
||||
inline void initPcmArray(uint8_t port)
|
||||
{
|
||||
pxxInitPcmArray(port);
|
||||
}
|
||||
|
||||
inline void putPcmHead(uint8_t port)
|
||||
{
|
||||
pxxPutPcmHead(port);
|
||||
}
|
||||
|
||||
inline void putPcmByte(uint8_t port, uint8_t byte)
|
||||
{
|
||||
pxxPutPcmByte(port, byte);
|
||||
}
|
||||
|
||||
inline void putPcmCrc(uint8_t port)
|
||||
{
|
||||
pxxPutPcmCrc(port);
|
||||
}
|
||||
|
||||
inline void putPcmTail(uint8_t port)
|
||||
{
|
||||
pxxPutPcmTail(port);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupPulsesPXX(unsigned int port)
|
||||
void setupPulsesPXX(uint8_t port)
|
||||
{
|
||||
uint16_t pulseValue=0, pulseValueLow=0;
|
||||
|
||||
modulePulsesData[port].pxx.ptr = modulePulsesData[port].pxx.pulses;
|
||||
modulePulsesData[port].pxx.pcmValue = 0 ;
|
||||
modulePulsesData[port].pxx.pcmCrc = 0;
|
||||
modulePulsesData[port].pxx.pcmOnesCount = 0;
|
||||
|
||||
/* Preamble */
|
||||
putPcmPreamble(port);
|
||||
initPcmArray(port);
|
||||
|
||||
/* Sync */
|
||||
putPcmHead(port);
|
||||
|
||||
/* Rx Number */
|
||||
putPcmByte(g_model.header.modelId[port], port);
|
||||
putPcmByte(port, g_model.header.modelId[port]);
|
||||
|
||||
/* FLAG1 */
|
||||
uint8_t flag1 = (g_model.moduleData[port].rfProtocol << 6);
|
||||
@@ -226,10 +298,10 @@ void setupPulsesPXX(unsigned int port)
|
||||
}
|
||||
}
|
||||
|
||||
putPcmByte(flag1, port);
|
||||
putPcmByte(port, flag1);
|
||||
|
||||
/* FLAG2 */
|
||||
putPcmByte(0, port);
|
||||
putPcmByte(port, 0);
|
||||
|
||||
/* PPM */
|
||||
static uint8_t pass[NUM_MODULES] = { MODULES_INIT(0) };
|
||||
@@ -291,9 +363,9 @@ void setupPulsesPXX(unsigned int port)
|
||||
}
|
||||
|
||||
if (i & 1) {
|
||||
putPcmByte(pulseValueLow, port); // Low byte of channel
|
||||
putPcmByte(((pulseValueLow >> 8) & 0x0F) | (pulseValue << 4), port); // 4 bits each from 2 channels
|
||||
putPcmByte(pulseValue >> 4, port); // High byte of channel
|
||||
putPcmByte(port, pulseValueLow); // Low byte of channel
|
||||
putPcmByte(port, ((pulseValueLow >> 8) & 0x0F) | (pulseValue << 4)); // 4 bits each from 2 channels
|
||||
putPcmByte(port, pulseValue >> 4); // High byte of channel
|
||||
}
|
||||
else {
|
||||
pulseValueLow = pulseValue;
|
||||
@@ -306,18 +378,16 @@ void setupPulsesPXX(unsigned int port)
|
||||
if (port == INTERNAL_MODULE) {
|
||||
antenna = g_model.moduleData[INTERNAL_MODULE].ppm.pulsePol;
|
||||
}
|
||||
putPcmByte (antenna, port);
|
||||
putPcmByte(port, antenna);
|
||||
#else
|
||||
putPcmByte(0, port);
|
||||
putPcmByte(port, 0);
|
||||
#endif
|
||||
|
||||
/* CRC16 */
|
||||
pulseValue = modulePulsesData[port].pxx.pcmCrc;
|
||||
putPcmByte(pulseValue >> 8, port);
|
||||
putPcmByte(pulseValue, port);
|
||||
/* CRC */
|
||||
putPcmCrc(port);
|
||||
|
||||
/* Sync */
|
||||
putPcmHead(port);
|
||||
|
||||
putPcmFlush(port);
|
||||
putPcmTail(port);
|
||||
}
|
||||
|
||||
@@ -138,8 +138,7 @@ void boardInit()
|
||||
RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph |
|
||||
ADC_RCC_APB2Periph |
|
||||
HAPTIC_RCC_APB2Periph |
|
||||
INTMODULE_RCC_APB2Periph |
|
||||
EXTMODULE_RCC_APB2Periph, ENABLE);
|
||||
INTMODULE_RCC_APB2Periph, ENABLE);
|
||||
|
||||
pwrInit();
|
||||
delaysInit();
|
||||
|
||||
@@ -164,6 +164,11 @@ void SDRAM_Init(void);
|
||||
#define EXTERNAL_MODULE_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN)
|
||||
#define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET)
|
||||
#define IS_EXTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) == Bit_SET)
|
||||
#define IS_UART_MODULE(port) (port == INTERNAL_MODULE)
|
||||
|
||||
// void setupPulses(uint8_t port);
|
||||
// void setupPulsesPPM(uint8_t port);
|
||||
// void setupPulsesPXX(uint8_t port);
|
||||
void init_no_pulses(uint32_t port);
|
||||
void disable_no_pulses(uint32_t port);
|
||||
void init_ppm( uint32_t module_index );
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
void extmoduleSendNextFrame();
|
||||
|
||||
void extmoduleStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_TIMER->DIER &= ~(TIM_DIER_CC2IE | TIM_DIER_UDE);
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
void extmoduleNoneStart()
|
||||
{
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, 0);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 36000; // 18mS
|
||||
EXTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
void extmodulePpmStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// PPM generation principle:
|
||||
//
|
||||
// Hardware timer in PWM mode is used for PPM generation
|
||||
// Output is OFF if CNT<CCR1(delay) and ON if bigger
|
||||
// CCR1 register defines duration of pulse length and is constant
|
||||
// AAR register defines duration of each pulse, it is
|
||||
// updated after every pulse in Update interrupt handler.
|
||||
// CCR2 register defines duration of no pulses (time between two pulse trains)
|
||||
// it is calculated every round to have PPM period constant.
|
||||
// CC2 interrupt is then used to setup new PPM values for the
|
||||
// next PPM pulses train.
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop timer
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 41000;
|
||||
// CH1 PWM mode 1, CH1 out is OFF if CNT<CCR1(delay) and ON if bigger (up to AAR,which is pulse length)
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
EXTMODULE_TIMER->EGR = 1; // Reloads register vales now
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Update DMA request
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN; // Start timer
|
||||
|
||||
setupPulsesPPM(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
void set_external_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
|
||||
{
|
||||
EXTMODULE_TIMER->CCR2 = idleTime;
|
||||
EXTMODULE_TIMER->CCR1 = delay;
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (positive ? 0 : TIM_CCER_CC1P);
|
||||
}
|
||||
|
||||
void extmodulePxxStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 18000;
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC1NE | TIM_CCER_CC1NP; // TIM_CCER_CC1E | TIM_CCER_CC1P;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 18;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
setupPulsesPXX(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
#if defined(DSM2)
|
||||
void extmoduleDsm2Start()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 44000; // 22mS
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 0;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
setupPulsesDSM2(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
void extmoduleCrossfireStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, 0);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_FRAME_PERIOD);
|
||||
EXTMODULE_TIMER->CCR2 = (2000 * CROSSFIRE_FRAME_PERIOD) - 1000;
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
void extmoduleSendNextFrame()
|
||||
{
|
||||
if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) {
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].ppm.pulses);
|
||||
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].ppm.ptr - modulePulsesData[EXTERNAL_MODULE].ppm.pulses;
|
||||
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) {
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.pulses);
|
||||
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.ptr - modulePulsesData[EXTERNAL_MODULE].pxx.pulses;
|
||||
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) {
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_1 | DMA_SxCR_MSIZE_1 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses);
|
||||
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
|
||||
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
else {
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void EXTMODULE_DMA_IRQHandler()
|
||||
{
|
||||
if (!DMA_GetITStatus(EXTMODULE_DMA_STREAM, EXTMODULE_DMA_FLAG_TC))
|
||||
return;
|
||||
|
||||
DMA_ClearITPendingBit(EXTMODULE_DMA_STREAM, EXTMODULE_DMA_FLAG_TC);
|
||||
|
||||
uint32_t arr = EXTMODULE_TIMER->ARR;
|
||||
if (arr > 4000) {
|
||||
EXTMODULE_TIMER->CCR2 = arr - 4000; // 2mS in advance
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
else {
|
||||
setupPulses(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void EXTMODULE_TIMER_IRQHandler()
|
||||
{
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
setupPulses(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
}
|
||||
@@ -261,7 +261,7 @@
|
||||
#define HAPTIC_GPIO_PinSource GPIO_PinSource2
|
||||
|
||||
// Internal Module
|
||||
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB)
|
||||
#define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2)
|
||||
#define INTMODULE_RCC_APB2Periph (RCC_APB2Periph_TIM1 | RCC_APB2Periph_USART1)
|
||||
#define INTMODULE_PWR_GPIO GPIOA
|
||||
#define INTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PA.08
|
||||
@@ -276,15 +276,17 @@
|
||||
#define INTMODULE_USART_IRQn USART1_IRQn
|
||||
#define INTMODULE_DMA_STREAM DMA2_Stream7
|
||||
#define INTMODULE_DMA_STREAM_IRQ DMA2_Stream7_IRQn
|
||||
#define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream7_IRQHandler
|
||||
#define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF7
|
||||
#define INTMODULE_DMA_CHANNEL DMA_Channel_4
|
||||
#define INTMODULE_TIMER TIM1
|
||||
#define INTMODULE_TIMER_IRQn TIM1_CC_IRQn
|
||||
#define INTMODULE_TIMER_CC_IRQn TIM1_CC_IRQn
|
||||
#define INTMODULE_TIMER_CC_IRQHandler TIM1_CC_IRQHandler
|
||||
#define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
|
||||
// External Module
|
||||
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB)
|
||||
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA1)
|
||||
#define EXTMODULE_RCC_APB1Periph RCC_APB1Periph_TIM2
|
||||
#define EXTMODULE_RCC_APB2Periph 0
|
||||
#define EXTMODULE_PWR_GPIO GPIOB
|
||||
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_3 // PB.03
|
||||
#define EXTMODULE_PPM_GPIO GPIOA
|
||||
@@ -292,8 +294,14 @@
|
||||
#define EXTMODULE_PPM_GPIO_PinSource GPIO_PinSource15
|
||||
#define EXTMODULE_TIMER TIM2
|
||||
#define EXTMODULE_PPM_GPIO_AF GPIO_AF_TIM2
|
||||
#define EXTMODULE_PPM_GPIO_PinSource GPIO_PinSource15
|
||||
#define EXTMODULE_DMA DMA1
|
||||
#define EXTMODULE_DMA_CHANNEL DMA_Channel_3
|
||||
#define EXTMODULE_DMA_STREAM DMA1_Stream7
|
||||
#define EXTMODULE_DMA_IRQn DMA1_Stream7_IRQn
|
||||
#define EXTMODULE_DMA_IRQHandler DMA1_Stream7_IRQHandler
|
||||
#define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF7
|
||||
#define EXTMODULE_TIMER_IRQn TIM2_IRQn
|
||||
#define EXTMODULE_TIMER_IRQHandler TIM2_IRQHandler
|
||||
#define EXTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1)
|
||||
|
||||
// Trainer Port
|
||||
|
||||
@@ -20,41 +20,64 @@
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
void setupPulses(unsigned int port);
|
||||
void setupPulsesPPM(unsigned int port);
|
||||
void setupPulsesPXX(unsigned int port);
|
||||
void intmoduleStop(void);
|
||||
void extmoduleStop(void);
|
||||
|
||||
static void intmodulePxxStart( void ) ;
|
||||
static void intmodulePxxStop( void ) ;
|
||||
static void extmodulePxxStart( void ) ;
|
||||
static void extmodulePxxStop( void ) ;
|
||||
void intmoduleNoneStart(void);
|
||||
void intmodulePxxStart(void);
|
||||
|
||||
void extmoduleNoneStart(void);
|
||||
void extmodulePpmStart(void);
|
||||
void extmodulePxxStart(void);
|
||||
#if defined(DSM2)
|
||||
static void extmoduleDsm2Start( void ) ;
|
||||
static void extmoduleDsm2Stop( void ) ;
|
||||
void extmoduleDsm2Start(void);
|
||||
#endif
|
||||
static void extmodulePpmStart( void ) ;
|
||||
static void extmodulePpmStop( void ) ;
|
||||
static void intmoduleNoneStart( void ) ;
|
||||
static void intmoduleNoneStop( void ) ;
|
||||
static void extmoduleNoneStart( void ) ;
|
||||
static void extmoduleNoneStop( void ) ;
|
||||
static void extmoduleCrossfireStart( void ) ;
|
||||
static void extmoduleCrossfireStop( void ) ;
|
||||
void extmoduleCrossfireStart(void);
|
||||
|
||||
void init_no_pulses(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmoduleNoneStart();
|
||||
else
|
||||
extmoduleNoneStart();
|
||||
}
|
||||
|
||||
void disable_no_pulses(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmoduleStop();
|
||||
else
|
||||
extmoduleStop();
|
||||
}
|
||||
|
||||
void init_ppm(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmodulePpmStart();
|
||||
}
|
||||
}
|
||||
|
||||
void disable_ppm(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmoduleStop();
|
||||
}
|
||||
}
|
||||
|
||||
void init_pxx(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmodulePxxStart() ;
|
||||
intmodulePxxStart();
|
||||
else
|
||||
extmodulePxxStart() ;
|
||||
extmodulePxxStart();
|
||||
}
|
||||
|
||||
void disable_pxx(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmodulePxxStop() ;
|
||||
intmoduleStop();
|
||||
else
|
||||
extmodulePxxStop() ;
|
||||
extmoduleStop();
|
||||
}
|
||||
|
||||
#if defined(DSM2)
|
||||
@@ -68,48 +91,11 @@ void init_dsm2(uint32_t port)
|
||||
void disable_dsm2(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmoduleDsm2Stop();
|
||||
extmoduleStop();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_ppm(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmodulePpmStart();
|
||||
}
|
||||
}
|
||||
|
||||
void disable_ppm(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmodulePpmStop();
|
||||
}
|
||||
}
|
||||
|
||||
void set_external_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
|
||||
{
|
||||
EXTMODULE_TIMER->CCR2 = idleTime;
|
||||
EXTMODULE_TIMER->CCR1 = delay;
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (positive ? 0 : TIM_CCER_CC1P);
|
||||
}
|
||||
|
||||
void init_no_pulses(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmoduleNoneStart();
|
||||
else
|
||||
extmoduleNoneStart();
|
||||
}
|
||||
|
||||
void disable_no_pulses(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmoduleNoneStop();
|
||||
else
|
||||
extmoduleNoneStop();
|
||||
}
|
||||
|
||||
void init_crossfire(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
@@ -119,184 +105,51 @@ void init_crossfire(uint32_t port)
|
||||
|
||||
void disable_crossfire(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE)
|
||||
extmoduleCrossfireStop();
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmoduleStop();
|
||||
}
|
||||
}
|
||||
|
||||
static void intmoduleNoneStart()
|
||||
void intmoduleStop()
|
||||
{
|
||||
INTERNAL_MODULE_OFF();
|
||||
|
||||
NVIC_DisableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void intmoduleNoneStart()
|
||||
{
|
||||
INTERNAL_MODULE_OFF();
|
||||
|
||||
// Timer1, channel 3
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(INTMODULE_TX_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(INTMODULE_TX_GPIO, INTMODULE_TX_GPIO_PIN) ; // Set high
|
||||
GPIO_SetBits(INTMODULE_TX_GPIO, INTMODULE_TX_GPIO_PIN); // Set high
|
||||
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
INTMODULE_TIMER->ARR = 36000 ; // 18mS
|
||||
INTMODULE_TIMER->CCR2 = 32000 ; // Update time
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1 ; // 0.5uS (2Mhz)
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
INTMODULE_TIMER->ARR = 36000; // 18mS
|
||||
INTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E ;
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = 0 ;
|
||||
INTMODULE_TIMER->EGR = 1 ; // Restart
|
||||
INTMODULE_TIMER->CCMR2 = 0;
|
||||
INTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 ; // Toggle CC1 o/p
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
|
||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN ;
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_IRQn) ;
|
||||
NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void intmoduleNoneStop()
|
||||
{
|
||||
NVIC_DisableIRQ(INTMODULE_TIMER_IRQn) ;
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE ;
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
extern "C" void DMA2_Stream7_IRQHandler(void)
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_DMA2S7);
|
||||
if(DMA_GetITStatus(INTMODULE_DMA_STREAM, DMA_IT_TCIF7)) {
|
||||
// TODO we could send the 8 next channels here (when needed)
|
||||
DMA_ClearITPendingBit(INTMODULE_DMA_STREAM, DMA_IT_TCIF7);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void TIM1_CC_IRQHandler()
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_TIM1CC);
|
||||
DEBUG_TIMER_SAMPLE(debugTimerIntPulses);
|
||||
DEBUG_TIMER_START(debugTimerIntPulsesDuration);
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // stop this interrupt
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // clear flag
|
||||
|
||||
setupPulses(INTERNAL_MODULE);
|
||||
|
||||
if (s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) {
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
DMA_DeInit(INTMODULE_DMA_STREAM);
|
||||
DMA_InitStructure.DMA_Channel = INTMODULE_DMA_CHANNEL;
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&INTMODULE_USART->DR);
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)modulePulsesData[INTERNAL_MODULE].pxx.pulses;
|
||||
DMA_InitStructure.DMA_BufferSize = (uint8_t *)modulePulsesData[INTERNAL_MODULE].pxx.ptr - (uint8_t *)modulePulsesData[INTERNAL_MODULE].pxx.pulses;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||||
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
||||
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
|
||||
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||
DMA_Init(INTMODULE_DMA_STREAM, &DMA_InitStructure);
|
||||
|
||||
DMA_Cmd(INTMODULE_DMA_STREAM, ENABLE);
|
||||
USART_DMACmd(INTMODULE_USART, USART_DMAReq_Tx, ENABLE);
|
||||
// DMA_ITConfig(INTMODULE_DMA_STREAM, DMA_IT_TC, ENABLE);
|
||||
}
|
||||
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
DEBUG_TIMER_STOP(debugTimerIntPulsesDuration);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void extmoduleNoneStart()
|
||||
{
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, 0); // TODO : check if needed
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN) ; // Set high
|
||||
|
||||
TIM_DeInit(EXTMODULE_TIMER);
|
||||
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseStructure.TIM_Period = 36000; // 18mS
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
|
||||
TIM_TimeBaseInit(EXTMODULE_TIMER, &TIM_TimeBaseStructure);
|
||||
|
||||
// set CC2 compare to fire slightly before the Update
|
||||
TIM_SetCompare2(EXTMODULE_TIMER, 32000); // 16ms
|
||||
|
||||
// enable CC2 interrupt
|
||||
TIM_ClearFlag(EXTMODULE_TIMER, TIM_FLAG_CC2);
|
||||
TIM_ITConfig(EXTMODULE_TIMER, TIM_IT_CC2, ENABLE);
|
||||
|
||||
// start timer
|
||||
TIM_Cmd(EXTMODULE_TIMER, ENABLE);
|
||||
|
||||
// enable interrupt and set it's priority
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmoduleNoneStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
TIM_DeInit(EXTMODULE_TIMER);
|
||||
}
|
||||
|
||||
static void extmoduleCrossfireStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
EXTMODULE_TIMER->ARR = 5000 ; // 2.5mS
|
||||
EXTMODULE_TIMER->CCR2 = 32000 ; // Update time
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1 ; // 0.5uS (2Mhz)
|
||||
|
||||
EXTMODULE_TIMER->CCMR2 = 0 ;
|
||||
EXTMODULE_TIMER->EGR = 1 ; // Restart
|
||||
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 ; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN ;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmoduleCrossfireStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE ;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
void intmodulePxxStart()
|
||||
@@ -306,7 +159,7 @@ void intmodulePxxStart()
|
||||
|
||||
INTERNAL_MODULE_ON();
|
||||
|
||||
setupPulsesPXX(INTERNAL_MODULE) ; // TODO not here!
|
||||
setupPulsesPXX(INTERNAL_MODULE);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = INTMODULE_DMA_STREAM_IRQ;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
@@ -340,270 +193,69 @@ void intmodulePxxStart()
|
||||
USART_Init(INTMODULE_USART, &USART_InitStructure);
|
||||
USART_Cmd(INTMODULE_USART, ENABLE);
|
||||
|
||||
// open DMA------------------------------
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // Enable DMA1 clock
|
||||
|
||||
// Timer
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
INTMODULE_TIMER->ARR = 18000 ; // 9mS
|
||||
INTMODULE_TIMER->CCR2 = 15000 ; // Update time
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1 ; // 0.5uS (2Mhz)
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E ;
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E ;
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
INTMODULE_TIMER->ARR = 18000; // 9mS
|
||||
INTMODULE_TIMER->CCR2 = 15000; // Update time
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = 0 ;
|
||||
INTMODULE_TIMER->EGR = 1 ; // Restart
|
||||
INTMODULE_TIMER->CCMR2 = 0;
|
||||
INTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 ; // Toggle CC1 o/p
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
|
||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN ;
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_IRQn) ;
|
||||
NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7);
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
static void intmodulePxxStop()
|
||||
extern "C" void INTMODULE_DMA_STREAM_IRQHandler(void)
|
||||
{
|
||||
INTERNAL_MODULE_OFF();
|
||||
}
|
||||
|
||||
void extmodulePxxStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
setupPulsesPXX(EXTERNAL_MODULE);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
EXTMODULE_TIMER->ARR = 18000 ; // 9mS
|
||||
EXTMODULE_TIMER->CCR2 = 15000 ; // Update time
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1 ; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE ;
|
||||
EXTMODULE_TIMER->CR2 = TIM_CR2_OIS1 ; // O/P idle high
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE ; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].pxx.pulses[0];
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0 ; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1 ; // Restart
|
||||
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC1DE ; // Enable DMA on CC1 match
|
||||
EXTMODULE_TIMER->DCR = 13;
|
||||
|
||||
// Enable the DMA channel here, DMA1 stream 5, channel 3 (TIM2_CH1)
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
|
||||
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL ;
|
||||
DMA1_Stream5->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->DMAR);
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].pxx.pulses[1]);
|
||||
// DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
|
||||
// DMA1_Stream5->NDTR = 100 ;
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN ; // Enable DMA
|
||||
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0 ; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN ;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmodulePxxStop()
|
||||
{
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE ;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
DEBUG_INTERRUPT(INT_DMA2S7);
|
||||
if (DMA_GetITStatus(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC)) {
|
||||
// TODO we could send the 8 next channels here (when needed)
|
||||
DMA_ClearITPendingBit(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DSM2)
|
||||
static void extmoduleDsm2Start()
|
||||
extern "C" void INTMODULE_TIMER_CC_IRQHandler()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
DEBUG_INTERRUPT(INT_TIM1CC);
|
||||
DEBUG_TIMER_SAMPLE(debugTimerIntPulses);
|
||||
DEBUG_TIMER_START(debugTimerIntPulsesDuration);
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // stop this interrupt
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // clear flag
|
||||
|
||||
setupPulsesDSM2(EXTERNAL_MODULE);
|
||||
setupPulses(INTERNAL_MODULE);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
if (s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) {
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
DMA_DeInit(INTMODULE_DMA_STREAM);
|
||||
DMA_InitStructure.DMA_Channel = INTMODULE_DMA_CHANNEL;
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&INTMODULE_USART->DR);
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(modulePulsesData[INTERNAL_MODULE].pxx_uart.pulses);
|
||||
DMA_InitStructure.DMA_BufferSize = (uint8_t *)modulePulsesData[INTERNAL_MODULE].pxx_uart.ptr - (uint8_t *)modulePulsesData[INTERNAL_MODULE].pxx_uart.pulses;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||||
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
||||
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
|
||||
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||
DMA_Init(INTMODULE_DMA_STREAM, &DMA_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
EXTMODULE_TIMER->ARR = 44000 ; // 22mS
|
||||
EXTMODULE_TIMER->CCR2 = 40000 ; // Update time
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1 ; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1NP ;
|
||||
EXTMODULE_TIMER->CR2 = TIM_CR2_OIS1 ; // O/P idle high
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE ; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[0];
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0 ; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1 ; // Restart
|
||||
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC1DE ; // Enable DMA on CC1 match
|
||||
EXTMODULE_TIMER->DCR = 13 ; // DMA to CC1
|
||||
|
||||
// Enable the DMA channel here, DMA1 stream 5, channel 3 (TIM2_CH1)
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
|
||||
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL ;
|
||||
DMA1_Stream5->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->DMAR);
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
|
||||
// DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
|
||||
// DMA1_Stream5->NDTR = 100 ;
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN ; // Enable DMA
|
||||
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0 ; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN ;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmoduleDsm2Stop()
|
||||
{
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE ;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void extmodulePpmStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// PPM generation principle:
|
||||
//
|
||||
// Hardware timer in PWM mode is used for PPM generation
|
||||
// Output is OFF if CNT<CCR1(delay) and ON if bigger
|
||||
// CCR1 register defines duration of pulse length and is constant
|
||||
// AAR register defines duration of each pulse, it is
|
||||
// updated after every pulse in Update interrupt handler.
|
||||
// CCR2 register defines duration of no pulses (time between two pulse trains)
|
||||
// it is calculated every round to have PPM period constant.
|
||||
// CC2 interrupt is then used to setup new PPM values for the
|
||||
// next PPM pulses train.
|
||||
// stop timer
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
|
||||
// setupPulsesPPM() is also configuring registers,
|
||||
// so it has to be called after the peripheral is enabled
|
||||
setupPulsesPPM(EXTERNAL_MODULE) ;
|
||||
|
||||
EXTMODULE_TIMER->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++ ;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1 ; // 0.5uS (2Mhz)
|
||||
|
||||
// CH1 PWM mode 1, CH1 out is OFF if CNT<CCR1(delay) and ON if bigger (up to AAR,which is pulse length)
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
|
||||
// Reloads register vales now
|
||||
EXTMODULE_TIMER->EGR = 1 ;
|
||||
|
||||
// Update DMA request enabled. WHY?????
|
||||
EXTMODULE_TIMER->DIER = TIM_DIER_UDE ;
|
||||
|
||||
// clear interrupt flags and enable Update and
|
||||
// CC2 interrupts (this one is enabled now to trigger pulse setup)
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_UIF ; // Clear flag
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UIE ;
|
||||
|
||||
// enable timer and global interrupts
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN ;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmodulePpmStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn) ;
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE & ~TIM_DIER_UIE ;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN ;
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF & ~TIM_SR_UIF; // Clear all flags
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void TIM2_IRQHandler()
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_TIM2);
|
||||
//determine if its CC or UP interrupt
|
||||
uint16_t sr = EXTMODULE_TIMER->SR;
|
||||
uint16_t dier = EXTMODULE_TIMER->DIER;
|
||||
|
||||
if (sr & TIM_SR_CC2IF && dier & TIM_DIER_CC2IE) { // Capture/Compare 2 interrupt enabled and fired
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear flag
|
||||
|
||||
setupPulses(EXTERNAL_MODULE);
|
||||
|
||||
if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) {
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].pxx.pulses[1]);
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN ; // Enable DMA
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].pxx.pulses[0];
|
||||
}
|
||||
#if defined(DSM2)
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) {
|
||||
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
|
||||
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
|
||||
DMA1_Stream5->CR |= DMA_SxCR_EN ; // Enable DMA
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[0];
|
||||
}
|
||||
#endif
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) {
|
||||
// Stop CC2 interrupt, the pulse train period ended
|
||||
// the new PPM values were set, we begin new pulse train
|
||||
// generation with Update interrupt
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE ; // stop CC2 interrupt
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE ;
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_UIF ; // Clear Update interrupt flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UIE ; // Enable Update interrupt
|
||||
}
|
||||
DMA_Cmd(INTMODULE_DMA_STREAM, ENABLE);
|
||||
USART_DMACmd(INTMODULE_USART, USART_DMAReq_Tx, ENABLE);
|
||||
}
|
||||
|
||||
if (sr & TIM_SR_UIF && dier & TIM_DIER_UIE) { // Update interrupt enabled and fired
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_UIF ; // Clear flag
|
||||
if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) {
|
||||
EXTMODULE_TIMER->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++ ;
|
||||
if (*modulePulsesData[EXTERNAL_MODULE].ppm.ptr == 0) {
|
||||
// we reached the end of PPM pulses
|
||||
// enable CC2 interrupt (which comes before Update in any case)
|
||||
// to start new PPM cycle and setup pulses
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear CC1 flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable CC1 interrupt
|
||||
}
|
||||
}
|
||||
}
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
DEBUG_TIMER_STOP(debugTimerIntPulsesDuration);
|
||||
}
|
||||
|
||||
@@ -103,7 +103,6 @@ void telemetryPortSetDirectionInput()
|
||||
|
||||
void sportSendBuffer(uint8_t * buffer, uint32_t count)
|
||||
{
|
||||
#if 0
|
||||
telemetryPortSetDirectionOutput();
|
||||
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
@@ -131,7 +130,6 @@ void sportSendBuffer(uint8_t * buffer, uint32_t count)
|
||||
// enable interrupt and set it's priority
|
||||
NVIC_EnableIRQ(TELEMETRY_DMA_TX_Stream_IRQ) ;
|
||||
NVIC_SetPriority(TELEMETRY_DMA_TX_Stream_IRQ, 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void TELEMETRY_DMA_TX_IRQHandler(void)
|
||||
|
||||
@@ -57,7 +57,7 @@ uint32_t Peri1_frequency, Peri2_frequency;
|
||||
GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpioi, gpioj;
|
||||
TIM_TypeDef tim1, tim2, tim3, tim4, tim5, tim6, tim7, tim8, tim9, tim10;
|
||||
RCC_TypeDef rcc;
|
||||
DMA_Stream_TypeDef dma2_stream2, dma2_stream6, dma1_stream5;
|
||||
DMA_Stream_TypeDef dma1_stream5, dma1_stream7, dma2_stream1, dma2_stream2, dma2_stream5, dma2_stream6;
|
||||
DMA_TypeDef dma2;
|
||||
USART_TypeDef Usart0, Usart1, Usart2, Usart3, Usart4;
|
||||
#elif defined(CPUARM)
|
||||
@@ -1355,6 +1355,11 @@ void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) { }
|
||||
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) { }
|
||||
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) { }
|
||||
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) { }
|
||||
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { }
|
||||
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) { }
|
||||
void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength) { }
|
||||
void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState) { }
|
||||
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState) { }
|
||||
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR) { }
|
||||
void RCC_PLLI2SCmd(FunctionalState NewState) { }
|
||||
void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource) { }
|
||||
@@ -1363,6 +1368,7 @@ void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct) { }
|
||||
void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState) { }
|
||||
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState) { }
|
||||
void RCC_LSEConfig(uint8_t RCC_LSE) { }
|
||||
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) { };
|
||||
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) { return SET; }
|
||||
ErrorStatus RTC_WaitForSynchro(void) { return SUCCESS; }
|
||||
void unlockFlash() { }
|
||||
|
||||
@@ -93,7 +93,7 @@ extern GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpio
|
||||
extern TIM_TypeDef tim1, tim2, tim3, tim4, tim5, tim6, tim7, tim8, tim9, tim10;
|
||||
extern USART_TypeDef Usart0, Usart1, Usart2, Usart3, Usart4;
|
||||
extern RCC_TypeDef rcc;
|
||||
extern DMA_Stream_TypeDef dma2_stream2, dma2_stream6, dma1_stream5;
|
||||
extern DMA_Stream_TypeDef dma1_stream5, dma1_stream7, dma2_stream1, dma2_stream2, dma2_stream5, dma2_stream6;
|
||||
extern DMA_TypeDef dma2;
|
||||
#undef GPIOA
|
||||
#undef GPIOB
|
||||
@@ -146,10 +146,16 @@ extern DMA_TypeDef dma2;
|
||||
#undef RCC
|
||||
#define RCC (&rcc)
|
||||
#undef DMA1_Stream5
|
||||
#undef DMA1_Stream7
|
||||
#undef DMA2_Stream1
|
||||
#undef DMA2_Stream2
|
||||
#undef DMA2_Stream5
|
||||
#undef DMA2_Stream6
|
||||
#define DMA1_Stream5 (&dma1_stream5)
|
||||
#define DMA1_Stream7 (&dma1_stream7)
|
||||
#define DMA2_Stream1 (&dma2_stream1)
|
||||
#define DMA2_Stream2 (&dma2_stream2)
|
||||
#define DMA2_Stream5 (&dma2_stream5)
|
||||
#define DMA2_Stream6 (&dma2_stream6)
|
||||
#undef DMA2
|
||||
#define DMA2 (&dma2)
|
||||
@@ -439,9 +445,6 @@ OS_TID CoCreateTask(FUNCPtr task, void *argv, uint32_t parameter, void * stk, ui
|
||||
#if defined(CPUSTM32)
|
||||
inline void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) { }
|
||||
#define TIM_DeInit(...)
|
||||
#if defined(PCBHORUS)
|
||||
inline void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { }
|
||||
#endif
|
||||
#define TIM_SetCompare2(...)
|
||||
#define TIM_ClearFlag(...)
|
||||
#define TIM_Cmd(...)
|
||||
|
||||
@@ -31,6 +31,7 @@ extern "C" {
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rcc.h"
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_gpio.h"
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_tim.h"
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_adc.h"
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_spi.h"
|
||||
#include "STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_i2c.h"
|
||||
@@ -45,6 +46,7 @@ extern "C" {
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rcc.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_gpio.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_tim.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_adc.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_spi.h"
|
||||
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_i2c.h"
|
||||
@@ -231,10 +233,15 @@ void checkRotaryEncoder(void);
|
||||
|
||||
// WDT driver
|
||||
#if !defined(SIMU)
|
||||
#if defined(WATCHDOG_DISABLED)
|
||||
#define wdt_enable(x)
|
||||
#define wdt_reset()
|
||||
#else
|
||||
#define wdt_enable(x) watchdogInit(x)
|
||||
#define wdt_reset() IWDG->KR = 0xAAAA
|
||||
#endif
|
||||
#define wdt_disable()
|
||||
void watchdogInit(unsigned int duration);
|
||||
#define wdt_enable(x) watchdogInit(x)
|
||||
#define wdt_reset() IWDG->KR = 0xAAAA
|
||||
#define WAS_RESET_BY_SOFTWARE() (RCC->CSR & RCC_CSR_SFTRSTF)
|
||||
#define WAS_RESET_BY_WATCHDOG() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF))
|
||||
#define WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() (RCC->CSR & (RCC_CSR_WDGRSTF | RCC_CSR_WWDGRSTF | RCC_CSR_SFTRSTF))
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
void extmoduleSendNextFrame();
|
||||
|
||||
void extmoduleStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_CC_IRQn);
|
||||
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_TIMER->DIER &= ~(TIM_DIER_CC2IE | TIM_DIER_UDE);
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
void extmoduleNoneStart()
|
||||
{
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, 0);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz
|
||||
EXTMODULE_TIMER->ARR = 36000; // 18mS
|
||||
EXTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
void extmodulePpmStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz
|
||||
EXTMODULE_TIMER->ARR = 41000;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE;
|
||||
EXTMODULE_TIMER->EGR = 1;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
setupPulsesPPM(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
void set_external_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
|
||||
{
|
||||
EXTMODULE_TIMER->CCR2 = idleTime;
|
||||
EXTMODULE_TIMER->CCR1 = delay;
|
||||
// we are using complementary output so logic has to be reversed here
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | (positive ? 0 : TIM_CCER_CC1NP);
|
||||
}
|
||||
|
||||
void extmodulePxxStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
EXTMODULE_TIMER->ARR = 18000;
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1NE;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 18;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
setupPulsesPXX(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
void extmoduleDsm2Start()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz
|
||||
EXTMODULE_TIMER->ARR = 44000; // 22mS
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1NP;
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = 0;
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
setupPulsesDSM2(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
void extmoduleCrossfireStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, 0);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->PSC = EXTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz
|
||||
EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_FRAME_PERIOD);
|
||||
EXTMODULE_TIMER->CCR2 = (2000 * CROSSFIRE_FRAME_PERIOD) - 1000;
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
void extmoduleSendNextFrame()
|
||||
{
|
||||
if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) {
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].ppm.pulses);
|
||||
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].ppm.ptr - modulePulsesData[EXTERNAL_MODULE].ppm.pulses;
|
||||
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) {
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].pxx.pulses);
|
||||
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].pxx.ptr - modulePulsesData[EXTERNAL_MODULE].pxx.pulses;
|
||||
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) {
|
||||
EXTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
EXTMODULE_DMA_STREAM->CR |= EXTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
EXTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
|
||||
EXTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[EXTERNAL_MODULE].dsm2.pulses);
|
||||
EXTMODULE_DMA_STREAM->NDTR = modulePulsesData[EXTERNAL_MODULE].dsm2.ptr - modulePulsesData[EXTERNAL_MODULE].dsm2.pulses;
|
||||
EXTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
else {
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void EXTMODULE_DMA_IRQHandler()
|
||||
{
|
||||
if (!DMA_GetITStatus(EXTMODULE_DMA_STREAM, EXTMODULE_DMA_FLAG_TC))
|
||||
return;
|
||||
|
||||
DMA_ClearITPendingBit(EXTMODULE_DMA_STREAM, EXTMODULE_DMA_FLAG_TC);
|
||||
|
||||
uint32_t arr = EXTMODULE_TIMER->ARR;
|
||||
if (arr > 4000) {
|
||||
EXTMODULE_TIMER->CCR2 = arr - 4000; // 2mS in advance
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
else {
|
||||
setupPulses(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void EXTMODULE_TIMER_CC_IRQHandler()
|
||||
{
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
setupPulses(EXTERNAL_MODULE);
|
||||
extmoduleSendNextFrame();
|
||||
}
|
||||
@@ -334,9 +334,16 @@
|
||||
#define INTMODULE_PPM_GPIO GPIOA
|
||||
#define INTMODULE_PPM_GPIO_PIN GPIO_Pin_10 // PA.10
|
||||
#define INTMODULE_PPM_GPIO_PinSource GPIO_PinSource10
|
||||
#define INTMODULE_PPM_GPIO_AF GPIO_AF_TIM1
|
||||
#define INTMODULE_TIMER TIM1
|
||||
#define INTMODULE_TIMER_IRQn TIM1_CC_IRQn
|
||||
#define INTMODULE_TIMER_CC_IRQn TIM1_CC_IRQn
|
||||
#define INTMODULE_TIMER_CC_IRQHandler TIM1_CC_IRQHandler
|
||||
#define INTMODULE_PPM_GPIO_AF GPIO_AF_TIM1
|
||||
#define INTMODULE_DMA_CHANNEL DMA_Channel_6
|
||||
#define INTMODULE_DMA_STREAM DMA2_Stream5
|
||||
#define INTMODULE_DMA_IRQn DMA2_Stream5_IRQn
|
||||
#define INTMODULE_DMA_IRQHandler DMA2_Stream5_IRQHandler
|
||||
#define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF5
|
||||
#define INTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
|
||||
// External Module
|
||||
#define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2)
|
||||
@@ -345,10 +352,17 @@
|
||||
#define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PD.08
|
||||
#define EXTMODULE_PPM_GPIO GPIOA
|
||||
#define EXTMODULE_PPM_GPIO_PIN GPIO_Pin_7 // PA.07
|
||||
#define EXTMODULE_PPM_GPIO_PinSource GPIO_PinSource7
|
||||
#define EXTMODULE_TIMER TIM8
|
||||
#define EXTMODULE_PPM_GPIO_AF GPIO_AF_TIM8
|
||||
#define EXTMODULE_PPM_GPIO_PinSource GPIO_PinSource7
|
||||
#define EXTMODULE_TIMER_IRQn TIM8_CC_IRQn
|
||||
#define EXTMODULE_TIMER_CC_IRQn TIM8_CC_IRQn
|
||||
#define EXTMODULE_TIMER_CC_IRQHandler TIM8_CC_IRQHandler
|
||||
#define EXTMODULE_DMA_CHANNEL DMA_Channel_7
|
||||
#define EXTMODULE_DMA_STREAM DMA2_Stream1
|
||||
#define EXTMODULE_DMA_IRQn DMA2_Stream1_IRQn
|
||||
#define EXTMODULE_DMA_IRQHandler DMA2_Stream1_IRQHandler
|
||||
#define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF1
|
||||
#define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
|
||||
|
||||
// Trainer Port
|
||||
#define TRAINER_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -18,32 +18,26 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "../../opentx.h"
|
||||
#include "opentx.h"
|
||||
|
||||
void setupPulses(unsigned int port);
|
||||
void setupPulsesPPM(unsigned int port);
|
||||
void setupPulsesPXX(unsigned int port);
|
||||
void intmoduleStop(void);
|
||||
void extmoduleStop(void);
|
||||
|
||||
static void intmodulePxxStart(void);
|
||||
static void intmodulePxxStop(void);
|
||||
void intmoduleNoneStart(void);
|
||||
void intmodulePxxStart(void);
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
static void intmodulePpmStart(void);
|
||||
static void intmodulePpmStop(void);
|
||||
void intmodulePpmStart(void);
|
||||
#endif
|
||||
static void extmodulePxxStart(void);
|
||||
static void extmodulePxxStop(void);
|
||||
|
||||
void extmoduleNoneStart(void);
|
||||
void extmodulePpmStart(void);
|
||||
void extmodulePxxStart(void);
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
static void extmoduleDsm2Start(void);
|
||||
static void extmoduleDsm2Stop(void);
|
||||
void extmoduleDsm2Start(void);
|
||||
#endif
|
||||
static void extmodulePpmStart(void);
|
||||
static void extmodulePpmStop(void);
|
||||
static void intmoduleNoneStart(void);
|
||||
static void intmoduleNoneStop(void);
|
||||
static void extmoduleNoneStart(void);
|
||||
static void extmoduleNoneStop(void);
|
||||
static void extmoduleCrossfireStart(void);
|
||||
static void extmoduleCrossfireStop(void);
|
||||
void extmoduleCrossfireStart(void);
|
||||
|
||||
void intmoduleSendNextFrame();
|
||||
|
||||
void init_pxx(uint32_t port)
|
||||
{
|
||||
@@ -56,9 +50,9 @@ void init_pxx(uint32_t port)
|
||||
void disable_pxx(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmodulePxxStop();
|
||||
intmoduleStop();
|
||||
else
|
||||
extmodulePxxStop();
|
||||
extmoduleStop();
|
||||
}
|
||||
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
@@ -72,7 +66,7 @@ void init_dsm2(uint32_t port)
|
||||
void disable_dsm2(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmoduleDsm2Stop();
|
||||
extmoduleStop();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -92,32 +86,15 @@ void init_ppm(uint32_t port)
|
||||
void disable_ppm(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmodulePpmStop();
|
||||
extmoduleStop();
|
||||
}
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
else if (port == INTERNAL_MODULE) {
|
||||
intmodulePpmStop();
|
||||
intmoduleStop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_external_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
|
||||
{
|
||||
EXTMODULE_TIMER->CCR2 = idleTime;
|
||||
EXTMODULE_TIMER->CCR1 = delay;
|
||||
// we are using complementary output so logic has to be reversed here
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | (positive ? 0 : TIM_CCER_CC1NP);
|
||||
}
|
||||
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
void set_internal_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
|
||||
{
|
||||
INTMODULE_TIMER->CCR2 = idleTime;
|
||||
INTMODULE_TIMER->CCR3 = delay;
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E | (positive ? TIM_CCER_CC3P : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void init_no_pulses(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
@@ -129,9 +106,9 @@ void init_no_pulses(uint32_t port)
|
||||
void disable_no_pulses(uint32_t port)
|
||||
{
|
||||
if (port == INTERNAL_MODULE)
|
||||
intmoduleNoneStop();
|
||||
intmoduleStop();
|
||||
else
|
||||
extmoduleNoneStop();
|
||||
extmoduleStop();
|
||||
}
|
||||
|
||||
void init_crossfire(uint32_t port)
|
||||
@@ -143,15 +120,27 @@ void init_crossfire(uint32_t port)
|
||||
|
||||
void disable_crossfire(uint32_t port)
|
||||
{
|
||||
if (port == EXTERNAL_MODULE)
|
||||
extmoduleCrossfireStop();
|
||||
if (port == EXTERNAL_MODULE) {
|
||||
extmoduleStop();
|
||||
}
|
||||
}
|
||||
|
||||
static void intmoduleNoneStart()
|
||||
void intmoduleStop()
|
||||
{
|
||||
INTERNAL_MODULE_OFF();
|
||||
|
||||
NVIC_DisableIRQ(INTMODULE_DMA_IRQn);
|
||||
NVIC_DisableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
|
||||
INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
INTMODULE_TIMER->DIER &= ~(TIM_DIER_CC2IE | TIM_DIER_UDE);
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
void intmoduleNoneStart()
|
||||
{
|
||||
INTERNAL_MODULE_OFF();
|
||||
|
||||
// Timer1, channel 3
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = INTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
@@ -159,241 +148,115 @@ static void intmoduleNoneStart()
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(INTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(INTMODULE_PPM_GPIO, INTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
INTMODULE_TIMER->ARR = 36000; // 18mS
|
||||
INTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
INTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = 0;
|
||||
INTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz
|
||||
INTMODULE_TIMER->ARR = 36000; // 18mS
|
||||
INTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
INTMODULE_TIMER->EGR = 1; // Restart
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7);
|
||||
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
static void intmoduleNoneStop()
|
||||
{
|
||||
NVIC_DisableIRQ(INTMODULE_TIMER_IRQn);
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
static void extmoduleNoneStart()
|
||||
{
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->ARR = 36000; // 18mS
|
||||
EXTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
EXTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
|
||||
EXTMODULE_TIMER->CCMR2 = 0;
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmoduleNoneStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
}
|
||||
|
||||
static void extmoduleCrossfireStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
GPIO_SetBits(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PIN); // Set high
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->ARR = (2000 * CROSSFIRE_FRAME_PERIOD);
|
||||
EXTMODULE_TIMER->CCR2 = 32000; // Update time
|
||||
EXTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
|
||||
EXTMODULE_TIMER->CCMR2 = 0;
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmoduleCrossfireStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
static void intmodulePxxStart()
|
||||
void intmodulePxxStart()
|
||||
{
|
||||
INTERNAL_MODULE_ON();
|
||||
|
||||
// Timer1, channel 3
|
||||
setupPulsesPXX(INTERNAL_MODULE); // TODO not here!
|
||||
GPIO_PinAFConfig(INTMODULE_PPM_GPIO, INTMODULE_PPM_GPIO_PinSource, INTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
GPIO_PinAFConfig(INTMODULE_PPM_GPIO, INTMODULE_PPM_GPIO_PinSource, INTMODULE_PPM_GPIO_AF);
|
||||
GPIO_InitStructure.GPIO_Pin = INTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(INTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
INTMODULE_TIMER->ARR = 18000; // 9mS
|
||||
INTMODULE_TIMER->CCR2 = 15000; // Update time
|
||||
INTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
||||
INTMODULE_TIMER->CR2 = TIM_CR2_OIS3; // O/P idle high
|
||||
INTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
INTMODULE_TIMER->CCR3 = modulePulsesData[INTERNAL_MODULE].pxx.pulses[0];
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high
|
||||
INTMODULE_TIMER->EGR = 1; // Restart
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC3DE; // Enable DMA on CC3 match
|
||||
INTMODULE_TIMER->DCR = 15; // DMA to CC1
|
||||
|
||||
// Enable the DMA channel here, DMA2 stream 6, channel 6
|
||||
DMA2_Stream6->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
DMA2->HIFCR = DMA_HIFCR_CTCIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6; // Write ones to clear bits
|
||||
DMA2_Stream6->CR = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
|
||||
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL;
|
||||
DMA2_Stream6->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->DMAR);
|
||||
DMA2_Stream6->M0AR = CONVERT_PTR_UINT(&modulePulsesData[INTERNAL_MODULE].pxx.pulses[1]);
|
||||
DMA2_Stream6->CR |= DMA_SxCR_EN; // Enable DMA
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz)
|
||||
INTMODULE_TIMER->ARR = 18000;
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E | TIM_CCER_CC3NE;
|
||||
INTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
INTMODULE_TIMER->CCR3 = 16;
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_0; // Force O/P high
|
||||
INTMODULE_TIMER->EGR = 1; // Restart
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_UDE; // Enable DMA on update
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
|
||||
INTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void intmodulePxxStop()
|
||||
{
|
||||
DMA2_Stream6->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
NVIC_DisableIRQ(INTMODULE_TIMER_IRQn);
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
INTERNAL_MODULE_OFF();
|
||||
setupPulsesPXX(INTERNAL_MODULE);
|
||||
intmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(INTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
// PPM output
|
||||
// Timer 1, channel 1 on PA8 for prototype
|
||||
// Pin is AF1 function for timer 1
|
||||
static void intmodulePpmStart()
|
||||
void intmodulePpmStart()
|
||||
{
|
||||
INTERNAL_MODULE_ON();
|
||||
|
||||
// Timer1
|
||||
configure_pins(INTMODULE_PPM_GPIO_PIN, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_1 | PIN_OS25);
|
||||
|
||||
GPIO_PinAFConfig(INTMODULE_PPM_GPIO, INTMODULE_PPM_GPIO_PinSource, INTMODULE_PPM_GPIO_AF);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = INTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(INTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
// setupPulsesPPM() is also configuring registers,
|
||||
// so it has to be called after the peripheral is enabled
|
||||
setupPulsesPPM(INTERNAL_MODULE);
|
||||
|
||||
INTMODULE_TIMER->ARR = *modulePulsesData[INTERNAL_MODULE].ppm.ptr++;
|
||||
INTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E;
|
||||
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // PWM mode 1
|
||||
INTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS from 30MHz
|
||||
INTMODULE_TIMER->ARR = 41000;
|
||||
INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // PWM mode 1
|
||||
INTMODULE_TIMER->BDTR = TIM_BDTR_MOE;
|
||||
INTMODULE_TIMER->EGR = 1;
|
||||
INTMODULE_TIMER->DIER = TIM_DIER_UDE;
|
||||
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_UIE;
|
||||
|
||||
INTMODULE_TIMER->CR1 = TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7);
|
||||
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
|
||||
NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 7);
|
||||
|
||||
setupPulsesPPM(INTERNAL_MODULE);
|
||||
intmoduleSendNextFrame();
|
||||
|
||||
NVIC_EnableIRQ(INTMODULE_DMA_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_DMA_IRQn, 7);
|
||||
NVIC_EnableIRQ(INTMODULE_TIMER_CC_IRQn);
|
||||
NVIC_SetPriority(INTMODULE_TIMER_CC_IRQn, 7);
|
||||
}
|
||||
|
||||
static void intmodulePpmStop()
|
||||
void set_internal_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive)
|
||||
{
|
||||
NVIC_DisableIRQ(INTMODULE_TIMER_IRQn);
|
||||
NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE & ~TIM_DIER_UIE;
|
||||
INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
INTERNAL_MODULE_OFF();
|
||||
INTMODULE_TIMER->CCR2 = idleTime;
|
||||
INTMODULE_TIMER->CCR3 = delay;
|
||||
INTMODULE_TIMER->CCER = TIM_CCER_CC3E | (positive ? TIM_CCER_CC3P : 0);
|
||||
}
|
||||
#endif // #if defined(TARANIS_INTERNAL_PPM)
|
||||
#endif // defined(TARANIS_INTERNAL_PPM)
|
||||
|
||||
#if !defined(SIMU)
|
||||
extern "C" void TIM1_CC_IRQHandler()
|
||||
void intmoduleSendNextFrame()
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_TIM1CC);
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // stop this interrupt
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // clear flag
|
||||
DMA2_Stream6->CR &= ~DMA_SxCR_EN; // disable DMA, it will have the whole of the execution time of setupPulses() to actually stop
|
||||
|
||||
setupPulses(INTERNAL_MODULE);
|
||||
|
||||
if (s_current_protocol[INTERNAL_MODULE] == PROTO_PXX) {
|
||||
DMA2->HIFCR = DMA_HIFCR_CTCIF6 | DMA_HIFCR_CHTIF6 | DMA_HIFCR_CTEIF6 | DMA_HIFCR_CDMEIF6 | DMA_HIFCR_CFEIF6;
|
||||
DMA2_Stream6->M0AR = CONVERT_PTR_UINT(&modulePulsesData[INTERNAL_MODULE].pxx.pulses[1]);
|
||||
DMA2_Stream6->CR |= DMA_SxCR_EN; // enable DMA
|
||||
INTMODULE_TIMER->CCR3 = modulePulsesData[INTERNAL_MODULE].pxx.pulses[0];
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // enable this interrupt
|
||||
INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
INTMODULE_DMA_STREAM->CR |= INTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR);
|
||||
INTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[INTERNAL_MODULE].pxx.pulses);
|
||||
INTMODULE_DMA_STREAM->NDTR = modulePulsesData[INTERNAL_MODULE].pxx.ptr - modulePulsesData[INTERNAL_MODULE].pxx.pulses;
|
||||
INTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
else if (s_current_protocol[INTERNAL_MODULE] == PROTO_PPM) {
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_UDE;
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_UIF;
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_UIE;
|
||||
INTMODULE_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
INTMODULE_DMA_STREAM->CR |= INTMODULE_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
|
||||
INTMODULE_DMA_STREAM->PAR = CONVERT_PTR_UINT(&INTMODULE_TIMER->ARR);
|
||||
INTMODULE_DMA_STREAM->M0AR = CONVERT_PTR_UINT(modulePulsesData[INTERNAL_MODULE].ppm.pulses);
|
||||
INTMODULE_DMA_STREAM->NDTR = modulePulsesData[INTERNAL_MODULE].ppm.ptr - modulePulsesData[INTERNAL_MODULE].ppm.pulses;
|
||||
INTMODULE_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
@@ -401,226 +264,29 @@ extern "C" void TIM1_CC_IRQHandler()
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void TIM1_UP_TIM10_IRQHandler()
|
||||
extern "C" void INTMODULE_DMA_IRQHandler()
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_TIM1);
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
|
||||
if (!DMA_GetITStatus(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC))
|
||||
return;
|
||||
|
||||
INTMODULE_TIMER->ARR = *modulePulsesData[INTERNAL_MODULE].ppm.ptr++;
|
||||
if (*modulePulsesData[INTERNAL_MODULE].ppm.ptr == 0) {
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear this flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
}
|
||||
#endif
|
||||
DMA_ClearITPendingBit(INTMODULE_DMA_STREAM, INTMODULE_DMA_FLAG_TC);
|
||||
|
||||
void extmodulePxxStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
setupPulsesPXX(EXTERNAL_MODULE);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->ARR = 18000; // 9mS
|
||||
EXTMODULE_TIMER->CCR2 = 15000; // Update time
|
||||
EXTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE;
|
||||
EXTMODULE_TIMER->CR2 = TIM_CR2_OIS1; // O/P idle high
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].pxx.pulses[0];
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC1DE; // Enable DMA on CC1 match
|
||||
EXTMODULE_TIMER->DCR = 13; // DMA to CC1
|
||||
|
||||
// Enable the DMA channel here, DMA2 stream 2, channel 7
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2; // Write ones to clear bits
|
||||
DMA2_Stream2->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
|
||||
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL;
|
||||
DMA2_Stream2->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->DMAR);
|
||||
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].pxx.pulses[1]);
|
||||
DMA2_Stream2->CR |= DMA_SxCR_EN; // Enable DMA
|
||||
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmodulePxxStop()
|
||||
{
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DSM2) || defined(MULTIMODULE)
|
||||
static void extmoduleDsm2Start()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
setupPulsesDSM2(EXTERNAL_MODULE);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_PinAFConfig(EXTMODULE_PPM_GPIO, EXTMODULE_PPM_GPIO_PinSource, EXTMODULE_PPM_GPIO_AF);
|
||||
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PPM_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(EXTMODULE_PPM_GPIO, &GPIO_InitStructure);
|
||||
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
EXTMODULE_TIMER->ARR = 44000; // 22mS
|
||||
EXTMODULE_TIMER->CCR2 = 40000; // Update time
|
||||
EXTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
EXTMODULE_TIMER->CCER = TIM_CCER_CC1NE | TIM_CCER_CC1NP;
|
||||
EXTMODULE_TIMER->CR2 = TIM_CR2_OIS1; // O/P idle high
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[0];
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high
|
||||
EXTMODULE_TIMER->EGR = 1; // Restart
|
||||
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC1DE; // Enable DMA on CC1 match
|
||||
EXTMODULE_TIMER->DCR = 13; // DMA to CC1
|
||||
|
||||
// Enable the DMA channel here, DMA2 stream 2, channel 7
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2; // Write ones to clear bits
|
||||
DMA2_Stream2->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0
|
||||
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_PFCTRL;
|
||||
DMA2_Stream2->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->DMAR);
|
||||
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
|
||||
// DMA2_Stream2->FCR = 0x05; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0;
|
||||
// DMA2_Stream2->NDTR = 100;
|
||||
DMA2_Stream2->CR |= DMA_SxCR_EN; // Enable DMA
|
||||
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; // Toggle CC1 o/p
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmoduleDsm2Stop()
|
||||
{
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void extmodulePpmStart()
|
||||
{
|
||||
EXTERNAL_MODULE_ON();
|
||||
|
||||
configure_pins(EXTMODULE_PPM_GPIO_PIN, PIN_PERIPHERAL | PIN_PORTA | PIN_PER_3 | PIN_OS25);
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
|
||||
// setupPulsesPPM() is also configuring registers,
|
||||
// so it has to be called after the peripheral is enabled
|
||||
setupPulsesPPM(EXTERNAL_MODULE);
|
||||
|
||||
EXTMODULE_TIMER->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++;
|
||||
EXTMODULE_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS from 30MHz
|
||||
|
||||
EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE; // PWM mode 1
|
||||
EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE;
|
||||
EXTMODULE_TIMER->EGR = 1;
|
||||
EXTMODULE_TIMER->DIER = TIM_DIER_UDE;
|
||||
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE;
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UIE;
|
||||
|
||||
EXTMODULE_TIMER->CR1 = TIM_CR1_CEN;
|
||||
NVIC_EnableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7);
|
||||
NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
|
||||
NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 7);
|
||||
}
|
||||
|
||||
static void extmodulePpmStop()
|
||||
{
|
||||
NVIC_DisableIRQ(EXTMODULE_TIMER_IRQn);
|
||||
NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn);
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE & ~TIM_DIER_UIE;
|
||||
EXTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN;
|
||||
if (!IS_TRAINER_EXTERNAL_MODULE()) {
|
||||
EXTERNAL_MODULE_OFF();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
extern "C" void TIM8_CC_IRQHandler()
|
||||
{
|
||||
EXTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // stop this interrupt
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
|
||||
setupPulses(EXTERNAL_MODULE);
|
||||
|
||||
if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PXX) {
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2; // Write ones to clear bits
|
||||
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].pxx.pulses[1]);
|
||||
DMA2_Stream2->CR |= DMA_SxCR_EN; // Enable DMA
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].pxx.pulses[0];
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
#if defined(DSM2)
|
||||
else if ((s_current_protocol[EXTERNAL_MODULE] >= PROTO_DSM2_LP45 && s_current_protocol[EXTERNAL_MODULE] <= PROTO_DSM2_DSMX) || IS_MULTIMODULE_PROTOCOL (s_current_protocol[EXTERNAL_MODULE]))
|
||||
|
||||
{
|
||||
DMA2_Stream2->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF2 | DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTEIF2 | DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2; // Write ones to clear bits
|
||||
DMA2_Stream2->M0AR = CONVERT_PTR_UINT(&modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[1]);
|
||||
DMA2_Stream2->CR |= DMA_SxCR_EN; // Enable DMA
|
||||
EXTMODULE_TIMER->CCR1 = modulePulsesData[EXTERNAL_MODULE].dsm2.pulses[0];
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
#endif
|
||||
else if (s_current_protocol[EXTERNAL_MODULE] == PROTO_PPM) {
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UDE;
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_UIF; // Clear this flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_UIE; // Enable this interrupt
|
||||
uint32_t arr = INTMODULE_TIMER->ARR;
|
||||
if (arr > 5000) {
|
||||
INTMODULE_TIMER->CCR2 = arr - 4000; // 2mS in advance
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag
|
||||
INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
else {
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
setupPulses(INTERNAL_MODULE);
|
||||
intmoduleSendNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void TIM8_UP_TIM13_IRQHandler()
|
||||
extern "C" void INTMODULE_TIMER_CC_IRQHandler()
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_TIM8);
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_UIF; // Clear flag
|
||||
|
||||
EXTMODULE_TIMER->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++;
|
||||
if (*modulePulsesData[EXTERNAL_MODULE].ppm.ptr == 0) {
|
||||
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear this flag
|
||||
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt
|
||||
}
|
||||
INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; // Stop this interrupt
|
||||
INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF;
|
||||
setupPulses(INTERNAL_MODULE);
|
||||
intmoduleSendNextFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user