1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-21 15:25:36 +03:00

Merge remote-tracking branch 'refs/remotes/betaflight/master' into betaflight

This commit is contained in:
tianbin4279 2016-07-14 22:45:12 +08:00
commit b15e2ed62c
250 changed files with 5240 additions and 4128 deletions

View file

@ -600,6 +600,7 @@ LDFLAGS = -lm \
-Wl,-gc-sections,-Map,$(TARGET_MAP) \ -Wl,-gc-sections,-Map,$(TARGET_MAP) \
-Wl,-L$(LINKER_DIR) \ -Wl,-L$(LINKER_DIR) \
-Wl,--cref \ -Wl,--cref \
-Wl,--no-wchar-size-warning \
-T$(LD_SCRIPT) -T$(LD_SCRIPT)
############################################################################### ###############################################################################
@ -664,27 +665,39 @@ all: $(VALID_TARGETS)
$(VALID_TARGETS): $(VALID_TARGETS):
echo "" && \ echo "" && \
echo "Building $@" && \ echo "Building $@" && \
$(MAKE) -j binary hex TARGET=$@ && \ $(MAKE) binary hex TARGET=$@ && \
echo "Building $@ succeeded." echo "Building $@ succeeded."
## clean : clean up all temporary / machine-generated files
CLEAN_TARGETS = $(addprefix clean_,$(VALID_TARGETS) )
TARGETS_CLEAN = $(addsuffix _clean,$(VALID_TARGETS) )
## clean : clean up temporary / machine-generated files
clean: clean:
echo "Cleaning $(TARGET)"
rm -f $(CLEAN_ARTIFACTS) rm -f $(CLEAN_ARTIFACTS)
rm -rf $(OBJECT_DIR)/$(TARGET) rm -rf $(OBJECT_DIR)/$(TARGET)
echo "Cleaning $(TARGET) succeeded."
## clean_test : clean up all temporary / machine-generated files (tests) ## clean_test : clean up temporary / machine-generated files (tests)
clean_test: clean_test:
cd src/test && $(MAKE) clean || true cd src/test && $(MAKE) clean || true
## clean_all_targets : clean all valid target platforms ## clean_<TARGET> : clean up one specific target
clean_all: $(CLEAN_TARGETS) :
for clean_target in $(VALID_TARGETS); do \ $(MAKE) -j TARGET=$(subst clean_,,$@) clean
echo "" && \
echo "Cleaning $$clean_target" && \ ## <TARGET>_clean : clean up one specific target (alias for above)
$(MAKE) -j TARGET=$$clean_target clean || \ $(TARGETS_CLEAN) :
break; \ $(MAKE) -j TARGET=$(subst _clean,,$@) clean
echo "Cleaning $$clean_target succeeded."; \
done ## clean_all : clean all valid targets
clean_all:$(CLEAN_TARGETS)
## all_clean : clean all valid targets (alias for above)
all_clean:$(TARGETS_CLEAN)
flash_$(TARGET): $(TARGET_HEX) flash_$(TARGET): $(TARGET_HEX)
stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
@ -700,8 +713,11 @@ st-flash_$(TARGET): $(TARGET_BIN)
## st-flash : flash firmware (.bin) onto flight controller ## st-flash : flash firmware (.bin) onto flight controller
st-flash: st-flash_$(TARGET) st-flash: st-flash_$(TARGET)
binary: $(TARGET_BIN) binary:
hex: $(TARGET_HEX) $(MAKE) -j $(TARGET_BIN)
hex:
$(MAKE) -j $(TARGET_HEX)
unbrick_$(TARGET): $(TARGET_HEX) unbrick_$(TARGET): $(TARGET_HEX)
stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon

View file

@ -1,6 +1,6 @@
# Betaflight # Betaflight
![Betaflight](https://dl.dropboxusercontent.com/u/31537757/betaflight%20logo.jpg) ![Betaflight](https://camo.githubusercontent.com/8178215d6cb90842dc95c9d437b1bdf09b2d57a7/687474703a2f2f7374617469632e726367726f7570732e6e65742f666f72756d732f6174746163686d656e74732f362f312f302f332f372f362f61393038383930302d3232382d62665f6c6f676f2e6a7067)
Clean-code version of baseflight flight-controller - flight controllers are used to fly multi-rotor craft and fixed wing craft. Clean-code version of baseflight flight-controller - flight controllers are used to fly multi-rotor craft and fixed wing craft.

View file

@ -20,7 +20,10 @@ targets=("PUBLISHMETA=True" \
"TARGET=ALIENFLIGHTF3" \ "TARGET=ALIENFLIGHTF3" \
"TARGET=DOGE" \ "TARGET=DOGE" \
"TARGET=SINGULARITY" \ "TARGET=SINGULARITY" \
"TARGET=SIRINFPV") "TARGET=SIRINFPV" \
"TARGET=X_RACERSPI")
#fake a travis build environment #fake a travis build environment
export TRAVIS_BUILD_NUMBER=$(date +%s) export TRAVIS_BUILD_NUMBER=$(date +%s)

View file

@ -325,9 +325,6 @@ extern uint32_t currentTime;
//From rx.c: //From rx.c:
extern uint16_t rssi; extern uint16_t rssi;
//From gyro.c
extern uint32_t targetLooptime;
//From rc_controls.c //From rc_controls.c
extern uint32_t rcModeActivationMask; extern uint32_t rcModeActivationMask;
@ -1169,7 +1166,7 @@ static bool blackboxWriteSysinfo()
} }
); );
BLACKBOX_PRINT_HEADER_LINE("looptime:%d", targetLooptime); BLACKBOX_PRINT_HEADER_LINE("looptime:%d", gyro.targetLooptime);
BLACKBOX_PRINT_HEADER_LINE("rcRate:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcRate8); BLACKBOX_PRINT_HEADER_LINE("rcRate:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcRate8);
BLACKBOX_PRINT_HEADER_LINE("rcExpo:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcExpo8); BLACKBOX_PRINT_HEADER_LINE("rcExpo:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcExpo8);
BLACKBOX_PRINT_HEADER_LINE("rcYawRate:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcYawRate8); BLACKBOX_PRINT_HEADER_LINE("rcYawRate:%d", masterConfig.profile[masterConfig.current_profile_index].controlRateProfile[masterConfig.profile[masterConfig.current_profile_index].activeRateProfile].rcYawRate8);

View file

@ -22,7 +22,6 @@
#include "drivers/accgyro.h" #include "drivers/accgyro.h"
#include "drivers/light_led.h" #include "drivers/light_led.h"
#include "drivers/sound_beeper.h" #include "drivers/sound_beeper.h"
#include "drivers/gyro_sync.h"
#include "sensors/sensors.h" #include "sensors/sensors.h"
#include "sensors/boardalignment.h" #include "sensors/boardalignment.h"

View file

@ -85,7 +85,7 @@ static inline uint8_t __basepriSetRetVal(uint8_t prio)
// ideally this would only protect memory passed as parameter (any type should work), but gcc is curently creating almost full barrier // ideally this would only protect memory passed as parameter (any type should work), but gcc is curently creating almost full barrier
// this macro can be used only ONCE PER LINE, but multiple uses per block are fine // this macro can be used only ONCE PER LINE, but multiple uses per block are fine
#if (__GNUC__ > 4) #if (__GNUC__ > 5)
#warning "Please verify that ATOMIC_BARRIER works as intended" #warning "Please verify that ATOMIC_BARRIER works as intended"
// increment version number is BARRIER works // increment version number is BARRIER works
// TODO - use flag to disable ATOMIC_BARRIER and use full barrier instead // TODO - use flag to disable ATOMIC_BARRIER and use full barrier instead

View file

@ -17,10 +17,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <math.h> #include <math.h>
#include "common/axis.h"
#include "common/filter.h" #include "common/filter.h"
#include "common/maths.h" #include "common/maths.h"
@ -30,63 +28,70 @@
#define BIQUAD_BANDWIDTH 1.9f /* bandwidth in octaves */ #define BIQUAD_BANDWIDTH 1.9f /* bandwidth in octaves */
#define BIQUAD_Q 1.0f / sqrtf(2.0f) /* quality factor - butterworth*/ #define BIQUAD_Q 1.0f / sqrtf(2.0f) /* quality factor - butterworth*/
// PT1 Low Pass filter (when no dT specified it will be calculated from the cycleTime) // PT1 Low Pass filter
float filterApplyPt1(float input, filterStatePt1_t *filter, float f_cut, float dT) {
void pt1FilterInit(pt1Filter_t *filter, uint8_t f_cut, float dT)
{
filter->RC = 1.0f / ( 2.0f * M_PI_FLOAT * f_cut );
filter->dT = dT;
}
float pt1FilterApply(pt1Filter_t *filter, float input)
{
filter->state = filter->state + filter->dT / (filter->RC + filter->dT) * (input - filter->state);
return filter->state;
}
float pt1FilterApply4(pt1Filter_t *filter, float input, uint8_t f_cut, float dT)
{
// Pre calculate and store RC // Pre calculate and store RC
if (!filter->RC) { if (!filter->RC) {
filter->RC = 1.0f / ( 2.0f * M_PI_FLOAT * f_cut ); filter->RC = 1.0f / ( 2.0f * M_PI_FLOAT * f_cut );
filter->dT = dT;
} }
filter->state = filter->state + dT / (filter->RC + dT) * (input - filter->state); filter->state = filter->state + filter->dT / (filter->RC + filter->dT) * (input - filter->state);
return filter->state; return filter->state;
} }
/* sets up a biquad Filter */ /* sets up a biquad Filter */
void BiQuadNewLpf(float filterCutFreq, biquad_t *newState, uint32_t refreshRate) void biquadFilterInit(biquadFilter_t *filter, float filterCutFreq, uint32_t refreshRate)
{ {
float sampleRate; const float sampleRate = 1 / ((float)refreshRate * 0.000001f);
sampleRate = 1 / ((float)refreshRate * 0.000001f); // setup variables
const float omega = 2 * M_PI_FLOAT * filterCutFreq / sampleRate;
float omega, sn, cs, alpha; const float sn = sinf(omega);
float a0, a1, a2, b0, b1, b2; const float cs = cosf(omega);
/* setup variables */
omega = 2 * M_PI_FLOAT * filterCutFreq / sampleRate;
sn = sinf(omega);
cs = cosf(omega);
//this is wrong, should be hyperbolic sine //this is wrong, should be hyperbolic sine
//alpha = sn * sinf(M_LN2_FLOAT /2 * BIQUAD_BANDWIDTH * omega /sn); //alpha = sn * sinf(M_LN2_FLOAT /2 * BIQUAD_BANDWIDTH * omega /sn);
alpha = sn / (2 * BIQUAD_Q); const float alpha = sn / (2 * BIQUAD_Q);
b0 = (1 - cs) / 2; const float b0 = (1 - cs) / 2;
b1 = 1 - cs; const float b1 = 1 - cs;
b2 = (1 - cs) / 2; const float b2 = (1 - cs) / 2;
a0 = 1 + alpha; const float a0 = 1 + alpha;
a1 = -2 * cs; const float a1 = -2 * cs;
a2 = 1 - alpha; const float a2 = 1 - alpha;
/* precompute the coefficients */ // precompute the coefficients
newState->b0 = b0 / a0; filter->b0 = b0 / a0;
newState->b1 = b1 / a0; filter->b1 = b1 / a0;
newState->b2 = b2 / a0; filter->b2 = b2 / a0;
newState->a1 = a1 / a0; filter->a1 = a1 / a0;
newState->a2 = a2 / a0; filter->a2 = a2 / a0;
/* zero initial samples */ // zero initial samples
newState->d1 = newState->d2 = 1; filter->d1 = filter->d2 = 0;
} }
/* Computes a biquad_t filter on a sample */ /* Computes a biquad_t filter on a sample */
float applyBiQuadFilter(float sample, biquad_t *state) //direct form 2 transposed float biquadFilterApply(biquadFilter_t *filter, float input)
{ {
float result; const float result = filter->b0 * input + filter->d1;
filter->d1 = filter->b1 * input - filter->a1 * result + filter->d2;
result = state->b0 * sample + state->d1; filter->d2 = filter->b2 * input - filter->a2 * result;
state->d1 = state->b1 * sample - state->a1 * result + state->d2;
state->d2 = state->b2 * sample - state->a2 * result;
return result; return result;
} }

View file

@ -17,20 +17,26 @@
#define DELTA_MAX_SAMPLES 12 #define DELTA_MAX_SAMPLES 12
typedef struct filterStatePt1_s { typedef struct pt1Filter_s {
float state; float state;
float RC; float RC;
float constdT; float dT;
} filterStatePt1_t; } pt1Filter_t;
/* this holds the data required to update samples thru a filter */ /* this holds the data required to update samples thru a filter */
typedef struct biquad_s { typedef struct biquadFilter_s {
float b0, b1, b2, a1, a2; float b0, b1, b2, a1, a2;
float d1, d2; float d1, d2;
} biquad_t; } biquadFilter_t;
void biquadFilterInit(biquadFilter_t *filter, float filterCutFreq, uint32_t refreshRate);
float biquadFilterApply(biquadFilter_t *filter, float input);
void pt1FilterInit(pt1Filter_t *filter, uint8_t f_cut, float dT);
float pt1FilterApply(pt1Filter_t *filter, float input);
float pt1FilterApply4(pt1Filter_t *filter, float input, uint8_t f_cut, float dT);
float applyBiQuadFilter(float sample, biquad_t *state);
float filterApplyPt1(float input, filterStatePt1_t *filter, float f_cut, float dt);
int32_t filterApplyAverage(int32_t input, uint8_t averageCount, int32_t averageState[DELTA_MAX_SAMPLES]); int32_t filterApplyAverage(int32_t input, uint8_t averageCount, int32_t averageState[DELTA_MAX_SAMPLES]);
float filterApplyAveragef(float input, uint8_t averageCount, float averageState[DELTA_MAX_SAMPLES]); float filterApplyAveragef(float input, uint8_t averageCount, float averageState[DELTA_MAX_SAMPLES]);
void BiQuadNewLpf(float filterCutFreq, biquad_t *newState, uint32_t refreshRate);

View file

@ -38,7 +38,6 @@
#include "drivers/timer.h" #include "drivers/timer.h"
#include "drivers/pwm_rx.h" #include "drivers/pwm_rx.h"
#include "drivers/serial.h" #include "drivers/serial.h"
#include "drivers/gyro_sync.h"
#include "drivers/pwm_output.h" #include "drivers/pwm_output.h"
#include "drivers/max7456.h" #include "drivers/max7456.h"
@ -90,6 +89,7 @@
#endif #endif
void useRcControlsConfig(modeActivationCondition_t *modeActivationConditions, escAndServoConfig_t *escAndServoConfigToUse, pidProfile_t *pidProfileToUse); void useRcControlsConfig(modeActivationCondition_t *modeActivationConditions, escAndServoConfig_t *escAndServoConfigToUse, pidProfile_t *pidProfileToUse);
void targetConfiguration(void);
#if !defined(FLASH_SIZE) #if !defined(FLASH_SIZE)
#error "Flash size not defined for target. (specify in KB)" #error "Flash size not defined for target. (specify in KB)"
@ -269,8 +269,13 @@ void resetSensorAlignment(sensorAlignmentConfig_t *sensorAlignmentConfig)
void resetEscAndServoConfig(escAndServoConfig_t *escAndServoConfig) void resetEscAndServoConfig(escAndServoConfig_t *escAndServoConfig)
{ {
#ifdef BRUSHED_MOTORS
escAndServoConfig->minthrottle = 1000;
escAndServoConfig->maxthrottle = 2000;
#else
escAndServoConfig->minthrottle = 1150; escAndServoConfig->minthrottle = 1150;
escAndServoConfig->maxthrottle = 1850; escAndServoConfig->maxthrottle = 1850;
#endif
escAndServoConfig->mincommand = 1000; escAndServoConfig->mincommand = 1000;
escAndServoConfig->servoCenterPulse = 1500; escAndServoConfig->servoCenterPulse = 1500;
escAndServoConfig->escDesyncProtection = 0; escAndServoConfig->escDesyncProtection = 0;
@ -416,8 +421,6 @@ uint16_t getCurrentMinthrottle(void)
// Default settings // Default settings
static void resetConf(void) static void resetConf(void)
{ {
int i;
// Clear all configuration // Clear all configuration
memset(&masterConfig, 0, sizeof(master_t)); memset(&masterConfig, 0, sizeof(master_t));
setProfile(0); setProfile(0);
@ -478,7 +481,11 @@ static void resetConf(void)
resetTelemetryConfig(&masterConfig.telemetryConfig); resetTelemetryConfig(&masterConfig.telemetryConfig);
#ifdef SERIALRX_PROVIDER
masterConfig.rxConfig.serialrx_provider = SERIALRX_PROVIDER;
#else
masterConfig.rxConfig.serialrx_provider = 0; masterConfig.rxConfig.serialrx_provider = 0;
#endif
masterConfig.rxConfig.sbus_inversion = 1; masterConfig.rxConfig.sbus_inversion = 1;
masterConfig.rxConfig.spektrum_sat_bind = 0; masterConfig.rxConfig.spektrum_sat_bind = 0;
masterConfig.rxConfig.spektrum_sat_bind_autoreset = 1; masterConfig.rxConfig.spektrum_sat_bind_autoreset = 1;
@ -488,7 +495,7 @@ static void resetConf(void)
masterConfig.rxConfig.rx_min_usec = 885; // any of first 4 channels below this value will trigger rx loss detection masterConfig.rxConfig.rx_min_usec = 885; // any of first 4 channels below this value will trigger rx loss detection
masterConfig.rxConfig.rx_max_usec = 2115; // any of first 4 channels above this value will trigger rx loss detection masterConfig.rxConfig.rx_max_usec = 2115; // any of first 4 channels above this value will trigger rx loss detection
for (i = 0; i < MAX_SUPPORTED_RC_CHANNEL_COUNT; i++) { for (int i = 0; i < MAX_SUPPORTED_RC_CHANNEL_COUNT; i++) {
rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &masterConfig.rxConfig.failsafe_channel_configurations[i]; rxFailsafeChannelConfiguration_t *channelFailsafeConfiguration = &masterConfig.rxConfig.failsafe_channel_configurations[i];
channelFailsafeConfiguration->mode = (i < NON_AUX_CHANNEL_COUNT) ? RX_FAILSAFE_MODE_AUTO : RX_FAILSAFE_MODE_HOLD; channelFailsafeConfiguration->mode = (i < NON_AUX_CHANNEL_COUNT) ? RX_FAILSAFE_MODE_AUTO : RX_FAILSAFE_MODE_HOLD;
channelFailsafeConfiguration->step = (i == THROTTLE) ? CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.rx_min_usec) : CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.midrc); channelFailsafeConfiguration->step = (i == THROTTLE) ? CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.rx_min_usec) : CHANNEL_VALUE_TO_RXFAIL_STEP(masterConfig.rxConfig.midrc);
@ -550,8 +557,7 @@ static void resetConf(void)
resetPidProfile(&currentProfile->pidProfile); resetPidProfile(&currentProfile->pidProfile);
uint8_t rI; for (int rI = 0; rI<MAX_RATEPROFILES; rI++) {
for (rI = 0; rI<MAX_RATEPROFILES; rI++) {
resetControlRateConfig(&masterConfig.profile[0].controlRateProfile[rI]); resetControlRateConfig(&masterConfig.profile[0].controlRateProfile[rI]);
} }
resetRollAndPitchTrims(&masterConfig.accelerometerTrims); resetRollAndPitchTrims(&masterConfig.accelerometerTrims);
@ -582,7 +588,7 @@ static void resetConf(void)
#ifdef USE_SERVOS #ifdef USE_SERVOS
// servos // servos
for (i = 0; i < MAX_SUPPORTED_SERVOS; i++) { for (int i = 0; i < MAX_SUPPORTED_SERVOS; i++) {
masterConfig.servoConf[i].min = DEFAULT_SERVO_MIN; masterConfig.servoConf[i].min = DEFAULT_SERVO_MIN;
masterConfig.servoConf[i].max = DEFAULT_SERVO_MAX; masterConfig.servoConf[i].max = DEFAULT_SERVO_MAX;
masterConfig.servoConf[i].middle = DEFAULT_SERVO_MIDDLE; masterConfig.servoConf[i].middle = DEFAULT_SERVO_MIDDLE;
@ -601,8 +607,9 @@ static void resetConf(void)
#endif #endif
// custom mixer. clear by defaults. // custom mixer. clear by defaults.
for (i = 0; i < MAX_SUPPORTED_MOTORS; i++) for (int i = 0; i < MAX_SUPPORTED_MOTORS; i++) {
masterConfig.customMotorMixer[i].throttle = 0.0f; masterConfig.customMotorMixer[i].throttle = 0.0f;
}
#ifdef LED_STRIP #ifdef LED_STRIP
applyDefaultColors(masterConfig.colors, CONFIGURABLE_COLOR_COUNT); applyDefaultColors(masterConfig.colors, CONFIGURABLE_COLOR_COUNT);
@ -640,61 +647,18 @@ static void resetConf(void)
#endif // BLACKBOX #endif // BLACKBOX
// alternative defaults settings for COLIBRI RACE targets #ifdef SERIALRX_UART
#if defined(COLIBRI_RACE) if (featureConfigured(FEATURE_RX_SERIAL)) {
masterConfig.escAndServoConfig.minthrottle = 1025; masterConfig.serialConfig.portConfigs[SERIALRX_UART].functionMask = FUNCTION_RX_SERIAL;
masterConfig.escAndServoConfig.maxthrottle = 1980; }
masterConfig.batteryConfig.vbatmaxcellvoltage = 45;
masterConfig.batteryConfig.vbatmincellvoltage = 30;
#endif #endif
#if defined(TARGET_CONFIG) #if defined(TARGET_CONFIG)
targetConfiguration(&masterConfig); targetConfiguration();
#endif
#if defined(ALIENFLIGHT)
featureClear(FEATURE_ONESHOT125);
#ifdef ALIENFLIGHTF1
masterConfig.serialConfig.portConfigs[1].functionMask = FUNCTION_RX_SERIAL;
#else
masterConfig.serialConfig.portConfigs[2].functionMask = FUNCTION_RX_SERIAL;
#endif
#ifdef ALIENFLIGHTF3
masterConfig.batteryConfig.vbatscale = 20;
masterConfig.mag_hardware = MAG_NONE; // disabled by default
#endif
masterConfig.rxConfig.serialrx_provider = SERIALRX_SPEKTRUM2048;
masterConfig.rxConfig.spektrum_sat_bind = 5;
masterConfig.rxConfig.spektrum_sat_bind_autoreset = 1;
masterConfig.escAndServoConfig.minthrottle = 1000;
masterConfig.escAndServoConfig.maxthrottle = 2000;
masterConfig.motor_pwm_rate = 32000;
masterConfig.failsafeConfig.failsafe_delay = 2;
masterConfig.failsafeConfig.failsafe_off_delay = 0;
currentControlRateProfile->rates[FD_PITCH] = 40;
currentControlRateProfile->rates[FD_ROLL] = 40;
currentControlRateProfile->rates[FD_YAW] = 40;
parseRcChannels("TAER1234", &masterConfig.rxConfig);
masterConfig.customMotorMixer[0] = (motorMixer_t){ 1.0f, -0.414178f, 1.0f, -1.0f }; // REAR_R
masterConfig.customMotorMixer[1] = (motorMixer_t){ 1.0f, -0.414178f, -1.0f, 1.0f }; // FRONT_R
masterConfig.customMotorMixer[2] = (motorMixer_t){ 1.0f, 0.414178f, 1.0f, 1.0f }; // REAR_L
masterConfig.customMotorMixer[3] = (motorMixer_t){ 1.0f, 0.414178f, -1.0f, -1.0f }; // FRONT_L
masterConfig.customMotorMixer[4] = (motorMixer_t){ 1.0f, -1.0f, -0.414178f, -1.0f }; // MIDFRONT_R
masterConfig.customMotorMixer[5] = (motorMixer_t){ 1.0f, 1.0f, -0.414178f, 1.0f }; // MIDFRONT_L
masterConfig.customMotorMixer[6] = (motorMixer_t){ 1.0f, -1.0f, 0.414178f, 1.0f }; // MIDREAR_R
masterConfig.customMotorMixer[7] = (motorMixer_t){ 1.0f, 1.0f, 0.414178f, -1.0f }; // MIDREAR_L#endif
#endif
#if defined(SINGULARITY)
// alternative defaults settings for SINGULARITY target
masterConfig.batteryConfig.vbatscale = 77;
masterConfig.serialConfig.portConfigs[2].functionMask = FUNCTION_RX_SERIAL;
#endif #endif
// copy first profile into remaining profile // copy first profile into remaining profile
for (i = 1; i < MAX_PROFILE_COUNT; i++) { for (int i = 1; i < MAX_PROFILE_COUNT; i++) {
memcpy(&masterConfig.profile[i], currentProfile, sizeof(profile_t)); memcpy(&masterConfig.profile[i], currentProfile, sizeof(profile_t));
} }
@ -751,7 +715,7 @@ void activateConfig(void)
&currentProfile->pidProfile &currentProfile->pidProfile
); );
useGyroConfig(&masterConfig.gyroConfig, masterConfig.gyro_soft_lpf_hz); gyroUseConfig(&masterConfig.gyroConfig, masterConfig.gyro_soft_lpf_hz);
#ifdef TELEMETRY #ifdef TELEMETRY
telemetryUseConfig(&masterConfig.telemetryConfig); telemetryUseConfig(&masterConfig.telemetryConfig);
@ -806,7 +770,7 @@ void activateConfig(void)
void validateAndFixConfig(void) void validateAndFixConfig(void)
{ {
if (!(featureConfigured(FEATURE_RX_PARALLEL_PWM) || featureConfigured(FEATURE_RX_PPM) || featureConfigured(FEATURE_RX_SERIAL) || featureConfigured(FEATURE_RX_MSP))) { if (!(featureConfigured(FEATURE_RX_PARALLEL_PWM) || featureConfigured(FEATURE_RX_PPM) || featureConfigured(FEATURE_RX_SERIAL) || featureConfigured(FEATURE_RX_MSP))) {
featureSet(FEATURE_RX_PARALLEL_PWM); // Consider changing the default to PPM featureSet(DEFAULT_RX_FEATURE);
} }
if (featureConfigured(FEATURE_RX_PPM)) { if (featureConfigured(FEATURE_RX_PPM)) {
@ -848,10 +812,10 @@ void validateAndFixConfig(void)
if (featureConfigured(FEATURE_SOFTSERIAL) && ( if (featureConfigured(FEATURE_SOFTSERIAL) && (
0 0
#ifdef USE_SOFTSERIAL1 #ifdef USE_SOFTSERIAL1
|| (LED_STRIP_TIMER == SOFTSERIAL_1_TIMER) || (WS2811_TIMER == SOFTSERIAL_1_TIMER)
#endif #endif
#ifdef USE_SOFTSERIAL2 #ifdef USE_SOFTSERIAL2
|| (LED_STRIP_TIMER == SOFTSERIAL_2_TIMER) || (WS2811_TIMER == SOFTSERIAL_2_TIMER)
#endif #endif
)) { )) {
// led strip needs the same timer as softserial // led strip needs the same timer as softserial
@ -871,7 +835,7 @@ void validateAndFixConfig(void)
} }
#endif #endif
#if defined(CC3D) && defined(DISPLAY) && defined(USE_USART3) #if defined(CC3D) && defined(DISPLAY) && defined(USE_UART3)
if (doesConfigurationUsePort(SERIAL_PORT_USART3) && feature(FEATURE_DISPLAY)) { if (doesConfigurationUsePort(SERIAL_PORT_USART3) && feature(FEATURE_DISPLAY)) {
featureClear(FEATURE_DISPLAY); featureClear(FEATURE_DISPLAY);
} }
@ -901,15 +865,11 @@ void validateAndFixConfig(void)
#if defined(COLIBRI_RACE) #if defined(COLIBRI_RACE)
masterConfig.serialConfig.portConfigs[0].functionMask = FUNCTION_MSP; masterConfig.serialConfig.portConfigs[0].functionMask = FUNCTION_MSP;
if(featureConfigured(FEATURE_RX_PARALLEL_PWM) || featureConfigured(FEATURE_RX_MSP)) { if (featureConfigured(FEATURE_RX_PARALLEL_PWM) || featureConfigured(FEATURE_RX_MSP)) {
featureClear(FEATURE_RX_PARALLEL_PWM); featureClear(FEATURE_RX_PARALLEL_PWM);
featureClear(FEATURE_RX_MSP); featureClear(FEATURE_RX_MSP);
featureSet(FEATURE_RX_PPM); featureSet(FEATURE_RX_PPM);
} }
if(featureConfigured(FEATURE_RX_SERIAL)) {
masterConfig.serialConfig.portConfigs[2].functionMask = FUNCTION_RX_SERIAL;
//masterConfig.rxConfig.serialrx_provider = SERIALRX_SBUS;
}
#endif #endif
useRxConfig(&masterConfig.rxConfig); useRxConfig(&masterConfig.rxConfig);

View file

@ -17,7 +17,11 @@
#pragma once #pragma once
#if FLASH_SIZE <= 128
#define MAX_PROFILE_COUNT 2 #define MAX_PROFILE_COUNT 2
#else
#define MAX_PROFILE_COUNT 3
#endif
#define MAX_RATEPROFILES 3 #define MAX_RATEPROFILES 3
#define ONESHOT_FEATURE_CHANGED_DELAY_ON_BOOT_MS 1500 #define ONESHOT_FEATURE_CHANGED_DELAY_ON_BOOT_MS 1500

View file

@ -27,6 +27,7 @@ typedef struct gyro_s {
sensorReadFuncPtr temperature; // read temperature if available sensorReadFuncPtr temperature; // read temperature if available
sensorInterruptFuncPtr intStatus; sensorInterruptFuncPtr intStatus;
float scale; // scalefactor float scale; // scalefactor
uint32_t targetLooptime;
} gyro_t; } gyro_t;
typedef struct acc_s { typedef struct acc_s {

View file

@ -76,7 +76,7 @@ static void l3gd20SpiInit(SPI_TypeDef *SPIx)
UNUSED(SPIx); // FIXME UNUSED(SPIx); // FIXME
mpul3gd20CsPin = IOGetByTag(IO_TAG(L3GD20_CS_PIN)); mpul3gd20CsPin = IOGetByTag(IO_TAG(L3GD20_CS_PIN));
IOInit(mpul3gd20CsPin, OWNER_SYSTEM, RESOURCE_SPI); IOInit(mpul3gd20CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
IOConfigGPIO(mpul3gd20CsPin, SPI_IO_CS_CFG); IOConfigGPIO(mpul3gd20CsPin, SPI_IO_CS_CFG);
DISABLE_L3GD20; DISABLE_L3GD20;

View file

@ -19,14 +19,13 @@
#include <stdint.h> #include <stdint.h>
#include "platform.h" #include "platform.h"
#include "build_config.h"
#include "debug.h" #include "debug.h"
#include "common/maths.h" #include "common/maths.h"
#include "common/axis.h" #include "common/axis.h"
#include "system.h" #include "system.h"
#include "gpio.h" #include "io.h"
#include "bus_i2c.h" #include "bus_i2c.h"
#include "sensor.h" #include "sensor.h"

View file

@ -22,8 +22,7 @@
*/ */
/* LSM303DLHC ACC struct */ /* LSM303DLHC ACC struct */
typedef struct typedef struct {
{
uint8_t Power_Mode; /* Power-down/Normal Mode */ uint8_t Power_Mode; /* Power-down/Normal Mode */
uint8_t AccOutput_DataRate; /* OUT data rate */ uint8_t AccOutput_DataRate; /* OUT data rate */
uint8_t Axes_Enable; /* Axes enable */ uint8_t Axes_Enable; /* Axes enable */
@ -31,25 +30,23 @@ typedef struct
uint8_t BlockData_Update; /* Block Data Update */ uint8_t BlockData_Update; /* Block Data Update */
uint8_t Endianness; /* Endian Data selection */ uint8_t Endianness; /* Endian Data selection */
uint8_t AccFull_Scale; /* Full Scale selection */ uint8_t AccFull_Scale; /* Full Scale selection */
}LSM303DLHCAcc_InitTypeDef; } LSM303DLHCAcc_InitTypeDef;
/* LSM303DLHC Acc High Pass Filter struct */ /* LSM303DLHC Acc High Pass Filter struct */
typedef struct typedef struct {
{
uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */ uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */
uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */ uint8_t HighPassFilter_CutOff_Frequency; /* High pass filter cut-off frequency */
uint8_t HighPassFilter_AOI1; /* HPF_enabling/disabling for AOI function on interrupt 1 */ uint8_t HighPassFilter_AOI1; /* HPF_enabling/disabling for AOI function on interrupt 1 */
uint8_t HighPassFilter_AOI2; /* HPF_enabling/disabling for AOI function on interrupt 2 */ uint8_t HighPassFilter_AOI2; /* HPF_enabling/disabling for AOI function on interrupt 2 */
}LSM303DLHCAcc_FilterConfigTypeDef; } LSM303DLHCAcc_FilterConfigTypeDef;
/* LSM303DLHC Mag struct */ /* LSM303DLHC Mag struct */
typedef struct typedef struct {
{
uint8_t Temperature_Sensor; /* Temperature sensor enable/disable */ uint8_t Temperature_Sensor; /* Temperature sensor enable/disable */
uint8_t MagOutput_DataRate; /* OUT data rate */ uint8_t MagOutput_DataRate; /* OUT data rate */
uint8_t Working_Mode; /* operating mode */ uint8_t Working_Mode; /* operating mode */
uint8_t MagFull_Scale; /* Full Scale selection */ uint8_t MagFull_Scale; /* Full Scale selection */
}LSM303DLHCMag_InitTypeDef; } LSM303DLHCMag_InitTypeDef;
/** /**
* @} * @}
*/ */
@ -78,43 +75,11 @@ typedef struct
* @brief LSM303DLHC I2C Interface pins * @brief LSM303DLHC I2C Interface pins
*/ */
#define LSM303DLHC_I2C I2C1 #define LSM303DLHC_I2C I2C1
#define LSM303DLHC_I2C_CLK RCC_APB1Periph_I2C1 #define LSM303DLHC_I2C_SCK_PIN PB6 /* PB.06 */
#define LSM303DLHC_I2C_SDA_PIN PB7 /* PB.7 */
#define LSM303DLHC_I2C_SCK_PIN GPIO_Pin_6 /* PB.06 */ #define LSM303DLHC_DRDY_PIN PE2 /* PE.02 */
#define LSM303DLHC_I2C_SCK_GPIO_PORT GPIOB /* GPIOB */ #define LSM303DLHC_I2C_INT1_PIN PE4 /* PE.04 */
#define LSM303DLHC_I2C_SCK_GPIO_CLK RCC_AHBPeriph_GPIOB #define LSM303DLHC_I2C_INT2_PIN PE5 /* PE.05 */
#define LSM303DLHC_I2C_SCK_SOURCE GPIO_PinSource6
#define LSM303DLHC_I2C_SCK_AF GPIO_AF_4
#define LSM303DLHC_I2C_SDA_PIN GPIO_Pin_7 /* PB.7 */
#define LSM303DLHC_I2C_SDA_GPIO_PORT GPIOB /* GPIOB */
#define LSM303DLHC_I2C_SDA_GPIO_CLK RCC_AHBPeriph_GPIOB
#define LSM303DLHC_I2C_SDA_SOURCE GPIO_PinSource7
#define LSM303DLHC_I2C_SDA_AF GPIO_AF_4
#define LSM303DLHC_DRDY_PIN GPIO_Pin_2 /* PE.02 */
#define LSM303DLHC_DRDY_GPIO_PORT GPIOE /* GPIOE */
#define LSM303DLHC_DRDY_GPIO_CLK RCC_AHBPeriph_GPIOE
#define LSM303DLHC_DRDY_EXTI_LINE EXTI_Line2
#define LSM303DLHC_DRDY_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE
#define LSM303DLHC_DRDY_EXTI_PIN_SOURCE EXTI_PinSource2
#define LSM303DLHC_DRDY_EXTI_IRQn EXTI2_TS_IRQn
#define LSM303DLHC_I2C_INT1_PIN GPIO_Pin_4 /* PE.04 */
#define LSM303DLHC_I2C_INT1_GPIO_PORT GPIOE /* GPIOE */
#define LSM303DLHC_I2C_INT1_GPIO_CLK RCC_AHBPeriph_GPIOE
#define LSM303DLHC_I2C_INT1_EXTI_LINE EXTI_Line4
#define LSM303DLHC_I2C_INT1_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE
#define LSM303DLHC_I2C_INT1_EXTI_PIN_SOURCE EXTI_PinSource4
#define LSM303DLHC_I2C_INT1_EXTI_IRQn EXTI4_IRQn
#define LSM303DLHC_I2C_INT2_PIN GPIO_Pin_5 /* PE.05 */
#define LSM303DLHC_I2C_INT2_GPIO_PORT GPIOE /* GPIOE */
#define LSM303DLHC_I2C_INT2_GPIO_CLK RCC_AHBPeriph_GPIOE
#define LSM303DLHC_I2C_INT2_EXTI_LINE EXTI_Line5
#define LSM303DLHC_I2C_INT2_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE
#define LSM303DLHC_I2C_INT2_EXTI_PIN_SOURCE EXTI_PinSource5ss
#define LSM303DLHC_I2C_INT2_EXTI_IRQn EXTI9_5_IRQn
/******************************************************************************/ /******************************************************************************/
/*************************** START REGISTER MAPPING **************************/ /*************************** START REGISTER MAPPING **************************/

View file

@ -105,7 +105,7 @@ static inline void mma8451ConfigureInterrupt(void)
// PA5 - ACC_INT2 output on NAZE rev3/4 hardware // PA5 - ACC_INT2 output on NAZE rev3/4 hardware
// NAZE rev.5 hardware has PA5 (ADC1_IN5) on breakout pad on bottom of board // NAZE rev.5 hardware has PA5 (ADC1_IN5) on breakout pad on bottom of board
// OLIMEXINO - The PA5 pin is wired up to LED1, if you need to use an mma8452 on an Olimexino use a different pin and provide support in code. // OLIMEXINO - The PA5 pin is wired up to LED1, if you need to use an mma8452 on an Olimexino use a different pin and provide support in code.
IOInit(IOGetByTag(IO_TAG(PA5)), OWNER_SYSTEM, RESOURCE_I2C); IOInit(IOGetByTag(IO_TAG(PA5)), OWNER_MPU, RESOURCE_EXTI, 0);
IOConfigGPIO(IOGetByTag(IO_TAG(PA5)), IOCFG_IN_FLOATING); // TODO - maybe pullup / pulldown ? IOConfigGPIO(IOGetByTag(IO_TAG(PA5)), IOCFG_IN_FLOATING); // TODO - maybe pullup / pulldown ?
#endif #endif

View file

@ -32,7 +32,6 @@
#include "gpio.h" #include "gpio.h"
#include "exti.h" #include "exti.h"
#include "bus_i2c.h" #include "bus_i2c.h"
#include "gyro_sync.h"
#include "sensor.h" #include "sensor.h"
#include "accgyro.h" #include "accgyro.h"
@ -245,7 +244,7 @@ void mpuIntExtiInit(void)
} }
#endif #endif
IOInit(mpuIntIO, OWNER_SYSTEM, RESOURCE_INPUT | RESOURCE_EXTI); IOInit(mpuIntIO, OWNER_MPU, RESOURCE_EXTI, 0);
IOConfigGPIO(mpuIntIO, IOCFG_IN_FLOATING); // TODO - maybe pullup / pulldown ? IOConfigGPIO(mpuIntIO, IOCFG_IN_FLOATING); // TODO - maybe pullup / pulldown ?
EXTIHandlerInit(&mpuIntCallbackRec, mpuIntExtiHandler); EXTIHandlerInit(&mpuIntCallbackRec, mpuIntExtiHandler);
@ -300,11 +299,14 @@ bool mpuGyroRead(int16_t *gyroADC)
return true; return true;
} }
void checkMPUDataReady(bool *mpuDataReadyPtr) { bool checkMPUDataReady(void)
{
bool ret;
if (mpuDataReady) { if (mpuDataReady) {
*mpuDataReadyPtr = true; ret = true;
mpuDataReady= false; mpuDataReady= false;
} else { } else {
*mpuDataReadyPtr = false; ret = false;
} }
return ret;
} }

View file

@ -17,6 +17,8 @@
#pragma once #pragma once
#include "exti.h"
// MPU6050 // MPU6050
#define MPU_RA_WHO_AM_I 0x75 #define MPU_RA_WHO_AM_I 0x75
#define MPU_RA_WHO_AM_I_LEGACY 0x00 #define MPU_RA_WHO_AM_I_LEGACY 0x00
@ -185,4 +187,4 @@ void mpuIntExtiInit(void);
bool mpuAccRead(int16_t *accData); bool mpuAccRead(int16_t *accData);
bool mpuGyroRead(int16_t *gyroADC); bool mpuGyroRead(int16_t *gyroADC);
mpuDetectionResult_t *detectMpu(const extiConfig_t *configToUse); mpuDetectionResult_t *detectMpu(const extiConfig_t *configToUse);
void checkMPUDataReady(bool *mpuDataReadyPtr); bool checkMPUDataReady(void);

View file

@ -30,7 +30,6 @@
#include "accgyro.h" #include "accgyro.h"
#include "accgyro_mpu.h" #include "accgyro_mpu.h"
#include "accgyro_mpu3050.h" #include "accgyro_mpu3050.h"
#include "gyro_sync.h"
// MPU3050, Standard address 0x68 // MPU3050, Standard address 0x68
#define MPU3050_ADDRESS 0x68 #define MPU3050_ADDRESS 0x68

View file

@ -1,4 +1,4 @@
/* /*
* This file is part of Cleanflight. * This file is part of Cleanflight.
* *
* Cleanflight is free software: you can redistribute it and/or modify * Cleanflight is free software: you can redistribute it and/or modify
@ -38,8 +38,6 @@
#include "accgyro_mpu.h" #include "accgyro_mpu.h"
#include "accgyro_mpu6050.h" #include "accgyro_mpu6050.h"
extern uint8_t mpuLowPassFilter;
//#define DEBUG_MPU_DATA_READY_INTERRUPT //#define DEBUG_MPU_DATA_READY_INTERRUPT
// MPU6050, Standard address 0x68 // MPU6050, Standard address 0x68

View file

@ -20,7 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "platform.h" #include "platform.h"
#include "build_config.h"
#include "common/axis.h" #include "common/axis.h"
#include "common/maths.h" #include "common/maths.h"

View file

@ -24,7 +24,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
@ -41,6 +40,9 @@
#include "sensor.h" #include "sensor.h"
#include "accgyro.h" #include "accgyro.h"
#include "accgyro_mpu.h" #include "accgyro_mpu.h"
#if defined(USE_GYRO_SPI_MPU6000) || defined(USE_ACC_SPI_MPU6000)
#include "accgyro_spi_mpu6000.h" #include "accgyro_spi_mpu6000.h"
static void mpu6000AccAndGyroInit(void); static void mpu6000AccAndGyroInit(void);
@ -159,7 +161,7 @@ bool mpu6000SpiDetect(void)
#ifdef MPU6000_CS_PIN #ifdef MPU6000_CS_PIN
mpuSpi6000CsPin = IOGetByTag(IO_TAG(MPU6000_CS_PIN)); mpuSpi6000CsPin = IOGetByTag(IO_TAG(MPU6000_CS_PIN));
#endif #endif
IOInit(mpuSpi6000CsPin, OWNER_SYSTEM, RESOURCE_SPI); IOInit(mpuSpi6000CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
IOConfigGPIO(mpuSpi6000CsPin, SPI_IO_CS_CFG); IOConfigGPIO(mpuSpi6000CsPin, SPI_IO_CS_CFG);
spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON);
@ -283,3 +285,5 @@ bool mpu6000SpiGyroDetect(gyro_t *gyro)
return true; return true;
} }
#endif

View file

@ -17,7 +17,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
@ -69,7 +68,7 @@ static void mpu6500SpiInit(void)
} }
mpuSpi6500CsPin = IOGetByTag(IO_TAG(MPU6500_CS_PIN)); mpuSpi6500CsPin = IOGetByTag(IO_TAG(MPU6500_CS_PIN));
IOInit(mpuSpi6500CsPin, OWNER_SYSTEM, RESOURCE_SPI); IOInit(mpuSpi6500CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
IOConfigGPIO(mpuSpi6500CsPin, SPI_IO_CS_CFG); IOConfigGPIO(mpuSpi6500CsPin, SPI_IO_CS_CFG);
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST); spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST);

View file

@ -25,7 +25,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
#include "light_led.h" #include "light_led.h"
@ -191,7 +190,7 @@ bool mpu9250SpiDetect(void)
#ifdef MPU9250_CS_PIN #ifdef MPU9250_CS_PIN
mpuSpi9250CsPin = IOGetByTag(IO_TAG(MPU9250_CS_PIN)); mpuSpi9250CsPin = IOGetByTag(IO_TAG(MPU9250_CS_PIN));
#endif #endif
IOInit(mpuSpi9250CsPin, OWNER_SYSTEM, RESOURCE_SPI); IOInit(mpuSpi9250CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
IOConfigGPIO(mpuSpi9250CsPin, SPI_IO_CS_CFG); IOConfigGPIO(mpuSpi9250CsPin, SPI_IO_CS_CFG);
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); //low speed spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); //low speed

View file

@ -17,6 +17,8 @@
#pragma once #pragma once
#include "io.h"
typedef enum { typedef enum {
ADC_BATTERY = 0, ADC_BATTERY = 0,
ADC_RSSI = 1, ADC_RSSI = 1,
@ -28,6 +30,7 @@ typedef enum {
#define ADC_CHANNEL_COUNT (ADC_CHANNEL_MAX + 1) #define ADC_CHANNEL_COUNT (ADC_CHANNEL_MAX + 1)
typedef struct adc_config_s { typedef struct adc_config_s {
ioTag_t tag;
uint8_t adcChannel; // ADC1_INxx channel number uint8_t adcChannel; // ADC1_INxx channel number
uint8_t dmaIndex; // index into DMA buffer in case of sparse channels uint8_t dmaIndex; // index into DMA buffer in case of sparse channels
bool enabled; bool enabled;

View file

@ -91,45 +91,25 @@ void adcInit(drv_adc_config_t *init)
#ifdef VBAT_ADC_PIN #ifdef VBAT_ADC_PIN
if (init->enableVBat) { if (init->enableVBat) {
IOInit(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_BATTERY].tag = IO_TAG(VBAT_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), IO_CONFIG(GPIO_Mode_AIN, 0));
adcConfig[ADC_BATTERY].adcChannel = adcChannelByTag(IO_TAG(VBAT_ADC_PIN));
adcConfig[ADC_BATTERY].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_BATTERY].enabled = true;
adcConfig[ADC_BATTERY].sampleTime = ADC_SampleTime_239Cycles5;
} }
#endif #endif
#ifdef RSSI_ADC_PIN #ifdef RSSI_ADC_PIN
if (init->enableRSSI) { if (init->enableRSSI) {
IOInit(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_RSSI].tag = IO_TAG(RSSI_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), IO_CONFIG(GPIO_Mode_AIN, 0));
adcConfig[ADC_RSSI].adcChannel = adcChannelByTag(IO_TAG(RSSI_ADC_PIN));
adcConfig[ADC_RSSI].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_RSSI].enabled = true;
adcConfig[ADC_RSSI].sampleTime = ADC_SampleTime_239Cycles5;
} }
#endif #endif
#ifdef EXTERNAL1_ADC_PIN #ifdef EXTERNAL1_ADC_PIN
if (init->enableExternal1) { if (init->enableExternal1) {
IOInit(IOGetByTag(IO_TAG(EXTERNAL1_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_EXTERNAL1].tag = IO_TAG(EXTERNAL1_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(EXTERNAL1_ADC_PIN)), IO_CONFIG(GPIO_Mode_AIN, 0));
adcConfig[ADC_EXTERNAL1].adcChannel = adcChannelByTag(IO_TAG(EXTERNAL1_ADC_PIN));
adcConfig[ADC_EXTERNAL1].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_EXTERNAL1].enabled = true;
adcConfig[ADC_EXTERNAL1].sampleTime = ADC_SampleTime_239Cycles5;
} }
#endif #endif
#ifdef CURRENT_METER_ADC_PIN #ifdef CURRENT_METER_ADC_PIN
if (init->enableCurrentMeter) { if (init->enableCurrentMeter) {
IOInit(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_CURRENT].tag = IO_TAG(CURRENT_METER_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), IO_CONFIG(GPIO_Mode_AIN, 0));
adcConfig[ADC_CURRENT].adcChannel = adcChannelByTag(IO_TAG(CURRENT_METER_ADC_PIN));
adcConfig[ADC_CURRENT].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_CURRENT].enabled = true;
adcConfig[ADC_CURRENT].sampleTime = ADC_SampleTime_239Cycles5;
} }
#endif #endif
@ -139,12 +119,22 @@ void adcInit(drv_adc_config_t *init)
adcDevice_t adc = adcHardware[device]; adcDevice_t adc = adcHardware[device];
for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) {
if (!adcConfig[i].tag)
continue;
IOInit(IOGetByTag(adcConfig[i].tag), OWNER_ADC, RESOURCE_ADC_BATTERY+i, 0);
IOConfigGPIO(IOGetByTag(adcConfig[i].tag), IO_CONFIG(GPIO_Mode_AIN, 0));
adcConfig[i].adcChannel = adcChannelByTag(adcConfig[i].tag);
adcConfig[i].dmaIndex = configuredAdcChannels++;
adcConfig[i].sampleTime = ADC_SampleTime_239Cycles5;
adcConfig[i].enabled = true;
}
RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 9MHz from 72MHz APB2 clock(HSE), 8MHz from 64MHz (HSI) RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 9MHz from 72MHz APB2 clock(HSE), 8MHz from 64MHz (HSI)
RCC_ClockCmd(adc.rccADC, ENABLE); RCC_ClockCmd(adc.rccADC, ENABLE);
RCC_ClockCmd(adc.rccDMA, ENABLE); RCC_ClockCmd(adc.rccDMA, ENABLE);
// FIXME ADC driver assumes all the GPIO was already placed in 'AIN' mode
DMA_DeInit(adc.DMAy_Channelx); DMA_DeInit(adc.DMAy_Channelx);
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit(&DMA_InitStructure); DMA_StructInit(&DMA_InitStructure);

View file

@ -107,53 +107,25 @@ void adcInit(drv_adc_config_t *init)
#ifdef VBAT_ADC_PIN #ifdef VBAT_ADC_PIN
if (init->enableVBat) { if (init->enableVBat) {
IOInit(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_BATTERY].tag = IO_TAG(VBAT_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_BATTERY].adcChannel = adcChannelByTag(IO_TAG(VBAT_ADC_PIN));
adcConfig[ADC_BATTERY].dmaIndex = adcChannelCount;
adcConfig[ADC_BATTERY].sampleTime = ADC_SampleTime_601Cycles5;
adcConfig[ADC_BATTERY].enabled = true;
adcChannelCount++;
} }
#endif #endif
#ifdef RSSI_ADC_PIN #ifdef RSSI_ADC_PIN
if (init->enableRSSI) { if (init->enableRSSI) {
IOInit(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_RSSI].tag = IO_TAG(RSSI_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_RSSI].adcChannel = adcChannelByTag(IO_TAG(RSSI_ADC_PIN));
adcConfig[ADC_RSSI].dmaIndex = adcChannelCount;
adcConfig[ADC_RSSI].sampleTime = ADC_SampleTime_601Cycles5;
adcConfig[ADC_RSSI].enabled = true;
adcChannelCount++;
} }
#endif #endif
#ifdef CURRENT_METER_ADC_GPIO #ifdef CURRENT_METER_ADC_PIN
if (init->enableCurrentMeter) { if (init->enableCurrentMeter) {
IOInit(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_CURRENT].tag = IO_TAG(CURRENT_METER_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_CURRENT].adcChannel = adcChannelByTag(IO_TAG(CURRENT_METER_ADC_PIN));
adcConfig[ADC_CURRENT].dmaIndex = adcChannelCount;
adcConfig[ADC_CURRENT].sampleTime = ADC_SampleTime_601Cycles5;
adcConfig[ADC_CURRENT].enabled = true;
adcChannelCount++;
} }
#endif #endif
#ifdef EXTERNAL1_ADC_GPIO #ifdef EXTERNAL1_ADC_PIN
if (init->enableExternal1) { if (init->enableExternal1) {
IOInit(IOGetByTag(IO_TAG(EXTERNAL1_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_EXTERNAL1].tag = IO_TAG(EXTERNAL1_ADC_PIN);
IOConfigGPIO(IOGetByTag(IO_TAG(EXTERNAL1_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_EXTERNAL1].adcChannel = adcChannelByTag(IO_TAG(EXTERNAL1_ADC_PIN));
adcConfig[ADC_EXTERNAL1].dmaIndex = adcChannelCount;
adcConfig[ADC_EXTERNAL1].sampleTime = ADC_SampleTime_601Cycles5;
adcConfig[ADC_EXTERNAL1].enabled = true;
adcChannelCount++;
} }
#endif #endif
@ -163,6 +135,18 @@ void adcInit(drv_adc_config_t *init)
adcDevice_t adc = adcHardware[device]; adcDevice_t adc = adcHardware[device];
for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) {
if (!adcConfig[i].tag)
continue;
IOInit(IOGetByTag(adcConfig[i].tag), OWNER_ADC, RESOURCE_ADC_BATTERY+i,0);
IOConfigGPIO(IOGetByTag(adcConfig[i].tag), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[i].adcChannel = adcChannelByTag(adcConfig[i].tag);
adcConfig[i].dmaIndex = adcChannelCount++;
adcConfig[i].sampleTime = ADC_SampleTime_601Cycles5;
adcConfig[i].enabled = true;
}
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div256); // 72 MHz divided by 256 = 281.25 kHz RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div256); // 72 MHz divided by 256 = 281.25 kHz
RCC_ClockCmd(adc.rccADC, ENABLE); RCC_ClockCmd(adc.rccADC, ENABLE);
RCC_ClockCmd(adc.rccDMA, ENABLE); RCC_ClockCmd(adc.rccDMA, ENABLE);

View file

@ -100,45 +100,25 @@ void adcInit(drv_adc_config_t *init)
#ifdef VBAT_ADC_PIN #ifdef VBAT_ADC_PIN
if (init->enableVBat) { if (init->enableVBat) {
IOInit(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_BATTERY].tag = IO_TAG(VBAT_ADC_PIN); //VBAT_ADC_CHANNEL;
IOConfigGPIO(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_BATTERY].adcChannel = adcChannelByTag(IO_TAG(VBAT_ADC_PIN)); //VBAT_ADC_CHANNEL;
adcConfig[ADC_BATTERY].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_BATTERY].enabled = true;
adcConfig[ADC_BATTERY].sampleTime = ADC_SampleTime_480Cycles;
}
#endif
#ifdef EXTERNAL1_ADC_PIN
if (init->enableExternal1) {
IOInit(IOGetByTag(IO_TAG(EXTERNAL1_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
IOConfigGPIO(IOGetByTag(IO_TAG(EXTERNAL1_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_EXTERNAL1].adcChannel = adcChannelByTag(IO_TAG(EXTERNAL1_ADC_PIN)); //EXTERNAL1_ADC_CHANNEL;
adcConfig[ADC_EXTERNAL1].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_EXTERNAL1].enabled = true;
adcConfig[ADC_EXTERNAL1].sampleTime = ADC_SampleTime_480Cycles;
} }
#endif #endif
#ifdef RSSI_ADC_PIN #ifdef RSSI_ADC_PIN
if (init->enableRSSI) { if (init->enableRSSI) {
IOInit(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_RSSI].tag = IO_TAG(RSSI_ADC_PIN); //RSSI_ADC_CHANNEL;
IOConfigGPIO(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL)); }
adcConfig[ADC_RSSI].adcChannel = adcChannelByTag(IO_TAG(RSSI_ADC_PIN)); //RSSI_ADC_CHANNEL; #endif
adcConfig[ADC_RSSI].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_RSSI].enabled = true; #ifdef EXTERNAL1_ADC_PIN
adcConfig[ADC_RSSI].sampleTime = ADC_SampleTime_480Cycles; if (init->enableExternal1) {
adcConfig[ADC_EXTERNAL1].tag = IO_TAG(EXTERNAL1_ADC_PIN); //EXTERNAL1_ADC_CHANNEL;
} }
#endif #endif
#ifdef CURRENT_METER_ADC_PIN #ifdef CURRENT_METER_ADC_PIN
if (init->enableCurrentMeter) { if (init->enableCurrentMeter) {
IOInit(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC); adcConfig[ADC_CURRENT].tag = IO_TAG(CURRENT_METER_ADC_PIN); //CURRENT_METER_ADC_CHANNEL;
IOConfigGPIO(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[ADC_CURRENT].adcChannel = adcChannelByTag(IO_TAG(CURRENT_METER_ADC_PIN)); //CURRENT_METER_ADC_CHANNEL;
adcConfig[ADC_CURRENT].dmaIndex = configuredAdcChannels++;
adcConfig[ADC_CURRENT].enabled = true;
adcConfig[ADC_CURRENT].sampleTime = ADC_SampleTime_480Cycles;
} }
#endif #endif
@ -150,6 +130,18 @@ void adcInit(drv_adc_config_t *init)
adcDevice_t adc = adcHardware[device]; adcDevice_t adc = adcHardware[device];
for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) {
if (!adcConfig[i].tag)
continue;
IOInit(IOGetByTag(adcConfig[i].tag), OWNER_ADC, RESOURCE_ADC_BATTERY + i, 0);
IOConfigGPIO(IOGetByTag(adcConfig[i].tag), IO_CONFIG(GPIO_Mode_AN, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL));
adcConfig[i].adcChannel = adcChannelByTag(adcConfig[i].tag);
adcConfig[i].dmaIndex = configuredAdcChannels++;
adcConfig[i].sampleTime = ADC_SampleTime_480Cycles;
adcConfig[i].enabled = true;
}
RCC_ClockCmd(adc.rccDMA, ENABLE); RCC_ClockCmd(adc.rccDMA, ENABLE);
RCC_ClockCmd(adc.rccADC, ENABLE); RCC_ClockCmd(adc.rccADC, ENABLE);

View file

@ -143,7 +143,7 @@ void bmp085InitXclrIO(const bmp085Config_t *config)
{ {
if (!xclrIO && config && config->xclrIO) { if (!xclrIO && config && config->xclrIO) {
xclrIO = IOGetByTag(config->xclrIO); xclrIO = IOGetByTag(config->xclrIO);
IOInit(xclrIO, OWNER_SYSTEM, RESOURCE_OUTPUT); IOInit(xclrIO, OWNER_BARO, RESOURCE_OUTPUT, 0);
IOConfigGPIO(xclrIO, IOCFG_OUT_PP); IOConfigGPIO(xclrIO, IOCFG_OUT_PP);
} }
} }

View file

@ -17,17 +17,15 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <platform.h> #include <platform.h>
#include "build_config.h"
#include "bus_spi.h" #include "bus_spi.h"
#include "barometer.h" #include "barometer.h"
#include "barometer_bmp280.h" #include "barometer_bmp280.h"
#ifdef USE_BARO_SPI_BMP280
#define DISABLE_BMP280 IOHi(bmp280CsPin) #define DISABLE_BMP280 IOHi(bmp280CsPin)
#define ENABLE_BMP280 IOLo(bmp280CsPin) #define ENABLE_BMP280 IOLo(bmp280CsPin)
@ -65,7 +63,7 @@ void bmp280SpiInit(void)
} }
bmp280CsPin = IOGetByTag(IO_TAG(BMP280_CS_PIN)); bmp280CsPin = IOGetByTag(IO_TAG(BMP280_CS_PIN));
IOInit(bmp280CsPin, OWNER_BARO, RESOURCE_SPI); IOInit(bmp280CsPin, OWNER_BARO, RESOURCE_SPI_CS, 0);
IOConfigGPIO(bmp280CsPin, IOCFG_OUT_PP); IOConfigGPIO(bmp280CsPin, IOCFG_OUT_PP);
DISABLE_BMP280; DISABLE_BMP280;
@ -91,3 +89,4 @@ void bmp280_spi_get_up(void)
bmp280_up = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4)); bmp280_up = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
bmp280_ut = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4)); bmp280_ut = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
} }
#endif

View file

@ -21,8 +21,6 @@
#include <platform.h> #include <platform.h>
#include "build_config.h"
#include "io.h" #include "io.h"
#include "system.h" #include "system.h"
@ -385,8 +383,8 @@ void i2cInit(I2CDevice device)
IO_t scl = IOGetByTag(i2c->scl); IO_t scl = IOGetByTag(i2c->scl);
IO_t sda = IOGetByTag(i2c->sda); IO_t sda = IOGetByTag(i2c->sda);
IOInit(scl, OWNER_SYSTEM, RESOURCE_I2C); IOInit(scl, OWNER_I2C, RESOURCE_I2C_SCL, RESOURCE_INDEX(device));
IOInit(sda, OWNER_SYSTEM, RESOURCE_I2C); IOInit(sda, OWNER_I2C, RESOURCE_I2C_SDA, RESOURCE_INDEX(device));
// Enable RCC // Enable RCC
RCC_ClockCmd(i2c->rcc, ENABLE); RCC_ClockCmd(i2c->rcc, ENABLE);
@ -423,6 +421,9 @@ void i2cInit(I2CDevice device)
I2C_Cmd(i2c->dev, ENABLE); I2C_Cmd(i2c->dev, ENABLE);
I2C_Init(i2c->dev, &i2cInit); I2C_Init(i2c->dev, &i2cInit);
I2C_StretchClockCmd(i2c->dev, ENABLE);
// I2C ER Interrupt // I2C ER Interrupt
nvic.NVIC_IRQChannel = i2c->er_irq; nvic.NVIC_IRQChannel = i2c->er_irq;
nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER); nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER);

View file

@ -17,12 +17,9 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <platform.h> #include <platform.h>
#include "build_config.h"
#include "gpio.h" #include "gpio.h"
#include "system.h" #include "system.h"
#include "drivers/io_impl.h" #include "drivers/io_impl.h"
@ -31,6 +28,15 @@
#ifndef SOFT_I2C #ifndef SOFT_I2C
#if defined(USE_I2C_PULLUP)
#define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_OD, GPIO_PuPd_UP)
#else
#define IOCFG_I2C IOCFG_AF_OD
#endif
#define I2C_HIGHSPEED_TIMING 0x00500E30 // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
#define I2C_STANDARD_TIMING 0x00E0257A // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10.
#define I2C_SHORT_TIMEOUT ((uint32_t)0x1000) #define I2C_SHORT_TIMEOUT ((uint32_t)0x1000)
#define I2C_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT)) #define I2C_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT))
#define I2C_GPIO_AF GPIO_AF_4 #define I2C_GPIO_AF GPIO_AF_4
@ -83,8 +89,11 @@ void i2cInit(I2CDevice device)
RCC_ClockCmd(i2c->rcc, ENABLE); RCC_ClockCmd(i2c->rcc, ENABLE);
RCC_I2CCLKConfig(I2Cx == I2C2 ? RCC_I2C2CLK_SYSCLK : RCC_I2C1CLK_SYSCLK); RCC_I2CCLKConfig(I2Cx == I2C2 ? RCC_I2C2CLK_SYSCLK : RCC_I2C1CLK_SYSCLK);
IOConfigGPIOAF(scl, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4); IOInit(scl, OWNER_I2C, RESOURCE_I2C_SCL, RESOURCE_INDEX(device));
IOConfigGPIOAF(sda, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4); IOConfigGPIOAF(scl, IOCFG_I2C, GPIO_AF_4);
IOInit(sda, OWNER_I2C, RESOURCE_I2C_SDA, RESOURCE_INDEX(device));
IOConfigGPIOAF(sda, IOCFG_I2C, GPIO_AF_4);
I2C_InitTypeDef i2cInit = { I2C_InitTypeDef i2cInit = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
@ -93,14 +102,13 @@ void i2cInit(I2CDevice device)
.I2C_OwnAddress1 = 0x00, .I2C_OwnAddress1 = 0x00,
.I2C_Ack = I2C_Ack_Enable, .I2C_Ack = I2C_Ack_Enable,
.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit, .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
.I2C_Timing = i2c->overClock ? .I2C_Timing = (i2c->overClock ? I2C_HIGHSPEED_TIMING : I2C_STANDARD_TIMING)
0x00500E30 : // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
0x00E0257A, // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10.
//.I2C_Timing = 0x8000050B;
}; };
I2C_Init(I2Cx, &i2cInit); I2C_Init(I2Cx, &i2cInit);
I2C_StretchClockCmd(I2Cx, ENABLE);
I2C_Cmd(I2Cx, ENABLE); I2C_Cmd(I2Cx, ENABLE);
} }

View file

@ -20,8 +20,6 @@
#include <platform.h> #include <platform.h>
#include "build_config.h"
#include "bus_spi.h" #include "bus_spi.h"
#include "io.h" #include "io.h"
#include "io_impl.h" #include "io_impl.h"
@ -113,28 +111,22 @@ void spiInitDevice(SPIDevice device)
RCC_ClockCmd(spi->rcc, ENABLE); RCC_ClockCmd(spi->rcc, ENABLE);
RCC_ResetCmd(spi->rcc, ENABLE); RCC_ResetCmd(spi->rcc, ENABLE);
IOInit(IOGetByTag(spi->sck), OWNER_SYSTEM, RESOURCE_SPI); IOInit(IOGetByTag(spi->sck), OWNER_SPI, RESOURCE_SPI_SCK, device + 1);
IOInit(IOGetByTag(spi->miso), OWNER_SYSTEM, RESOURCE_SPI); IOInit(IOGetByTag(spi->miso), OWNER_SPI, RESOURCE_SPI_MISO, device + 1);
IOInit(IOGetByTag(spi->mosi), OWNER_SYSTEM, RESOURCE_SPI); IOInit(IOGetByTag(spi->mosi), OWNER_SPI, RESOURCE_SPI_MOSI, device + 1);
#if defined(STM32F303xC) || defined(STM32F4) #if defined(STM32F3) || defined(STM32F4)
if (spi->sdcard) {
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->af);
}
else {
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af); IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_CFG, spi->af); IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_CFG, spi->af);
}
IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af); IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af);
if (spi->nss) if (spi->nss)
IOConfigGPIOAF(IOGetByTag(spi->nss), SPI_IO_CS_CFG, spi->af); IOConfigGPIOAF(IOGetByTag(spi->nss), SPI_IO_CS_CFG, spi->af);
#endif #endif
#if defined(STM32F10X) #if defined(STM32F10X)
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_CFG); IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_CFG); IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_CFG); IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_CFG);
if (spi->nss) if (spi->nss)
IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG); IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);

View file

@ -27,8 +27,10 @@
#define SPI_IO_AF_MISO_CFG IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP) #define SPI_IO_AF_MISO_CFG IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP)
#define SPI_IO_CS_CFG IO_CONFIG(GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL) #define SPI_IO_CS_CFG IO_CONFIG(GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
#elif defined(STM32F1) #elif defined(STM32F1)
#define SPI_IO_AF_CFG IO_CONFIG(GPIO_Mode_AF_OD, GPIO_Speed_50MHz) #define SPI_IO_AF_SCK_CFG IO_CONFIG(GPIO_Mode_AF_PP, GPIO_Speed_50MHz)
#define SPI_IO_CS_CFG IO_CONFIG(GPIO_Mode_Out_OD, GPIO_Speed_50MHz) #define SPI_IO_AF_MOSI_CFG IO_CONFIG(GPIO_Mode_AF_PP, GPIO_Speed_50MHz)
#define SPI_IO_AF_MISO_CFG IO_CONFIG(GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz)
#define SPI_IO_CS_CFG IO_CONFIG(GPIO_Mode_Out_PP, GPIO_Speed_50MHz)
#else #else
#error "Unknown processor" #error "Unknown processor"
#endif #endif

View file

@ -30,8 +30,6 @@
#include "common/maths.h" #include "common/maths.h"
#include "system.h" #include "system.h"
#include "gpio.h"
#include "exti.h"
#include "bus_i2c.h" #include "bus_i2c.h"
#include "bus_spi.h" #include "bus_spi.h"

View file

@ -17,7 +17,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <math.h> #include <math.h>
@ -29,7 +28,8 @@
#include "system.h" #include "system.h"
#include "nvic.h" #include "nvic.h"
#include "gpio.h" #include "io.h"
#include "exti.h"
#include "bus_i2c.h" #include "bus_i2c.h"
#include "light_led.h" #include "light_led.h"
@ -120,14 +120,14 @@ static float magGain[3] = { 1.0f, 1.0f, 1.0f };
static const hmc5883Config_t *hmc5883Config = NULL; static const hmc5883Config_t *hmc5883Config = NULL;
void MAG_DATA_READY_EXTI_Handler(void) #ifdef USE_MAG_DATA_READY_SIGNAL
static IO_t intIO;
static extiCallbackRec_t hmc5883_extiCallbackRec;
void hmc5883_extiHandler(extiCallbackRec_t* cb)
{ {
if (EXTI_GetITStatus(hmc5883Config->exti_line) == RESET) { UNUSED(cb);
return;
}
EXTI_ClearITPendingBit(hmc5883Config->exti_line);
#ifdef DEBUG_MAG_DATA_READY_INTERRUPT #ifdef DEBUG_MAG_DATA_READY_INTERRUPT
// Measure the delta between calls to the interrupt handler // Measure the delta between calls to the interrupt handler
// currently should be around 65/66 milli seconds / 15hz output rate // currently should be around 65/66 milli seconds / 15hz output rate
@ -143,57 +143,26 @@ void MAG_DATA_READY_EXTI_Handler(void)
lastCalledAt = now; lastCalledAt = now;
#endif #endif
} }
#endif
static void hmc5883lConfigureDataReadyInterruptHandling(void) static void hmc5883lConfigureDataReadyInterruptHandling(void)
{ {
#ifdef USE_MAG_DATA_READY_SIGNAL #ifdef USE_MAG_DATA_READY_SIGNAL
if (!(hmc5883Config->exti_port_source && hmc5883Config->exti_pin_source)) { if (!(hmc5883Config->intTag)) {
return; return;
} }
#ifdef STM32F10X intIO = IOGetByTag(hmc5883Config->intTag);
// enable AFIO for EXTI support
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
#endif
#ifdef STM32F303xC
/* Enable SYSCFG clock otherwise the EXTI irq handlers are not called */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
#endif
#ifdef STM32F10X
gpioExtiLineConfig(hmc5883Config->exti_port_source, hmc5883Config->exti_pin_source);
#endif
#ifdef STM32F303xC
gpioExtiLineConfig(hmc5883Config->exti_port_source, hmc5883Config->exti_pin_source);
#endif
#ifdef ENSURE_MAG_DATA_READY_IS_HIGH #ifdef ENSURE_MAG_DATA_READY_IS_HIGH
uint8_t status = GPIO_ReadInputDataBit(hmc5883Config->gpioPort, hmc5883Config->gpioPin); uint8_t status = IORead(intIO);
if (!status) { if (!status) {
return; return;
} }
#endif #endif
registerExtiCallbackHandler(hmc5883Config->exti_irqn, MAG_DATA_READY_EXTI_Handler); EXTIHandlerInit(&hmc5883_extiCallbackRec, hmc5883_extiHandler);
EXTIConfig(intIO, &hmc5883_extiCallbackRec, NVIC_PRIO_MAG_INT_EXTI, EXTI_Trigger_Rising);
EXTI_ClearITPendingBit(hmc5883Config->exti_line); EXTIEnable(intIO, true);
EXTI_InitTypeDef EXTIInit;
EXTIInit.EXTI_Line = hmc5883Config->exti_line;
EXTIInit.EXTI_Mode = EXTI_Mode_Interrupt;
EXTIInit.EXTI_Trigger = EXTI_Trigger_Falling;
EXTIInit.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTIInit);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = hmc5883Config->exti_irqn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_MAG_DATA_READY);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_MAG_DATA_READY);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif #endif
} }
@ -221,25 +190,6 @@ void hmc5883lInit(void)
int32_t xyz_total[3] = { 0, 0, 0 }; // 32 bit totals so they won't overflow. int32_t xyz_total[3] = { 0, 0, 0 }; // 32 bit totals so they won't overflow.
bool bret = true; // Error indicator bool bret = true; // Error indicator
gpio_config_t gpio;
if (hmc5883Config) {
#ifdef STM32F303
if (hmc5883Config->gpioAHBPeripherals) {
RCC_AHBPeriphClockCmd(hmc5883Config->gpioAHBPeripherals, ENABLE);
}
#endif
#ifdef STM32F10X
if (hmc5883Config->gpioAPB2Peripherals) {
RCC_APB2PeriphClockCmd(hmc5883Config->gpioAPB2Peripherals, ENABLE);
}
#endif
gpio.pin = hmc5883Config->gpioPin;
gpio.speed = Speed_2MHz;
gpio.mode = Mode_IN_FLOATING;
gpioInit(hmc5883Config->gpioPort, &gpio);
}
delay(50); delay(50);
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x010 + HMC_POS_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to pos bias i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x010 + HMC_POS_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to pos bias
// Note that the very first measurement after a gain change maintains the same gain as the previous setting. // Note that the very first measurement after a gain change maintains the same gain as the previous setting.

View file

@ -17,20 +17,10 @@
#pragma once #pragma once
typedef struct hmc5883Config_s { #include "io.h"
#ifdef STM32F303
uint32_t gpioAHBPeripherals;
#endif
#ifdef STM32F10X
uint32_t gpioAPB2Peripherals;
#endif
uint16_t gpioPin;
GPIO_TypeDef *gpioPort;
uint8_t exti_port_source; typedef struct hmc5883Config_s {
uint32_t exti_line; ioTag_t intTag;
uint8_t exti_pin_source;
IRQn_Type exti_irqn;
} hmc5883Config_t; } hmc5883Config_t;
bool hmc5883lDetect(mag_t* mag, const hmc5883Config_t *hmc5883ConfigToUse); bool hmc5883lDetect(mag_t* mag, const hmc5883Config_t *hmc5883ConfigToUse);

View file

@ -17,7 +17,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"

View file

@ -21,63 +21,66 @@
#include <platform.h> #include <platform.h>
#include "build_config.h" #include "drivers/nvic.h"
#include "drivers/dma.h" #include "drivers/dma.h"
/* /*
* DMA handlers for DMA resources that are shared between different features depending on run-time configuration. * DMA descriptors.
*/ */
static dmaHandlers_t dmaHandlers; static dmaChannelDescriptor_t dmaDescriptors[] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel1, 0, DMA1_Channel1_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel2, 4, DMA1_Channel2_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel3, 8, DMA1_Channel3_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel4, 12, DMA1_Channel4_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel5, 16, DMA1_Channel5_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel6, 20, DMA1_Channel6_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel7, 24, DMA1_Channel7_IRQn, RCC_AHBPeriph_DMA1),
#if defined(STM32F3) || defined(STM32F10X_CL)
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel1, 0, DMA2_Channel1_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel2, 4, DMA2_Channel2_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel3, 8, DMA2_Channel3_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel4, 12, DMA2_Channel4_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel5, 16, DMA2_Channel5_IRQn, RCC_AHBPeriph_DMA2),
#endif
};
void dmaNoOpHandler(DMA_Channel_TypeDef *channel) /*
{ * DMA IRQ Handlers
UNUSED(channel); */
} DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_CH1_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_CH2_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_CH3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_CH5_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_CH6_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_CH7_HANDLER)
void DMA1_Channel2_IRQHandler(void) #if defined(STM32F3) || defined(STM32F10X_CL)
{ DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER)
dmaHandlers.dma1Channel2IRQHandler(DMA1_Channel2); DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_CH2_HANDLER)
} DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_CH3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER)
#endif
void DMA1_Channel3_IRQHandler(void)
{
dmaHandlers.dma1Channel3IRQHandler(DMA1_Channel3);
}
void DMA1_Channel6_IRQHandler(void)
{
dmaHandlers.dma1Channel6IRQHandler(DMA1_Channel6);
}
void DMA1_Channel7_IRQHandler(void)
{
dmaHandlers.dma1Channel7IRQHandler(DMA1_Channel7);
}
void dmaInit(void) void dmaInit(void)
{ {
memset(&dmaHandlers, 0, sizeof(dmaHandlers)); // TODO: Do we need this?
dmaHandlers.dma1Channel2IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Channel3IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Channel6IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Channel7IRQHandler = dmaNoOpHandler;
} }
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback) void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{ {
switch (identifier) { NVIC_InitTypeDef NVIC_InitStructure;
case DMA1_CH2_HANDLER:
dmaHandlers.dma1Channel2IRQHandler = callback; RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
break; dmaDescriptors[identifier].irqHandlerCallback = callback;
case DMA1_CH3_HANDLER: dmaDescriptors[identifier].userParam = userParam;
dmaHandlers.dma1Channel3IRQHandler = callback;
break; NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN;
case DMA1_CH6_HANDLER: NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
dmaHandlers.dma1Channel6IRQHandler = callback; NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
break; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
case DMA1_CH7_HANDLER: NVIC_Init(&NVIC_InitStructure);
dmaHandlers.dma1Channel7IRQHandler = callback;
break;
}
} }

View file

@ -15,37 +15,97 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
struct dmaChannelDescriptor_s;
typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor);
#ifdef STM32F4 #ifdef STM32F4
typedef void(*dmaCallbackHandlerFuncPtr)(DMA_Stream_TypeDef *stream);
typedef enum { typedef enum {
DMA1_ST2_HANDLER = 0, DMA1_ST1_HANDLER = 0,
DMA1_ST2_HANDLER,
DMA1_ST3_HANDLER,
DMA1_ST4_HANDLER,
DMA1_ST5_HANDLER,
DMA1_ST6_HANDLER,
DMA1_ST7_HANDLER, DMA1_ST7_HANDLER,
DMA2_ST1_HANDLER,
DMA2_ST2_HANDLER,
DMA2_ST3_HANDLER,
DMA2_ST4_HANDLER,
DMA2_ST5_HANDLER,
DMA2_ST6_HANDLER,
DMA2_ST7_HANDLER,
} dmaHandlerIdentifier_e; } dmaHandlerIdentifier_e;
typedef struct dmaHandlers_s { typedef struct dmaChannelDescriptor_s {
dmaCallbackHandlerFuncPtr dma1Stream2IRQHandler; DMA_TypeDef* dma;
dmaCallbackHandlerFuncPtr dma1Stream7IRQHandler; DMA_Stream_TypeDef* stream;
} dmaHandlers_t; dmaCallbackHandlerFuncPtr irqHandlerCallback;
uint8_t flagsShift;
IRQn_Type irqN;
uint32_t rcc;
uint32_t userParam;
} dmaChannelDescriptor_t;
#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .stream = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0}
#define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\
if (dmaDescriptors[i].irqHandlerCallback)\
dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\
}
#define DMA_CLEAR_FLAG(d, flag) if(d->flagsShift > 31) d->dma->HIFCR = (flag << (d->flagsShift - 32)); else d->dma->LIFCR = (flag << d->flagsShift)
#define DMA_GET_FLAG_STATUS(d, flag) (d->flagsShift > 31 ? d->dma->HISR & (flag << (d->flagsShift - 32)): d->dma->LISR & (flag << d->flagsShift))
#define DMA_IT_TCIF ((uint32_t)0x00000020)
#define DMA_IT_HTIF ((uint32_t)0x00000010)
#define DMA_IT_TEIF ((uint32_t)0x00000008)
#define DMA_IT_DMEIF ((uint32_t)0x00000004)
#define DMA_IT_FEIF ((uint32_t)0x00000001)
#else #else
typedef void (*dmaCallbackHandlerFuncPtr)(DMA_Channel_TypeDef *channel);
typedef enum { typedef enum {
DMA1_CH2_HANDLER = 0, DMA1_CH1_HANDLER = 0,
DMA1_CH2_HANDLER,
DMA1_CH3_HANDLER, DMA1_CH3_HANDLER,
DMA1_CH4_HANDLER,
DMA1_CH5_HANDLER,
DMA1_CH6_HANDLER, DMA1_CH6_HANDLER,
DMA1_CH7_HANDLER, DMA1_CH7_HANDLER,
DMA2_CH1_HANDLER,
DMA2_CH2_HANDLER,
DMA2_CH3_HANDLER,
DMA2_CH4_HANDLER,
DMA2_CH5_HANDLER,
} dmaHandlerIdentifier_e; } dmaHandlerIdentifier_e;
typedef struct dmaHandlers_s { typedef struct dmaChannelDescriptor_s {
dmaCallbackHandlerFuncPtr dma1Channel2IRQHandler; DMA_TypeDef* dma;
dmaCallbackHandlerFuncPtr dma1Channel3IRQHandler; DMA_Channel_TypeDef* channel;
dmaCallbackHandlerFuncPtr dma1Channel6IRQHandler; dmaCallbackHandlerFuncPtr irqHandlerCallback;
dmaCallbackHandlerFuncPtr dma1Channel7IRQHandler; uint8_t flagsShift;
} dmaHandlers_t; IRQn_Type irqN;
uint32_t rcc;
uint32_t userParam;
} dmaChannelDescriptor_t;
#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .channel = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0}
#define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\
if (dmaDescriptors[i].irqHandlerCallback)\
dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\
}
#define DMA_CLEAR_FLAG(d, flag) d->dma->IFCR = (flag << d->flagsShift)
#define DMA_GET_FLAG_STATUS(d, flag) (d->dma->ISR & (flag << d->flagsShift))
#define DMA_IT_TCIF ((uint32_t)0x00000002)
#define DMA_IT_HTIF ((uint32_t)0x00000004)
#define DMA_IT_TEIF ((uint32_t)0x00000008)
#endif #endif
void dmaInit(void); void dmaInit(void);
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback); void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam);

View file

@ -16,50 +16,72 @@
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <platform.h> #include <platform.h>
#include "build_config.h" #include "drivers/nvic.h"
#include "drivers/dma.h" #include "drivers/dma.h"
/* /*
* DMA handlers for DMA resources that are shared between different features depending on run-time configuration. * DMA descriptors.
*/ */
static dmaHandlers_t dmaHandlers; static dmaChannelDescriptor_t dmaDescriptors[] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1Periph_DMA1),
void dmaNoOpHandler(DMA_Stream_TypeDef *stream) DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1Periph_DMA2),
{ DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1Periph_DMA2),
UNUSED(stream); DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1Periph_DMA2),
} DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1Periph_DMA2),
void DMA1_Stream2_IRQHandler(void) };
{
dmaHandlers.dma1Stream2IRQHandler(DMA1_Stream2); /*
} * DMA IRQ Handlers
*/
DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_ST1_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_ST2_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_ST3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_ST4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_ST5_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_ST6_HANDLER)
DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_ST7_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_ST1_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_ST2_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_ST3_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_ST4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_ST5_HANDLER)
void DMA1_Stream7_IRQHandler(void)
{
dmaHandlers.dma1Stream7IRQHandler(DMA1_Stream7);
}
void dmaInit(void) void dmaInit(void)
{ {
memset(&dmaHandlers, 0, sizeof(dmaHandlers)); // TODO: Do we need this?
dmaHandlers.dma1Stream2IRQHandler = dmaNoOpHandler;
dmaHandlers.dma1Stream7IRQHandler = dmaNoOpHandler;
} }
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback) void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{ {
switch (identifier) { NVIC_InitTypeDef NVIC_InitStructure;
case DMA1_ST2_HANDLER:
dmaHandlers.dma1Stream2IRQHandler = callback; RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
break; dmaDescriptors[identifier].irqHandlerCallback = callback;
case DMA1_ST7_HANDLER: dmaDescriptors[identifier].userParam = userParam;
dmaHandlers.dma1Stream7IRQHandler = callback;
break; NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN;
} NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} }

View file

@ -1,6 +1,6 @@
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include "platform.h" #include "platform.h"

View file

@ -15,7 +15,6 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -203,7 +202,7 @@ bool m25p16_init()
#ifdef M25P16_CS_PIN #ifdef M25P16_CS_PIN
m25p16CsPin = IOGetByTag(IO_TAG(M25P16_CS_PIN)); m25p16CsPin = IOGetByTag(IO_TAG(M25P16_CS_PIN));
#endif #endif
IOInit(m25p16CsPin, OWNER_FLASH, RESOURCE_SPI); IOInit(m25p16CsPin, OWNER_FLASH, RESOURCE_SPI_CS, 0);
IOConfigGPIO(m25p16CsPin, SPI_IO_CS_CFG); IOConfigGPIO(m25p16CsPin, SPI_IO_CS_CFG);
DISABLE_M25P16; DISABLE_M25P16;

View file

@ -20,8 +20,6 @@
#include "platform.h" #include "platform.h"
#include "build_config.h"
#include "gpio.h" #include "gpio.h"
#define MODE_OFFSET 0 #define MODE_OFFSET 0

View file

@ -4,48 +4,39 @@
* Created on: 3 aug. 2015 * Created on: 3 aug. 2015
* Author: borisb * Author: borisb
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
#include "build_config.h"
#include "common/axis.h"
#include "common/maths.h"
#include "drivers/sensor.h" #include "drivers/sensor.h"
#include "drivers/accgyro.h" #include "drivers/accgyro.h"
#include "drivers/gyro_sync.h" #include "drivers/gyro_sync.h"
#include "sensors/sensors.h"
#include "sensors/acceleration.h"
#include "config/runtime_config.h"
#include "config/config.h"
extern gyro_t gyro;
uint32_t targetLooptime;
static uint8_t mpuDividerDrops; static uint8_t mpuDividerDrops;
bool getMpuDataStatus(gyro_t *gyro) bool gyroSyncCheckUpdate(const gyro_t *gyro)
{ {
bool mpuDataStatus;
if (!gyro->intStatus) if (!gyro->intStatus)
return false; return false;
gyro->intStatus(&mpuDataStatus); return gyro->intStatus();
return mpuDataStatus;
} }
bool gyroSyncCheckUpdate(void) { #define GYRO_LPF_256HZ 0
return getMpuDataStatus(&gyro); #define GYRO_LPF_188HZ 1
} #define GYRO_LPF_98HZ 2
#define GYRO_LPF_42HZ 3
#define GYRO_LPF_20HZ 4
#define GYRO_LPF_10HZ 5
#define GYRO_LPF_5HZ 6
#define GYRO_LPF_NONE 7
void gyroUpdateSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator) { uint32_t gyroSetSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator)
{
int gyroSamplePeriod; int gyroSamplePeriod;
if (!lpf || lpf == 7) { if (lpf == GYRO_LPF_256HZ || lpf == GYRO_LPF_NONE) {
gyroSamplePeriod = 125; gyroSamplePeriod = 125;
} else { } else {
gyroSamplePeriod = 1000; gyroSamplePeriod = 1000;
@ -54,9 +45,11 @@ void gyroUpdateSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator) {
// calculate gyro divider and targetLooptime (expected cycleTime) // calculate gyro divider and targetLooptime (expected cycleTime)
mpuDividerDrops = gyroSyncDenominator - 1; mpuDividerDrops = gyroSyncDenominator - 1;
targetLooptime = (mpuDividerDrops + 1) * gyroSamplePeriod; const uint32_t targetLooptime = gyroSyncDenominator * gyroSamplePeriod;
return targetLooptime;
} }
uint8_t gyroMPU6xxxGetDividerDrops(void) { uint8_t gyroMPU6xxxGetDividerDrops(void)
{
return mpuDividerDrops; return mpuDividerDrops;
} }

View file

@ -5,8 +5,7 @@
* Author: borisb * Author: borisb
*/ */
extern uint32_t targetLooptime; struct gyro_s;
bool gyroSyncCheckUpdate(const struct gyro_s *gyro);
bool gyroSyncCheckUpdate(void);
uint8_t gyroMPU6xxxGetDividerDrops(void); uint8_t gyroMPU6xxxGetDividerDrops(void);
void gyroUpdateSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator); uint32_t gyroSetSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator);

View file

@ -31,7 +31,7 @@ static const IO_t pin = DEFIO_IO(INVERTER);
void initInverter(void) void initInverter(void)
{ {
IOInit(pin, OWNER_SYSTEM, RESOURCE_OUTPUT); IOInit(pin, OWNER_INVERTER, RESOURCE_OUTPUT, 0);
IOConfigGPIO(pin, IOCFG_OUT_PP); IOConfigGPIO(pin, IOCFG_OUT_PP);
inverterSet(false); inverterSet(false);

View file

@ -53,6 +53,19 @@ const struct ioPortDef_s ioPortDefs[] = {
}; };
# endif # endif
const char * const ownerNames[OWNER_TOTAL_COUNT] = {
"FREE", "PWM", "PPM", "MOTOR", "SERVO", "SOFTSERIAL", "ADC", "SERIAL", "DEBUG", "TIMER",
"SONAR", "SYSTEM", "SPI", "I2C", "SDCARD", "FLASH", "USB", "BEEPER", "OSD",
"BARO", "MPU", "INVERTER", "LED STRIP", "LED", "RECEIVER", "TRANSMITTER"
};
const char * const resourceNames[RESOURCE_TOTAL_COUNT] = {
"", // NONE
"IN", "OUT", "IN / OUT", "TIMER","UART TX","UART RX","UART TX/RX","EXTI","SCL",
"SDA", "SCK","MOSI","MISO","CS","BATTERY","RSSI","EXT","CURRENT"
};
ioRec_t* IO_Rec(IO_t io) ioRec_t* IO_Rec(IO_t io)
{ {
return io; return io;
@ -190,12 +203,12 @@ void IOToggle(IO_t io)
} }
// claim IO pin, set owner and resources // claim IO pin, set owner and resources
void IOInit(IO_t io, resourceOwner_t owner, resourceType_t resources) void IOInit(IO_t io, resourceOwner_t owner, resourceType_t resource, uint8_t index)
{ {
ioRec_t *ioRec = IO_Rec(io); ioRec_t *ioRec = IO_Rec(io);
if (owner != OWNER_FREE) // pass OWNER_FREE to keep old owner
ioRec->owner = owner; ioRec->owner = owner;
ioRec->resourcesUsed |= resources; ioRec->resource = resource;
ioRec->index = index;
} }
void IORelease(IO_t io) void IORelease(IO_t io)
@ -210,10 +223,10 @@ resourceOwner_t IOGetOwner(IO_t io)
return ioRec->owner; return ioRec->owner;
} }
resourceType_t IOGetResources(IO_t io) resourceType_t IOGetResource(IO_t io)
{ {
ioRec_t *ioRec = IO_Rec(io); ioRec_t *ioRec = IO_Rec(io);
return ioRec->resourcesUsed; return ioRec->resource;
} }
#if defined(STM32F1) #if defined(STM32F1)

View file

@ -52,6 +52,7 @@ typedef uint8_t ioConfig_t; // packed IO configuration
#define IO_CONFIG(mode, speed, otype, pupd) ((mode) | ((speed) << 2) | ((otype) << 4) | ((pupd) << 5)) #define IO_CONFIG(mode, speed, otype, pupd) ((mode) | ((speed) << 2) | ((otype) << 4) | ((pupd) << 5))
#define IOCFG_OUT_PP IO_CONFIG(GPIO_Mode_OUT, 0, GPIO_OType_PP, GPIO_PuPd_NOPULL) // TODO #define IOCFG_OUT_PP IO_CONFIG(GPIO_Mode_OUT, 0, GPIO_OType_PP, GPIO_PuPd_NOPULL) // TODO
#define IOCFG_OUT_PP_25 IO_CONFIG(GPIO_Mode_OUT, GPIO_Speed_25MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
#define IOCFG_OUT_OD IO_CONFIG(GPIO_Mode_OUT, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL) #define IOCFG_OUT_OD IO_CONFIG(GPIO_Mode_OUT, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL)
#define IOCFG_AF_PP IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_PP, GPIO_PuPd_NOPULL) #define IOCFG_AF_PP IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_PP, GPIO_PuPd_NOPULL)
#define IOCFG_AF_PP_PD IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_PP, GPIO_PuPd_DOWN) #define IOCFG_AF_PP_PD IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_PP, GPIO_PuPd_DOWN)
@ -60,6 +61,7 @@ typedef uint8_t ioConfig_t; // packed IO configuration
#define IOCFG_IPD IO_CONFIG(GPIO_Mode_IN, 0, 0, GPIO_PuPd_DOWN) #define IOCFG_IPD IO_CONFIG(GPIO_Mode_IN, 0, 0, GPIO_PuPd_DOWN)
#define IOCFG_IPU IO_CONFIG(GPIO_Mode_IN, 0, 0, GPIO_PuPd_UP) #define IOCFG_IPU IO_CONFIG(GPIO_Mode_IN, 0, 0, GPIO_PuPd_UP)
#define IOCFG_IN_FLOATING IO_CONFIG(GPIO_Mode_IN, 0, 0, GPIO_PuPd_NOPULL) #define IOCFG_IN_FLOATING IO_CONFIG(GPIO_Mode_IN, 0, 0, GPIO_PuPd_NOPULL)
#define IOCFG_IPU_25 IO_CONFIG(GPIO_Mode_IN, GPIO_Speed_25MHz, 0, GPIO_PuPd_UP)
#elif defined(UNIT_TEST) #elif defined(UNIT_TEST)
@ -84,7 +86,7 @@ void IOHi(IO_t io);
void IOLo(IO_t io); void IOLo(IO_t io);
void IOToggle(IO_t io); void IOToggle(IO_t io);
void IOInit(IO_t io, resourceOwner_t owner, resourceType_t resources); void IOInit(IO_t io, resourceOwner_t owner, resourceType_t resource, uint8_t index);
void IORelease(IO_t io); // unimplemented void IORelease(IO_t io); // unimplemented
resourceOwner_t IOGetOwner(IO_t io); resourceOwner_t IOGetOwner(IO_t io);
resourceType_t IOGetResources(IO_t io); resourceType_t IOGetResources(IO_t io);

View file

@ -12,7 +12,8 @@ typedef struct ioRec_s {
GPIO_TypeDef *gpio; GPIO_TypeDef *gpio;
uint16_t pin; uint16_t pin;
resourceOwner_t owner; resourceOwner_t owner;
resourceType_t resourcesUsed; // TODO! resourceType_t resource;
uint8_t index;
} ioRec_t; } ioRec_t;
extern ioRec_t ioRecs[DEFIO_IO_USED_COUNT]; extern ioRec_t ioRecs[DEFIO_IO_USED_COUNT];

View file

@ -97,7 +97,7 @@ void ledInit(bool alternative_led)
for (i = 0; i < LED_NUMBER; i++) { for (i = 0; i < LED_NUMBER; i++) {
if (leds[i + ledOffset]) { if (leds[i + ledOffset]) {
IOInit(leds[i + ledOffset], OWNER_SYSTEM, RESOURCE_OUTPUT); IOInit(leds[i + ledOffset], OWNER_LED, RESOURCE_OUTPUT, RESOURCE_INDEX(i));
IOConfigGPIO(leds[i + ledOffset], IOCFG_OUT_PP); IOConfigGPIO(leds[i + ledOffset], IOCFG_OUT_PP);
} }
} }

View file

@ -80,18 +80,9 @@ void setStripColors(const hsvColor_t *colors)
} }
} }
void ws2811DMAHandler(DMA_Channel_TypeDef *channel) {
if (DMA_GetFlagStatus(WS2811_DMA_TC_FLAG)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(channel, DISABLE);
DMA_ClearFlag(WS2811_DMA_TC_FLAG);
}
}
void ws2811LedStripInit(void) void ws2811LedStripInit(void)
{ {
memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE); memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE);
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, ws2811DMAHandler);
ws2811LedStripHardwareInit(); ws2811LedStripHardwareInit();
ws2811UpdateStrip(); ws2811UpdateStrip();
} }
@ -141,12 +132,11 @@ STATIC_UNIT_TESTED void updateLEDDMABuffer(uint8_t componentValue)
*/ */
void ws2811UpdateStrip(void) void ws2811UpdateStrip(void)
{ {
static uint32_t waitCounter = 0;
static rgbColor24bpp_t *rgb24; static rgbColor24bpp_t *rgb24;
// wait until previous transfer completes // don't wait - risk of infinite block, just get an update next time round
while(ws2811LedDataTransferInProgress) { if (ws2811LedDataTransferInProgress) {
waitCounter++; return;
} }
dmaBufferOffset = 0; // reset buffer memory index dmaBufferOffset = 0; // reset buffer memory index

View file

@ -25,8 +25,13 @@
#define WS2811_DMA_BUFFER_SIZE (WS2811_DATA_BUFFER_SIZE + WS2811_DELAY_BUFFER_LENGTH) // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes) #define WS2811_DMA_BUFFER_SIZE (WS2811_DATA_BUFFER_SIZE + WS2811_DELAY_BUFFER_LENGTH) // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes)
#if defined(STM32F40_41xxx)
#define BIT_COMPARE_1 67 // timer compare value for logical 1
#define BIT_COMPARE_0 33 // timer compare value for logical 0
#else
#define BIT_COMPARE_1 17 // timer compare value for logical 1 #define BIT_COMPARE_1 17 // timer compare value for logical 1
#define BIT_COMPARE_0 9 // timer compare value for logical 0 #define BIT_COMPARE_0 9 // timer compare value for logical 0
#endif
void ws2811LedStripInit(void); void ws2811LedStripInit(void);

View file

@ -23,35 +23,40 @@
#include "common/color.h" #include "common/color.h"
#include "drivers/light_ws2811strip.h" #include "drivers/light_ws2811strip.h"
#include "nvic.h" #include "nvic.h"
#include "io.h"
#include "dma.h"
#include "timer.h"
#ifdef LED_STRIP
static IO_t ws2811IO = IO_NONE;
bool ws2811Initialised = false;
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) {
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(descriptor->channel, DISABLE);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
}
}
void ws2811LedStripHardwareInit(void) void ws2811LedStripHardwareInit(void)
{ {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
uint16_t prescalerValue; uint16_t prescalerValue;
#ifdef CC3D dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#else
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* GPIOA Configuration: TIM3 Channel 1 as alternate function push-pull */ ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
GPIO_StructInit(&GPIO_InitStructure); /* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP));
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
#endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Compute the prescaler value */ /* Compute the prescaler value */
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
/* Time base configuration */ /* Time base configuration */
@ -100,24 +105,20 @@ void ws2811LedStripHardwareInit(void)
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure; ws2811Initialised = true;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
setStripColor(&hsv_white); setStripColor(&hsv_white);
ws2811UpdateStrip(); ws2811UpdateStrip();
} }
void ws2811LedStripDMAEnable(void) void ws2811LedStripDMAEnable(void)
{ {
if (!ws2811Initialised)
return;
DMA_SetCurrDataCounter(DMA1_Channel6, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred DMA_SetCurrDataCounter(DMA1_Channel6, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
TIM_SetCounter(TIM3, 0); TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE); DMA_Cmd(DMA1_Channel6, ENABLE);
} }
#endif

View file

@ -20,51 +20,51 @@
#include <platform.h> #include <platform.h>
#include "gpio.h" #include "io.h"
#include "nvic.h" #include "nvic.h"
#include "common/color.h" #include "common/color.h"
#include "drivers/light_ws2811strip.h" #include "drivers/light_ws2811strip.h"
#include "dma.h"
#include "rcc.h"
#include "timer.h"
#ifndef WS2811_GPIO #ifdef LED_STRIP
#define WS2811_GPIO GPIOB
#define WS2811_GPIO_AHB_PERIPHERAL RCC_AHBPeriph_GPIOB #ifndef WS2811_PIN
#define WS2811_GPIO_AF GPIO_AF_1 #define WS2811_PIN PB8 // TIM16_CH1
#define WS2811_PIN GPIO_Pin_8 // TIM16_CH1
#define WS2811_PIN_SOURCE GPIO_PinSource8
#define WS2811_TIMER TIM16 #define WS2811_TIMER TIM16
#define WS2811_TIMER_APB2_PERIPHERAL RCC_APB2Periph_TIM16
#define WS2811_DMA_CHANNEL DMA1_Channel3 #define WS2811_DMA_CHANNEL DMA1_Channel3
#define WS2811_IRQ DMA1_Channel3_IRQn
#define WS2811_DMA_TC_FLAG DMA1_FLAG_TC3
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_CH3_HANDLER #define WS2811_DMA_HANDLER_IDENTIFER DMA1_CH3_HANDLER
#endif #endif
static IO_t ws2811IO = IO_NONE;
bool ws2811Initialised = false;
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) {
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(descriptor->channel, DISABLE);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
}
}
void ws2811LedStripHardwareInit(void) void ws2811LedStripHardwareInit(void)
{ {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
uint16_t prescalerValue; uint16_t prescalerValue;
RCC_AHBPeriphClockCmd(WS2811_GPIO_AHB_PERIPHERAL, ENABLE); dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
GPIO_PinAFConfig(WS2811_GPIO, WS2811_PIN_SOURCE, WS2811_GPIO_AF); ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerGPIOAF(WS2811_TIMER));
/* Configuration alternate function push-pull */ RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = WS2811_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(WS2811_GPIO, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(WS2811_TIMER_APB2_PERIPHERAL, ENABLE);
/* Compute the prescaler value */ /* Compute the prescaler value */
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
@ -89,9 +89,6 @@ void ws2811LedStripHardwareInit(void)
TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE); TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE);
/* configure DMA */ /* configure DMA */
/* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA1 Channel Config */ /* DMA1 Channel Config */
DMA_DeInit(WS2811_DMA_CHANNEL); DMA_DeInit(WS2811_DMA_CHANNEL);
@ -114,24 +111,20 @@ void ws2811LedStripHardwareInit(void)
DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE); DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure; ws2811Initialised = true;
NVIC_InitStructure.NVIC_IRQChannel = WS2811_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
setStripColor(&hsv_white); setStripColor(&hsv_white);
ws2811UpdateStrip(); ws2811UpdateStrip();
} }
void ws2811LedStripDMAEnable(void) void ws2811LedStripDMAEnable(void)
{ {
if (!ws2811Initialised)
return;
DMA_SetCurrDataCounter(WS2811_DMA_CHANNEL, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred DMA_SetCurrDataCounter(WS2811_DMA_CHANNEL, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
TIM_SetCounter(WS2811_TIMER, 0); TIM_SetCounter(WS2811_TIMER, 0);
TIM_Cmd(WS2811_TIMER, ENABLE); TIM_Cmd(WS2811_TIMER, ENABLE);
DMA_Cmd(WS2811_DMA_CHANNEL, ENABLE); DMA_Cmd(WS2811_DMA_CHANNEL, ENABLE);
} }
#endif

View file

@ -23,63 +23,116 @@
#include "common/color.h" #include "common/color.h"
#include "light_ws2811strip.h" #include "light_ws2811strip.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "io.h"
#include "system.h"
#include "rcc.h"
#include "timer.h"
#ifdef LED_STRIP #ifdef LED_STRIP
#if !defined(WS2811_PIN)
#define WS2811_PIN PA0
#define WS2811_TIMER TIM5
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
#define WS2811_DMA_STREAM DMA1_Stream2
#define WS2811_DMA_IT DMA_IT_TCIF2
#define WS2811_DMA_CHANNEL DMA_Channel_6
#define WS2811_TIMER_CHANNEL TIM_Channel_1
#endif
static IO_t ws2811IO = IO_NONE;
static uint16_t timDMASource = 0;
bool ws2811Initialised = false;
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
{
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(descriptor->stream, DISABLE);
TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
}
}
void ws2811LedStripHardwareInit(void) void ws2811LedStripHardwareInit(void)
{ {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
uint16_t prescalerValue; uint16_t prescalerValue;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */ /* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerGPIOAF(WS2811_TIMER));
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM5);
// Stop timer // Stop timer
TIM_Cmd(TIM5, DISABLE); TIM_Cmd(WS2811_TIMER, DISABLE);
/* Compute the prescaler value */ /* Compute the prescaler value */
prescalerValue = (uint16_t) (SystemCoreClock / 2 / 84000000) - 1; prescalerValue = (uint16_t)(SystemCoreClock / 2 / 84000000) - 1;
/* Time base configuration */ /* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 104; // 800kHz TIM_TimeBaseStructure.TIM_Period = 104; // 800kHz
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); TIM_TimeBaseInit(WS2811_TIMER, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */ /* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM5, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
TIM_Cmd(TIM5, ENABLE); uint32_t channelAddress = 0;
switch (WS2811_TIMER_CHANNEL) {
case TIM_Channel_1:
TIM_OC1Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC1;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR1);
TIM_OC1PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
case TIM_Channel_2:
TIM_OC2Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC2;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR2);
TIM_OC2PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
case TIM_Channel_3:
TIM_OC3Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC3;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR3);
TIM_OC3PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
case TIM_Channel_4:
TIM_OC4Init(WS2811_TIMER, &TIM_OCInitStructure);
timDMASource = TIM_DMA_CC4;
channelAddress = (uint32_t)(&WS2811_TIMER->CCR4);
TIM_OC4PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
break;
}
TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE);
TIM_ARRPreloadConfig(WS2811_TIMER, ENABLE);
TIM_CCxCmd(WS2811_TIMER, WS2811_TIMER_CHANNEL, TIM_CCx_Enable);
TIM_Cmd(WS2811_TIMER, ENABLE);
/* configure DMA */ /* configure DMA */
/* DMA1 Channel Config */ DMA_Cmd(WS2811_DMA_STREAM, DISABLE);
DMA_Cmd(DMA1_Stream2, DISABLE); // disable DMA channel 6 DMA_DeInit(WS2811_DMA_STREAM);
DMA_DeInit(DMA1_Stream2);
DMA_StructInit(&DMA_InitStructure); DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_Channel = DMA_Channel_6; DMA_InitStructure.DMA_Channel = WS2811_DMA_CHANNEL;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM5->CCR1); DMA_InitStructure.DMA_PeripheralBaseAddr = channelAddress;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
@ -93,38 +146,28 @@ void ws2811LedStripHardwareInit(void)
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream2, &DMA_InitStructure);
DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE); DMA_Init(WS2811_DMA_STREAM, &DMA_InitStructure);
DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2); // clear DMA1 Channel 6 transfer complete flag
NVIC_InitTypeDef NVIC_InitStructure; DMA_ITConfig(WS2811_DMA_STREAM, DMA_IT_TC, ENABLE);
DMA_ClearITPendingBit(WS2811_DMA_STREAM, WS2811_DMA_IT);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn; dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ws2811Initialised = true;
setStripColor(&hsv_white); setStripColor(&hsv_white);
ws2811UpdateStrip(); ws2811UpdateStrip();
} }
void DMA1_Stream2_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_Stream2, DMA_FLAG_TCIF2)) {
ws2811LedDataTransferInProgress = 0;
DMA_Cmd(DMA1_Stream2, DISABLE);
TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE);
DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2);
}
}
void ws2811LedStripDMAEnable(void) void ws2811LedStripDMAEnable(void)
{ {
DMA_SetCurrDataCounter(DMA1_Stream2, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred if (!ws2811Initialised)
TIM_SetCounter(TIM5, 0); return;
DMA_Cmd(DMA1_Stream2, ENABLE);
TIM_DMACmd(TIM5, TIM_DMA_CC1, ENABLE); DMA_SetCurrDataCounter(WS2811_DMA_STREAM, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
TIM_SetCounter(WS2811_TIMER, 0);
DMA_Cmd(WS2811_DMA_STREAM, ENABLE);
TIM_DMACmd(WS2811_TIMER, timDMASource, ENABLE);
} }
#endif #endif

View file

@ -15,20 +15,20 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include <stdint.h> #include <stdint.h>
#include "common/printf.h"
#include "platform.h" #include "platform.h"
#include "version.h" #include "version.h"
#ifdef USE_MAX7456 #ifdef USE_MAX7456
#include "common/printf.h"
#include "drivers/bus_spi.h" #include "drivers/bus_spi.h"
#include "drivers/light_led.h" #include "drivers/light_led.h"
#include "drivers/system.h" #include "drivers/system.h"
#include "drivers/nvic.h"
#include "drivers/dma.h"
#include "max7456.h" #include "max7456.h"
#include "max7456_symbols.h" #include "max7456_symbols.h"
@ -36,24 +36,116 @@
#define DISABLE_MAX7456 IOHi(max7456CsPin) #define DISABLE_MAX7456 IOHi(max7456CsPin)
#define ENABLE_MAX7456 IOLo(max7456CsPin) #define ENABLE_MAX7456 IOLo(max7456CsPin)
/** Artificial Horizon limits **/
#define AHIPITCHMAX 200 // Specify maximum AHI pitch value displayed. Default 200 = 20.0 degrees
#define AHIROLLMAX 400 // Specify maximum AHI roll value displayed. Default 400 = 40.0 degrees
#define AHISIDEBARWIDTHPOSITION 7
#define AHISIDEBARHEIGHTPOSITION 3
uint16_t max_screen_size; uint16_t max_screen_size;
char max7456_screen[VIDEO_BUFFER_CHARS_PAL]; static MAX7456_CHAR_TYPE max7456_screen[VIDEO_BUFFER_CHARS_PAL + 5];
#define SCREEN_BUFFER ((MAX7456_CHAR_TYPE*)&max7456_screen[3])
#ifdef MAX7456_DMA_CHANNEL_TX
volatile uint8_t dma_transaction_in_progress = 0;
#endif
static uint8_t video_signal_type = 0; static uint8_t video_signal_type = 0;
static uint8_t max7456_lock = 0; static uint8_t max7456_lock = 0;
static IO_t max7456CsPin = IO_NONE; static IO_t max7456CsPin = IO_NONE;
uint8_t max7456_send(uint8_t add, uint8_t data) {
MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void) {
return SCREEN_BUFFER;
}
static uint8_t max7456_send(uint8_t add, uint8_t data)
{
spiTransferByte(MAX7456_SPI_INSTANCE, add); spiTransferByte(MAX7456_SPI_INSTANCE, add);
return spiTransferByte(MAX7456_SPI_INSTANCE, data); return spiTransferByte(MAX7456_SPI_INSTANCE, data);
} }
#ifdef MAX7456_DMA_CHANNEL_TX
static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_size) {
DMA_InitTypeDef DMA_InitStructure;
#ifdef MAX7456_DMA_CHANNEL_RX
static uint16_t dummy[] = {0xffff};
#else
UNUSED(rx_buffer);
#endif
while (dma_transaction_in_progress); // Wait for prev DMA transaction
DMA_DeInit(MAX7456_DMA_CHANNEL_TX);
#ifdef MAX7456_DMA_CHANNEL_RX
DMA_DeInit(MAX7456_DMA_CHANNEL_RX);
#endif
// Common to both channels
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(MAX7456_SPI_INSTANCE->DR));
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_BufferSize = buffer_size;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
#ifdef MAX7456_DMA_CHANNEL_RX
// Rx Channel
DMA_InitStructure.DMA_MemoryBaseAddr = rx_buffer ? (uint32_t)rx_buffer : (uint32_t)(dummy);
DMA_InitStructure.DMA_MemoryInc = rx_buffer ? DMA_MemoryInc_Enable : DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_Init(MAX7456_DMA_CHANNEL_RX, &DMA_InitStructure);
DMA_Cmd(MAX7456_DMA_CHANNEL_RX, ENABLE);
#endif
// Tx channel
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tx_buffer; //max7456_screen;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_Init(MAX7456_DMA_CHANNEL_TX, &DMA_InitStructure);
DMA_Cmd(MAX7456_DMA_CHANNEL_TX, ENABLE);
#ifdef MAX7456_DMA_CHANNEL_RX
DMA_ITConfig(MAX7456_DMA_CHANNEL_RX, DMA_IT_TC, ENABLE);
#else
DMA_ITConfig(MAX7456_DMA_CHANNEL_TX, DMA_IT_TC, ENABLE);
#endif
// Enable SPI TX/RX request
ENABLE_MAX7456;
dma_transaction_in_progress = 1;
SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE,
#ifdef MAX7456_DMA_CHANNEL_RX
SPI_I2S_DMAReq_Rx |
#endif
SPI_I2S_DMAReq_Tx, ENABLE);
}
void max7456_dma_irq_handler(dmaChannelDescriptor_t* descriptor) {
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
#ifdef MAX7456_DMA_CHANNEL_RX
DMA_Cmd(MAX7456_DMA_CHANNEL_RX, DISABLE);
#else
//Empty RX buffer. RX DMA takes care of it if enabled
while (SPI_I2S_GetFlagStatus(MAX7456_SPI_INSTANCE, SPI_I2S_FLAG_RXNE) == SET) {
MAX7456_SPI_INSTANCE->DR;
}
#endif
DMA_Cmd(MAX7456_DMA_CHANNEL_TX, DISABLE);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE,
#ifdef MAX7456_DMA_CHANNEL_RX
SPI_I2S_DMAReq_Rx |
#endif
SPI_I2S_DMAReq_Tx, DISABLE);
DISABLE_MAX7456;
for (uint16_t x = 0; x < max_screen_size; x++)
max7456_screen[x + 3] = MAX7456_CHAR(' ');
dma_transaction_in_progress = 0;
}
}
#endif
void max7456_init(uint8_t video_system) void max7456_init(uint8_t video_system)
{ {
@ -64,7 +156,7 @@ void max7456_init(uint8_t video_system)
#ifdef MAX7456_SPI_CS_PIN #ifdef MAX7456_SPI_CS_PIN
max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN)); max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN));
#endif #endif
IOInit(max7456CsPin, OWNER_SYSTEM, RESOURCE_SPI); IOInit(max7456CsPin, OWNER_OSD, RESOURCE_SPI_CS, 0);
IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG); IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG);
//Minimum spi clock period for max7456 is 100ns (10Mhz) //Minimum spi clock period for max7456 is 100ns (10Mhz)
@ -112,94 +204,66 @@ void max7456_init(uint8_t video_system)
DISABLE_MAX7456; DISABLE_MAX7456;
delay(100); delay(100);
for (x = 0; x < max_screen_size; x++)
SCREEN_BUFFER[x] = MAX7456_CHAR(' ');
#ifdef MAX7456_DMA_CHANNEL_TX
max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8));
max7456_screen[1] = (uint16_t)(MAX7456ADD_DMAL | (0 << 8));
max7456_screen[2] = (uint16_t)(MAX7456ADD_DMM | (1 << 8));
max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8));
max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8));
dmaSetHandler(MAX7456_DMA_IRQ_HANDLER_ID, max7456_dma_irq_handler, NVIC_PRIO_MAX7456_DMA, 0);
#endif
} }
// Copy string from ram into screen buffer // Copy string from ram into screen buffer
void max7456_write_string(const char *string, int16_t address) { void max7456_write_string(const char *string, int16_t address) {
char *dest; MAX7456_CHAR_TYPE *dest;
if (address >= 0) if (address >= 0)
dest = max7456_screen + address; dest = SCREEN_BUFFER + address;
else else
dest = max7456_screen + (max_screen_size + address); dest = SCREEN_BUFFER + (max_screen_size + address);
while(*string && dest < (max7456_screen + max_screen_size)) while(*string && dest < (SCREEN_BUFFER + max_screen_size)) {
*dest++ = *string++; *dest++ = MAX7456_CHAR(*string++);
}
// Write the artifical horizon to the screen buffer
void max7456_artificial_horizon(int rollAngle, int pitchAngle, uint8_t show_sidebars) {
uint16_t position = 194;
if(pitchAngle>AHIPITCHMAX) pitchAngle=AHIPITCHMAX;
if(pitchAngle<-AHIPITCHMAX) pitchAngle=-AHIPITCHMAX;
if(rollAngle>AHIROLLMAX) rollAngle=AHIROLLMAX;
if(rollAngle<-AHIROLLMAX) rollAngle=-AHIROLLMAX;
for(uint8_t X=0; X<=8; X++) {
if (X==4) X=5;
int Y = (rollAngle * (4-X)) / 64;
Y -= pitchAngle / 8;
Y += 41;
if(Y >= 0 && Y <= 81) {
uint16_t pos = position -7 + LINE*(Y/9) + 3 - 4*LINE + X;
max7456_screen[pos] = SYM_AH_BAR9_0+(Y%9);
}
}
max7456_screen[position-1] = SYM_AH_CENTER_LINE;
max7456_screen[position+1] = SYM_AH_CENTER_LINE_RIGHT;
max7456_screen[position] = SYM_AH_CENTER;
if (show_sidebars) {
// Draw AH sides
int8_t hudwidth = AHISIDEBARWIDTHPOSITION;
int8_t hudheight = AHISIDEBARHEIGHTPOSITION;
for(int8_t X=-hudheight; X<=hudheight; X++) {
max7456_screen[position-hudwidth+(X*LINE)] = SYM_AH_DECORATION;
max7456_screen[position+hudwidth+(X*LINE)] = SYM_AH_DECORATION;
}
// AH level indicators
max7456_screen[position-hudwidth+1] = SYM_AH_LEFT;
max7456_screen[position+hudwidth-1] = SYM_AH_RIGHT;
} }
} }
void max7456_draw_screen(void) { void max7456_draw_screen(void) {
uint16_t xx;
if (!max7456_lock) { if (!max7456_lock) {
ENABLE_MAX7456; #ifdef MAX7456_DMA_CHANNEL_TX
for (xx = 0; xx < max_screen_size; ++xx) { max7456_send_dma(max7456_screen, NULL, max_screen_size * 2 + 10);
max7456_send(MAX7456ADD_DMAH, xx>>8); #else
max7456_send(MAX7456ADD_DMAL, xx); uint16_t xx;
max7456_send(MAX7456ADD_DMDI, max7456_screen[xx]); max7456_lock = 1;
max7456_screen[xx] = ' ';
}
DISABLE_MAX7456;
}
}
void max7456_draw_screen_fast(void) {
uint16_t xx;
if (!max7456_lock) {
ENABLE_MAX7456; ENABLE_MAX7456;
max7456_send(MAX7456ADD_DMAH, 0); max7456_send(MAX7456ADD_DMAH, 0);
max7456_send(MAX7456ADD_DMAL, 0); max7456_send(MAX7456ADD_DMAL, 0);
max7456_send(MAX7456ADD_DMM, 1); max7456_send(MAX7456ADD_DMM, 1);
for (xx = 0; xx < max_screen_size; ++xx) { for (xx = 0; xx < max_screen_size; ++xx) {
max7456_send(MAX7456ADD_DMDI, max7456_screen[xx]); max7456_send(MAX7456ADD_DMDI, SCREEN_BUFFER[xx]);
max7456_screen[xx] = ' '; SCREEN_BUFFER[xx] = MAX7456_CHAR(0);
} }
max7456_send(MAX7456ADD_DMDI, 0xFF); max7456_send(MAX7456ADD_DMDI, 0xFF);
max7456_send(MAX7456ADD_DMM, 0); max7456_send(MAX7456ADD_DMM, 0);
DISABLE_MAX7456; DISABLE_MAX7456;
max7456_lock = 0;
#endif
} }
} }
void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) { void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) {
uint8_t x; uint8_t x;
#ifdef MAX7456_DMA_CHANNEL_TX
while (dma_transaction_in_progress);
#endif
while (max7456_lock);
max7456_lock = 1; max7456_lock = 1;
ENABLE_MAX7456; ENABLE_MAX7456;

View file

@ -143,12 +143,18 @@
enum VIDEO_TYPES { AUTO = 0, PAL, NTSC }; enum VIDEO_TYPES { AUTO = 0, PAL, NTSC };
extern uint16_t max_screen_size; extern uint16_t max_screen_size;
extern char max7456_screen[VIDEO_BUFFER_CHARS_PAL];
#ifdef MAX7456_DMA_CHANNEL_TX
#define MAX7456_CHAR_TYPE uint16_t
#define MAX7456_CHAR(X) (MAX7456ADD_DMDI | ((X) << 8))
#else
#define MAX7456_CHAR_TYPE char
#define MAX7456_CHAR(X) (X)
#endif
void max7456_init(uint8_t system); void max7456_init(uint8_t system);
void max7456_draw_screen(void); void max7456_draw_screen(void);
void max7456_draw_screen_fast(void);
void max7456_artificial_horizon(int rollAngle, int pitchAngle, uint8_t show_sidebars);
void max7456_write_string(const char *string, int16_t address); void max7456_write_string(const char *string, int16_t address);
void max7456_write_nvm(uint8_t char_address, uint8_t *font_data); void max7456_write_nvm(uint8_t char_address, uint8_t *font_data);
MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void);

View file

@ -38,6 +38,7 @@
#define NVIC_PRIO_MPU_DATA_READY NVIC_BUILD_PRIORITY(0x0f, 0x0f) #define NVIC_PRIO_MPU_DATA_READY NVIC_BUILD_PRIORITY(0x0f, 0x0f)
#define NVIC_PRIO_MAG_DATA_READY NVIC_BUILD_PRIORITY(0x0f, 0x0f) #define NVIC_PRIO_MAG_DATA_READY NVIC_BUILD_PRIORITY(0x0f, 0x0f)
#define NVIC_PRIO_CALLBACK NVIC_BUILD_PRIORITY(0x0f, 0x0f) #define NVIC_PRIO_CALLBACK NVIC_BUILD_PRIORITY(0x0f, 0x0f)
#define NVIC_PRIO_MAX7456_DMA NVIC_BUILD_PRIORITY(3, 0)
// utility macros to join/split priority // utility macros to join/split priority
#define NVIC_BUILD_PRIORITY(base,sub) (((((base)<<(4-(7-(NVIC_PRIORITY_GROUPING>>8))))|((sub)&(0x0f>>(7-(NVIC_PRIORITY_GROUPING>>8)))))<<4)&0xf0) #define NVIC_BUILD_PRIORITY(base,sub) (((((base)<<(4-(7-(NVIC_PRIORITY_GROUPING>>8))))|((sub)&(0x0f>>(7-(NVIC_PRIORITY_GROUPING>>8)))))<<4)&0xf0)

View file

@ -18,7 +18,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
@ -93,16 +92,6 @@ pwmOutputConfiguration_t *pwmGetOutputConfiguration(void)
return &pwmOutputConfiguration; return &pwmOutputConfiguration;
} }
bool CheckGPIOPin(ioTag_t tag, GPIO_TypeDef *gpio, uint16_t pin)
{
return IO_GPIOBYTAG(tag) == gpio && IO_PINBYTAG(tag) == pin;
}
bool CheckGPIOPinSource(ioTag_t tag, GPIO_TypeDef *gpio, uint16_t pin)
{
return IO_GPIOBYTAG(tag) == gpio && IO_GPIO_PinSource(IOGetByTag(tag)) == pin;
}
pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init) pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
{ {
int i = 0; int i = 0;
@ -142,9 +131,9 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
continue; continue;
#endif #endif
#if defined(STM32F303xC) && defined(USE_USART3) #if defined(STM32F303xC) && defined(USE_UART3)
// skip UART3 ports (PB10/PB11) // skip UART3 ports (PB10/PB11)
if (init->useUART3 && (CheckGPIOPin(timerHardwarePtr->tag, UART3_GPIO, UART3_TX_PIN) || CheckGPIOPin(timerHardwarePtr->tag, UART3_GPIO, UART3_RX_PIN))) if (init->useUART3 && (timerHardwarePtr->tag == IO_TAG(UART3_TX_PIN) || timerHardwarePtr->tag == IO_TAG(UART3_RX_PIN)))
continue; continue;
#endif #endif
@ -157,33 +146,33 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
continue; continue;
#endif #endif
#ifdef LED_STRIP_TIMER #ifdef WS2811_TIMER
// skip LED Strip output // skip LED Strip output
if (init->useLEDStrip) { if (init->useLEDStrip) {
if (timerHardwarePtr->tim == LED_STRIP_TIMER) if (timerHardwarePtr->tim == WS2811_TIMER)
continue; continue;
#if defined(STM32F303xC) && defined(WS2811_GPIO) && defined(WS2811_PIN_SOURCE) #if defined(STM32F303xC) && defined(WS2811_PIN)
if (CheckGPIOPinSource(timerHardwarePtr->tag, WS2811_GPIO, WS2811_PIN_SOURCE)) if (timerHardwarePtr->tag == IO_TAG(WS2811_PIN))
continue; continue;
#endif #endif
} }
#endif #endif
#ifdef VBAT_ADC_GPIO #ifdef VBAT_ADC_PIN
if (init->useVbat && CheckGPIOPin(timerHardwarePtr->tag, VBAT_ADC_GPIO, VBAT_ADC_GPIO_PIN)) { if (init->useVbat && timerHardwarePtr->tag == IO_TAG(VBAT_ADC_PIN)) {
continue; continue;
} }
#endif #endif
#ifdef RSSI_ADC_GPIO #ifdef RSSI_ADC_GPIO
if (init->useRSSIADC && CheckGPIOPin(timerHardwarePtr->tag, RSSI_ADC_GPIO, RSSI_ADC_GPIO_PIN)) { if (init->useRSSIADC && timerHardwarePtr->tag == IO_TAG(RSSI_ADC_PIN)) {
continue; continue;
} }
#endif #endif
#ifdef CURRENT_METER_ADC_GPIO #ifdef CURRENT_METER_ADC_GPIO
if (init->useCurrentMeterADC && CheckGPIOPin(timerHardwarePtr->tag, CURRENT_METER_ADC_GPIO, CURRENT_METER_ADC_GPIO_PIN)) { if (init->useCurrentMeterADC && timerHardwarePtr->tag == IO_TAG(CURRENT_METER_ADC_PIN)) {
continue; continue;
} }
#endif #endif
@ -274,7 +263,7 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
} }
if (init->useChannelForwarding && !init->airplane) { if (init->useChannelForwarding && !init->airplane) {
#if defined(NAZE) && defined(LED_STRIP_TIMER) #if defined(NAZE) && defined(WS2811_TIMER)
// if LED strip is active, PWM5-8 are unavailable, so map AUX1+AUX2 to PWM13+PWM14 // if LED strip is active, PWM5-8 are unavailable, so map AUX1+AUX2 to PWM13+PWM14
if (init->useLEDStrip) { if (init->useLEDStrip) {
if (timerIndex >= PWM13 && timerIndex <= PWM14) { if (timerIndex >= PWM13 && timerIndex <= PWM14) {

View file

@ -34,10 +34,20 @@
#define MAX_INPUTS 8 #define MAX_INPUTS 8
#define PWM_TIMER_MHZ 1 #define PWM_TIMER_MHZ 1
#if defined(STM32F40_41xxx) // must be multiples of timer clock
#define ONESHOT42_TIMER_MHZ 21
#define ONESHOT125_TIMER_MHZ 12
#define PWM_BRUSHED_TIMER_MHZ 21
#define MULTISHOT_TIMER_MHZ 84
#else
#define PWM_BRUSHED_TIMER_MHZ 24 #define PWM_BRUSHED_TIMER_MHZ 24
#define MULTISHOT_TIMER_MHZ 72 #define MULTISHOT_TIMER_MHZ 72
#define ONESHOT42_TIMER_MHZ 24 #define ONESHOT42_TIMER_MHZ 24
#define ONESHOT125_TIMER_MHZ 8 #define ONESHOT125_TIMER_MHZ 8
#endif
#define MULTISHOT_5US_PW (MULTISHOT_TIMER_MHZ * 5)
#define MULTISHOT_20US_MULT (MULTISHOT_TIMER_MHZ * 20 / 1000.0f)
typedef struct sonarIOConfig_s { typedef struct sonarIOConfig_s {
ioTag_t triggerTag; ioTag_t triggerTag;
@ -93,8 +103,6 @@ typedef enum {
PWM_PF_OUTPUT_PROTOCOL_ONESHOT = (1 << 4) PWM_PF_OUTPUT_PROTOCOL_ONESHOT = (1 << 4)
} pwmPortFlags_e; } pwmPortFlags_e;
enum {PWM_INVERTED = 1};
typedef struct pwmPortConfiguration_s { typedef struct pwmPortConfiguration_s {
uint8_t index; uint8_t index;
pwmPortFlags_e flags; pwmPortFlags_e flags;

View file

@ -84,22 +84,19 @@ static void pwmOCConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t value, uint8
} }
} }
static void pwmGPIOConfig(ioTag_t pin, ioConfig_t mode)
{
IOInit(IOGetByTag(pin), OWNER_PWMOUTPUT_MOTOR, RESOURCE_OUTPUT);
IOConfigGPIO(IOGetByTag(pin), mode);
}
static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timerHardware, uint8_t mhz, uint16_t period, uint16_t value) static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timerHardware, uint8_t mhz, uint16_t period, uint16_t value)
{ {
pwmOutputPort_t *p = &pwmOutputPorts[allocatedOutputPortCount++]; pwmOutputPort_t *p = &pwmOutputPorts[allocatedOutputPortCount++];
configTimeBase(timerHardware->tim, period, mhz); configTimeBase(timerHardware->tim, period, mhz);
pwmGPIOConfig(timerHardware->tag, IOCFG_AF_PP);
pwmOCConfig(timerHardware->tim, timerHardware->channel, value, timerHardware->outputInverted); IO_t io = IOGetByTag(timerHardware->tag);
IOInit(io, OWNER_MOTOR, RESOURCE_OUTPUT, allocatedOutputPortCount);
IOConfigGPIO(io, IOCFG_AF_PP);
if (timerHardware->outputEnable) { pwmOCConfig(timerHardware->tim, timerHardware->channel, value, timerHardware->output & TIMER_OUTPUT_INVERTED);
if (timerHardware->output & TIMER_OUTPUT_ENABLED) {
TIM_CtrlPWMOutputs(timerHardware->tim, ENABLE); TIM_CtrlPWMOutputs(timerHardware->tim, ENABLE);
} }
TIM_Cmd(timerHardware->tim, ENABLE); TIM_Cmd(timerHardware->tim, ENABLE);
@ -121,6 +118,8 @@ static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timerHardware, uint8
p->period = period; p->period = period;
p->tim = timerHardware->tim; p->tim = timerHardware->tim;
*p->ccr = 0;
return p; return p;
} }
@ -134,9 +133,19 @@ static void pwmWriteStandard(uint8_t index, uint16_t value)
*motors[index]->ccr = value; *motors[index]->ccr = value;
} }
static void pwmWriteOneShot42(uint8_t index, uint16_t value)
{
*motors[index]->ccr = lrintf((float)(value * ONESHOT42_TIMER_MHZ/24.0f));
}
static void pwmWriteOneShot125(uint8_t index, uint16_t value)
{
*motors[index]->ccr = lrintf((float)(value * ONESHOT125_TIMER_MHZ/8.0f));
}
static void pwmWriteMultiShot(uint8_t index, uint16_t value) static void pwmWriteMultiShot(uint8_t index, uint16_t value)
{ {
*motors[index]->ccr = lrintf(((float)(value-1000) / 0.69444f) + 360); *motors[index]->ccr = lrintf(((float)(value-1000) * MULTISHOT_20US_MULT) + MULTISHOT_5US_PW);
} }
void pwmWriteMotor(uint8_t index, uint16_t value) void pwmWriteMotor(uint8_t index, uint16_t value)
@ -221,7 +230,9 @@ void pwmFastPwmMotorConfig(const timerHardware_t *timerHardware, uint8_t motorIn
motors[motorIndex] = pwmOutConfig(timerHardware, timerMhzCounter, 0xFFFF, 0); motors[motorIndex] = pwmOutConfig(timerHardware, timerMhzCounter, 0xFFFF, 0);
} }
motors[motorIndex]->pwmWritePtr = (fastPwmProtocolType == PWM_TYPE_MULTISHOT) ? pwmWriteMultiShot : pwmWriteStandard; motors[motorIndex]->pwmWritePtr = (fastPwmProtocolType == PWM_TYPE_MULTISHOT) ? pwmWriteMultiShot :
((fastPwmProtocolType == PWM_TYPE_ONESHOT125) ? pwmWriteOneShot125 :
pwmWriteOneShot42);
} }
#ifdef USE_SERVOS #ifdef USE_SERVOS

View file

@ -18,9 +18,8 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <platform.h> #include <platform.h>
#include "build_config.h" #include "build_config.h"
#include "debug.h" #include "debug.h"
@ -337,12 +336,6 @@ static void pwmEdgeCallback(timerCCHandlerRec_t *cbRec, captureCompare_t capture
} }
} }
static void pwmGPIOConfig(ioTag_t pin, ioConfig_t mode)
{
IOInit(IOGetByTag(pin), OWNER_PWMINPUT, RESOURCE_INPUT);
IOConfigGPIO(IOGetByTag(pin), mode);
}
void pwmICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity) void pwmICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
{ {
TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitTypeDef TIM_ICInitStructure;
@ -372,7 +365,10 @@ void pwmInConfig(const timerHardware_t *timerHardwarePtr, uint8_t channel)
self->mode = INPUT_MODE_PWM; self->mode = INPUT_MODE_PWM;
self->timerHardware = timerHardwarePtr; self->timerHardware = timerHardwarePtr;
pwmGPIOConfig(timerHardwarePtr->tag, timerHardwarePtr->ioMode); IO_t io = IOGetByTag(timerHardwarePtr->tag);
IOInit(io, OWNER_PWMINPUT, RESOURCE_INPUT, RESOURCE_INDEX(channel));
IOConfigGPIO(io, timerHardwarePtr->ioMode);
pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising); pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising);
timerConfigure(timerHardwarePtr, (uint16_t)PWM_TIMER_PERIOD, PWM_TIMER_MHZ); timerConfigure(timerHardwarePtr, (uint16_t)PWM_TIMER_PERIOD, PWM_TIMER_MHZ);
@ -401,7 +397,10 @@ void ppmInConfig(const timerHardware_t *timerHardwarePtr)
self->mode = INPUT_MODE_PPM; self->mode = INPUT_MODE_PPM;
self->timerHardware = timerHardwarePtr; self->timerHardware = timerHardwarePtr;
pwmGPIOConfig(timerHardwarePtr->tag, timerHardwarePtr->ioMode); IO_t io = IOGetByTag(timerHardwarePtr->tag);
IOInit(io, OWNER_PPMINPUT, RESOURCE_INPUT, 0);
IOConfigGPIO(io, timerHardwarePtr->ioMode);
pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising); pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising);
timerConfigure(timerHardwarePtr, (uint16_t)PPM_TIMER_PERIOD, PWM_TIMER_MHZ); timerConfigure(timerHardwarePtr, (uint16_t)PPM_TIMER_PERIOD, PWM_TIMER_MHZ);

View file

@ -7,7 +7,7 @@ void RCC_ClockCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
int tag = periphTag >> 5; int tag = periphTag >> 5;
uint32_t mask = 1 << (periphTag & 0x1f); uint32_t mask = 1 << (periphTag & 0x1f);
switch (tag) { switch (tag) {
#if defined(STM32F303xC) #if defined(STM32F3) || defined(STM32F1)
case RCC_AHB: case RCC_AHB:
RCC_AHBPeriphClockCmd(mask, NewState); RCC_AHBPeriphClockCmd(mask, NewState);
break; break;
@ -18,7 +18,7 @@ void RCC_ClockCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
case RCC_APB1: case RCC_APB1:
RCC_APB1PeriphClockCmd(mask, NewState); RCC_APB1PeriphClockCmd(mask, NewState);
break; break;
#if defined(STM32F40_41xxx) || defined(STM32F411xE) #if defined(STM32F4)
case RCC_AHB1: case RCC_AHB1:
RCC_AHB1PeriphClockCmd(mask, NewState); RCC_AHB1PeriphClockCmd(mask, NewState);
break; break;
@ -31,7 +31,7 @@ void RCC_ResetCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
int tag = periphTag >> 5; int tag = periphTag >> 5;
uint32_t mask = 1 << (periphTag & 0x1f); uint32_t mask = 1 << (periphTag & 0x1f);
switch (tag) { switch (tag) {
#if defined(STM32F303xC) #if defined(STM32F3) || defined(STM32F10X_CL)
case RCC_AHB: case RCC_AHB:
RCC_AHBPeriphResetCmd(mask, NewState); RCC_AHBPeriphResetCmd(mask, NewState);
break; break;
@ -42,7 +42,7 @@ void RCC_ResetCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
case RCC_APB1: case RCC_APB1:
RCC_APB1PeriphResetCmd(mask, NewState); RCC_APB1PeriphResetCmd(mask, NewState);
break; break;
#if defined(STM32F40_41xxx) || defined(STM32F411xE) #if defined(STM32F4)
case RCC_AHB1: case RCC_AHB1:
RCC_AHB1PeriphResetCmd(mask, NewState); RCC_AHB1PeriphResetCmd(mask, NewState);
break; break;

View file

@ -1,46 +1,52 @@
#pragma once #pragma once
#define RESOURCE_INDEX(x) x + 1
typedef enum { typedef enum {
OWNER_FREE = 0, OWNER_FREE = 0,
OWNER_PWMINPUT, OWNER_PWMINPUT,
OWNER_PPMINPUT, OWNER_PPMINPUT,
OWNER_PWMOUTPUT_MOTOR, OWNER_MOTOR,
OWNER_PWMOUTPUT_SERVO, OWNER_SERVO,
OWNER_SOFTSERIAL_RX, OWNER_SOFTSERIAL,
OWNER_SOFTSERIAL_TX,
OWNER_SOFTSERIAL_RXTX, // bidirectional pin for softserial
OWNER_SOFTSERIAL_AUXTIMER, // timer channel is used for softserial. No IO function on pin
OWNER_ADC, OWNER_ADC,
OWNER_SERIAL_RX, OWNER_SERIAL,
OWNER_SERIAL_TX,
OWNER_SERIAL_RXTX,
OWNER_PINDEBUG, OWNER_PINDEBUG,
OWNER_TIMER, OWNER_TIMER,
OWNER_SONAR, OWNER_SONAR,
OWNER_SYSTEM, OWNER_SYSTEM,
OWNER_SPI,
OWNER_I2C,
OWNER_SDCARD, OWNER_SDCARD,
OWNER_FLASH, OWNER_FLASH,
OWNER_USB, OWNER_USB,
OWNER_BEEPER, OWNER_BEEPER,
OWNER_OSD, OWNER_OSD,
OWNER_BARO, OWNER_BARO,
OWNER_MPU,
OWNER_INVERTER,
OWNER_LED_STRIP,
OWNER_LED,
OWNER_RX,
OWNER_TX,
OWNER_TOTAL_COUNT OWNER_TOTAL_COUNT
} resourceOwner_t; } resourceOwner_t;
extern const char * const ownerNames[OWNER_TOTAL_COUNT];
// Currently TIMER should be shared resource (softserial dualtimer and timerqueue needs to allocate timer channel, but pin can be used for other function) // Currently TIMER should be shared resource (softserial dualtimer and timerqueue needs to allocate timer channel, but pin can be used for other function)
// with mode switching (shared serial ports, ...) this will need some improvement // with mode switching (shared serial ports, ...) this will need some improvement
typedef enum { typedef enum {
RESOURCE_NONE = 0, RESOURCE_NONE = 0,
RESOURCE_INPUT = 1 << 0, RESOURCE_INPUT, RESOURCE_OUTPUT, RESOURCE_IO,
RESOURCE_OUTPUT = 1 << 1, RESOURCE_TIMER,
RESOURCE_IO = RESOURCE_INPUT | RESOURCE_OUTPUT, RESOURCE_UART_TX, RESOURCE_UART_RX, RESOURCE_UART_TXRX,
RESOURCE_TIMER = 1 << 2, RESOURCE_EXTI,
RESOURCE_TIMER_DUAL = 1 << 3, // channel used in dual-capture, other channel will be allocated too RESOURCE_I2C_SCL, RESOURCE_I2C_SDA,
RESOURCE_USART = 1 << 4, RESOURCE_SPI_SCK, RESOURCE_SPI_MOSI, RESOURCE_SPI_MISO, RESOURCE_SPI_CS,
RESOURCE_ADC = 1 << 5, RESOURCE_ADC_BATTERY, RESOURCE_ADC_RSSI, RESOURCE_ADC_EXTERNAL1, RESOURCE_ADC_CURRENT,
RESOURCE_EXTI = 1 << 6, RESOURCE_TOTAL_COUNT
RESOURCE_I2C = 1 << 7,
RESOURCE_SPI = 1 << 8,
} resourceType_t; } resourceType_t;
extern const char * const resourceNames[RESOURCE_TOTAL_COUNT];

View file

@ -15,12 +15,13 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "platform.h" #include "platform.h"
#ifdef USE_SDCARD
#include "nvic.h" #include "nvic.h"
#include "io.h" #include "io.h"
@ -30,8 +31,6 @@
#include "sdcard.h" #include "sdcard.h"
#include "sdcard_standard.h" #include "sdcard_standard.h"
#ifdef USE_SDCARD
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING #ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
#define SDCARD_PROFILING #define SDCARD_PROFILING
#endif #endif
@ -44,7 +43,7 @@
// Chosen so that CMD8 will have the same CRC as CMD0: // Chosen so that CMD8 will have the same CRC as CMD0:
#define SDCARD_IF_COND_CHECK_PATTERN 0xAB #define SDCARD_IF_COND_CHECK_PATTERN 0xAB
#define SDCARD_TIMEOUT_INIT_MILLIS 2000 #define SDCARD_TIMEOUT_INIT_MILLIS 200
#define SDCARD_MAX_CONSECUTIVE_FAILURES 8 #define SDCARD_MAX_CONSECUTIVE_FAILURES 8
/* Break up 512-byte SD card sectors into chunks of this size when writing without DMA to reduce the peak overhead /* Break up 512-byte SD card sectors into chunks of this size when writing without DMA to reduce the peak overhead
@ -126,7 +125,7 @@ void sdcardInsertionDetectDeinit(void)
{ {
#ifdef SDCARD_DETECT_PIN #ifdef SDCARD_DETECT_PIN
sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN)); sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
IOInit(sdCardDetectPin, OWNER_SYSTEM, RESOURCE_SPI); IOInit(sdCardDetectPin, OWNER_FREE, RESOURCE_NONE, 0);
IOConfigGPIO(sdCardDetectPin, IOCFG_IN_FLOATING); IOConfigGPIO(sdCardDetectPin, IOCFG_IN_FLOATING);
#endif #endif
} }
@ -135,7 +134,7 @@ void sdcardInsertionDetectInit(void)
{ {
#ifdef SDCARD_DETECT_PIN #ifdef SDCARD_DETECT_PIN
sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN)); sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
IOInit(sdCardDetectPin, OWNER_SDCARD, RESOURCE_INPUT); IOInit(sdCardDetectPin, OWNER_SDCARD, RESOURCE_INPUT, 0);
IOConfigGPIO(sdCardDetectPin, IOCFG_IPU); IOConfigGPIO(sdCardDetectPin, IOCFG_IPU);
#endif #endif
} }
@ -547,7 +546,7 @@ void sdcard_init(bool useDMA)
#ifdef SDCARD_SPI_CS_PIN #ifdef SDCARD_SPI_CS_PIN
sdCardCsPin = IOGetByTag(IO_TAG(SDCARD_SPI_CS_PIN)); sdCardCsPin = IOGetByTag(IO_TAG(SDCARD_SPI_CS_PIN));
IOInit(sdCardCsPin, OWNER_SDCARD, RESOURCE_SPI); IOInit(sdCardCsPin, OWNER_SDCARD, RESOURCE_SPI_CS, 0);
IOConfigGPIO(sdCardCsPin, SPI_IO_CS_CFG); IOConfigGPIO(sdCardCsPin, SPI_IO_CS_CFG);
#endif // SDCARD_SPI_CS_PIN #endif // SDCARD_SPI_CS_PIN

View file

@ -22,4 +22,4 @@ typedef void (*sensorInitFuncPtr)(void); // sensor init proto
typedef bool (*sensorReadFuncPtr)(int16_t *data); // sensor read and align prototype typedef bool (*sensorReadFuncPtr)(int16_t *data); // sensor read and align prototype
typedef void (*sensorAccInitFuncPtr)(struct acc_s *acc); // sensor init prototype typedef void (*sensorAccInitFuncPtr)(struct acc_s *acc); // sensor init prototype
typedef void (*sensorGyroInitFuncPtr)(uint8_t lpf); // gyro sensor init prototype typedef void (*sensorGyroInitFuncPtr)(uint8_t lpf); // gyro sensor init prototype
typedef void (*sensorInterruptFuncPtr)(bool *data); // sensor Interrupt Data Ready typedef bool (*sensorInterruptFuncPtr)(void); // sensor Interrupt Data Ready

View file

@ -56,7 +56,7 @@ void serialWriteBuf(serialPort_t *instance, uint8_t *data, int count)
} }
} }
uint8_t serialRxBytesWaiting(serialPort_t *instance) uint32_t serialRxBytesWaiting(serialPort_t *instance)
{ {
return instance->vTable->serialTotalRxWaiting(instance); return instance->vTable->serialTotalRxWaiting(instance);
} }

View file

@ -81,7 +81,7 @@ struct serialPortVTable {
}; };
void serialWrite(serialPort_t *instance, uint8_t ch); void serialWrite(serialPort_t *instance, uint8_t ch);
uint8_t serialRxBytesWaiting(serialPort_t *instance); uint32_t serialRxBytesWaiting(serialPort_t *instance);
uint8_t serialTxBytesFree(serialPort_t *instance); uint8_t serialTxBytesFree(serialPort_t *instance);
void serialWriteBuf(serialPort_t *instance, uint8_t *data, int count); void serialWriteBuf(serialPort_t *instance, uint8_t *data, int count);
uint8_t serialRead(serialPort_t *instance); uint8_t serialRead(serialPort_t *instance);

View file

@ -17,7 +17,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
@ -100,19 +99,20 @@ void setTxSignal(softSerial_t *softSerial, uint8_t state)
} }
} }
static void softSerialGPIOConfig(ioTag_t pin, ioConfig_t mode) void serialInputPortConfig(ioTag_t pin, uint8_t portIndex)
{ {
IOInit(IOGetByTag(pin), OWNER_SOFTSERIAL_RXTX, RESOURCE_USART); IOInit(IOGetByTag(pin), OWNER_SOFTSERIAL, RESOURCE_UART_RX, RESOURCE_INDEX(portIndex));
IOConfigGPIO(IOGetByTag(pin), mode); #ifdef STM32F1
IOConfigGPIO(IOGetByTag(pin), IOCFG_IPU);
#else
IOConfigGPIO(IOGetByTag(pin), IOCFG_AF_PP_UP);
#endif
} }
void serialInputPortConfig(ioTag_t pin) static void serialOutputPortConfig(ioTag_t pin, uint8_t portIndex)
{ {
#ifdef STM32F1 IOInit(IOGetByTag(pin), OWNER_SOFTSERIAL, RESOURCE_UART_TX, RESOURCE_INDEX(portIndex));
softSerialGPIOConfig(pin, IOCFG_IPU); IOConfigGPIO(IOGetByTag(pin), IOCFG_OUT_PP);
#else
softSerialGPIOConfig(pin, IOCFG_AF_PP_UP);
#endif
} }
static bool isTimerPeriodTooLarge(uint32_t timerPeriod) static bool isTimerPeriodTooLarge(uint32_t timerPeriod)
@ -164,11 +164,6 @@ static void serialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t
timerChConfigCallbacks(timerHardwarePtr, &softSerialPorts[reference].edgeCb, NULL); timerChConfigCallbacks(timerHardwarePtr, &softSerialPorts[reference].edgeCb, NULL);
} }
static void serialOutputPortConfig(ioTag_t pin)
{
softSerialGPIOConfig(pin, IOCFG_OUT_PP);
}
static void resetBuffers(softSerial_t *softSerial) static void resetBuffers(softSerial_t *softSerial)
{ {
softSerial->port.rxBufferSize = SOFTSERIAL_BUFFER_SIZE; softSerial->port.rxBufferSize = SOFTSERIAL_BUFFER_SIZE;
@ -219,10 +214,10 @@ serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallb
softSerial->softSerialPortIndex = portIndex; softSerial->softSerialPortIndex = portIndex;
softSerial->txIO = IOGetByTag(softSerial->txTimerHardware->tag); softSerial->txIO = IOGetByTag(softSerial->txTimerHardware->tag);
serialOutputPortConfig(softSerial->txTimerHardware->tag); serialOutputPortConfig(softSerial->txTimerHardware->tag, portIndex);
softSerial->rxIO = IOGetByTag(softSerial->rxTimerHardware->tag); softSerial->rxIO = IOGetByTag(softSerial->rxTimerHardware->tag);
serialInputPortConfig(softSerial->rxTimerHardware->tag); serialInputPortConfig(softSerial->rxTimerHardware->tag, portIndex);
setTxSignal(softSerial, ENABLE); setTxSignal(softSerial, ENABLE);
delay(50); delay(50);
@ -271,8 +266,6 @@ void processTxState(softSerial_t *softSerial)
softSerial->isTransmittingData = false; softSerial->isTransmittingData = false;
} }
enum { enum {
TRAILING, TRAILING,
LEADING LEADING
@ -408,7 +401,7 @@ void onSerialRxPinChange(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
} }
} }
uint8_t softSerialRxBytesWaiting(serialPort_t *instance) uint32_t softSerialRxBytesWaiting(serialPort_t *instance)
{ {
if ((instance->mode & MODE_RX) == 0) { if ((instance->mode & MODE_RX) == 0) {
return 0; return 0;

View file

@ -28,7 +28,7 @@ serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallb
// serialPort API // serialPort API
void softSerialWriteByte(serialPort_t *instance, uint8_t ch); void softSerialWriteByte(serialPort_t *instance, uint8_t ch);
uint8_t softSerialRxBytesWaiting(serialPort_t *instance); uint32_t softSerialRxBytesWaiting(serialPort_t *instance);
uint8_t softSerialTxBytesFree(serialPort_t *instance); uint8_t softSerialTxBytesFree(serialPort_t *instance);
uint8_t softSerialReadByte(serialPort_t *instance); uint8_t softSerialReadByte(serialPort_t *instance);
void softSerialSetBaudRate(serialPort_t *s, uint32_t baudRate); void softSerialSetBaudRate(serialPort_t *s, uint32_t baudRate);

View file

@ -22,7 +22,6 @@
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
@ -99,26 +98,26 @@ serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback,
uartPort_t *s = NULL; uartPort_t *s = NULL;
if (USARTx == USART1) { if (USARTx == USART1) {
s = serialUSART1(baudRate, mode, options); s = serialUART1(baudRate, mode, options);
#ifdef USE_USART2 #ifdef USE_UART2
} else if (USARTx == USART2) { } else if (USARTx == USART2) {
s = serialUSART2(baudRate, mode, options); s = serialUART2(baudRate, mode, options);
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
} else if (USARTx == USART3) { } else if (USARTx == USART3) {
s = serialUSART3(baudRate, mode, options); s = serialUART3(baudRate, mode, options);
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
} else if (USARTx == UART4) { } else if (USARTx == UART4) {
s = serialUSART4(baudRate, mode, options); s = serialUART4(baudRate, mode, options);
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
} else if (USARTx == UART5) { } else if (USARTx == UART5) {
s = serialUSART5(baudRate, mode, options); s = serialUART5(baudRate, mode, options);
#endif #endif
#ifdef USE_USART6 #ifdef USE_UART6
} else if (USARTx == USART6) { } else if (USARTx == USART6) {
s = serialUSART6(baudRate, mode, options); s = serialUART6(baudRate, mode, options);
#endif #endif
} else { } else {

View file

@ -23,10 +23,10 @@ extern const struct serialPortVTable uartVTable[];
void uartStartTxDMA(uartPort_t *s); void uartStartTxDMA(uartPort_t *s);
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options); uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options);
uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t options); uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options);
uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t options); uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options);
uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t options); uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options);
uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t options); uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options);
uartPort_t *serialUSART6(uint32_t baudRate, portMode_t mode, portOptions_t options); uartPort_t *serialUART6(uint32_t baudRate, portMode_t mode, portOptions_t options);

View file

@ -24,38 +24,32 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <platform.h> #include <platform.h>
#include "system.h" #include "system.h"
#include "gpio.h" #include "io.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "rcc.h"
#include "serial.h" #include "serial.h"
#include "serial_uart.h" #include "serial_uart.h"
#include "serial_uart_impl.h" #include "serial_uart_impl.h"
#ifdef USE_USART1 #ifdef USE_UART1
static uartPort_t uartPort1; static uartPort_t uartPort1;
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
static uartPort_t uartPort2; static uartPort_t uartPort2;
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
static uartPort_t uartPort3; static uartPort_t uartPort3;
#endif #endif
// Using RX DMA disables the use of receive callbacks void uartIrqCallback(uartPort_t *s)
#define USE_USART1_RX_DMA
#if defined(CC3D) // FIXME move board specific code to target.h files.
#undef USE_USART1_RX_DMA
#endif
void usartIrqCallback(uartPort_t *s)
{ {
uint16_t SR = s->USARTx->SR; uint16_t SR = s->USARTx->SR;
@ -82,15 +76,26 @@ void usartIrqCallback(uartPort_t *s)
} }
} }
#ifdef USE_USART1 // USART1 Tx DMA Handler
void uart_tx_dma_IRQHandler(dmaChannelDescriptor_t* descriptor)
{
uartPort_t *s = (uartPort_t*)(descriptor->userParam);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
DMA_Cmd(descriptor->channel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
#ifdef USE_UART1
// USART1 - Telemetry (RX/TX by DMA) // USART1 - Telemetry (RX/TX by DMA)
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE]; static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE];
static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE]; static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE];
gpio_config_t gpio;
NVIC_InitTypeDef NVIC_InitStructure;
s = &uartPort1; s = &uartPort1;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -105,46 +110,40 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->USARTx = USART1; s->USARTx = USART1;
#ifdef USE_USART1_RX_DMA #ifdef USE_UART1_RX_DMA
s->rxDMAChannel = DMA1_Channel5; s->rxDMAChannel = DMA1_Channel5;
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
#endif #endif
s->txDMAChannel = DMA1_Channel4; s->txDMAChannel = DMA1_Channel4;
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_ClockCmd(RCC_APB2(USART1), ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
// USART1_TX PA9 // UART1_TX PA9
// USART1_RX PA10 // UART1_RX PA10
gpio.speed = Speed_2MHz;
gpio.pin = Pin_9;
if (options & SERIAL_BIDIR) { if (options & SERIAL_BIDIR) {
gpio.mode = Mode_AF_OD; IOInit(IOGetByTag(IO_TAG(PA9)), OWNER_SERIAL, RESOURCE_UART_TXRX, 1);
gpioInit(GPIOA, &gpio); IOConfigGPIO(IOGetByTag(IO_TAG(PA9)), IOCFG_AF_OD);
} else { } else {
if (mode & MODE_TX) { if (mode & MODE_TX) {
gpio.mode = Mode_AF_PP; IOInit(IOGetByTag(IO_TAG(PA9)), OWNER_SERIAL, RESOURCE_UART_TX, 1);
gpioInit(GPIOA, &gpio); IOConfigGPIO(IOGetByTag(IO_TAG(PA9)), IOCFG_AF_PP);
} }
if (mode & MODE_RX) { if (mode & MODE_RX) {
gpio.pin = Pin_10; IOInit(IOGetByTag(IO_TAG(PA10)), OWNER_SERIAL, RESOURCE_UART_RX, 1);
gpio.mode = Mode_IPU; IOConfigGPIO(IOGetByTag(IO_TAG(PA10)), IOCFG_IPU);
gpioInit(GPIOA, &gpio);
} }
} }
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; dmaSetHandler(DMA1_CH4_HANDLER, uart_tx_dma_IRQHandler, NVIC_PRIO_SERIALUART1_TXDMA, (uint32_t)&uartPort1);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#ifndef USE_USART1_RX_DMA #ifndef USE_UART1_RX_DMA
// RX/TX Interrupt // RX/TX Interrupt
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1);
@ -155,37 +154,23 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
return s; return s;
} }
// USART1 Tx DMA Handler
void DMA1_Channel4_IRQHandler(void)
{
uartPort_t *s = &uartPort1;
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_Cmd(s->txDMAChannel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
// USART1 Rx/Tx IRQ Handler // USART1 Rx/Tx IRQ Handler
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
uartPort_t *s = &uartPort1; uartPort_t *s = &uartPort1;
usartIrqCallback(s); uartIrqCallback(s);
} }
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
// USART2 - GPS or Spektrum or ?? (RX + TX by IRQ) // USART2 - GPS or Spektrum or ?? (RX + TX by IRQ)
uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE]; static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE];
static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE]; static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE];
gpio_config_t gpio;
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
s = &uartPort2; s = &uartPort2;
@ -203,27 +188,23 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_ClockCmd(RCC_APB1(USART2), ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
// USART2_TX PA2 // UART2_TX PA2
// USART2_RX PA3 // UART2_RX PA3
gpio.speed = Speed_2MHz;
gpio.pin = Pin_2;
if (options & SERIAL_BIDIR) { if (options & SERIAL_BIDIR) {
gpio.mode = Mode_AF_OD; IOInit(IOGetByTag(IO_TAG(PA2)), OWNER_SERIAL, RESOURCE_UART_TXRX, 2);
gpioInit(GPIOA, &gpio); IOConfigGPIO(IOGetByTag(IO_TAG(PA2)), IOCFG_AF_OD);
} else { } else {
if (mode & MODE_TX) { if (mode & MODE_TX) {
gpio.mode = Mode_AF_PP; IOInit(IOGetByTag(IO_TAG(PA2)), OWNER_SERIAL, RESOURCE_UART_TX, 2);
gpioInit(GPIOA, &gpio); IOConfigGPIO(IOGetByTag(IO_TAG(PA2)), IOCFG_AF_PP);
} }
if (mode & MODE_RX) { if (mode & MODE_RX) {
gpio.pin = Pin_3; IOInit(IOGetByTag(IO_TAG(PA3)), OWNER_SERIAL, RESOURCE_UART_RX, 2);
gpio.mode = Mode_IPU; IOConfigGPIO(IOGetByTag(IO_TAG(PA3)), IOCFG_IPU);
gpioInit(GPIOA, &gpio);
} }
} }
@ -242,19 +223,19 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
{ {
uartPort_t *s = &uartPort2; uartPort_t *s = &uartPort2;
usartIrqCallback(s); uartIrqCallback(s);
} }
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
// USART3 // USART3
uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE]; static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE];
static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE]; static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE];
gpio_config_t gpio;
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
s = &uartPort3; s = &uartPort3;
@ -272,29 +253,20 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
#ifdef USART3_APB1_PERIPHERALS RCC_ClockCmd(RCC_APB1(USART3), ENABLE);
RCC_APB1PeriphClockCmd(USART3_APB1_PERIPHERALS, ENABLE);
#endif
#ifdef USART3_APB2_PERIPHERALS
RCC_APB2PeriphClockCmd(USART3_APB2_PERIPHERALS, ENABLE);
#endif
gpio.speed = Speed_2MHz;
gpio.pin = USART3_TX_PIN;
if (options & SERIAL_BIDIR) { if (options & SERIAL_BIDIR) {
gpio.mode = Mode_AF_OD; IOInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), OWNER_SERIAL, RESOURCE_UART_TXRX, 3);
gpioInit(USART3_GPIO, &gpio); IOConfigGPIO(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOCFG_AF_OD);
} else { } else {
if (mode & MODE_TX) { if (mode & MODE_TX) {
gpio.mode = Mode_AF_PP; IOInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), OWNER_SERIAL, RESOURCE_UART_TX, 3);
gpioInit(USART3_GPIO, &gpio); IOConfigGPIO(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOCFG_AF_PP);
} }
if (mode & MODE_RX) { if (mode & MODE_RX) {
gpio.pin = USART3_RX_PIN; IOInit(IOGetByTag(IO_TAG(UART3_RX_PIN)), OWNER_SERIAL, RESOURCE_UART_RX, 3);
gpio.mode = Mode_IPU; IOConfigGPIO(IOGetByTag(IO_TAG(UART3_RX_PIN)), IOCFG_IPU);
gpioInit(USART3_GPIO, &gpio);
} }
} }
@ -312,6 +284,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
void USART3_IRQHandler(void) void USART3_IRQHandler(void)
{ {
uartPort_t *s = &uartPort3; uartPort_t *s = &uartPort3;
usartIrqCallback(s); uartIrqCallback(s);
} }
#endif #endif

View file

@ -25,94 +25,125 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <platform.h> #include <platform.h>
#include "system.h" #include "system.h"
#include "gpio.h" #include "io.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "rcc.h"
#include "serial.h" #include "serial.h"
#include "serial_uart.h" #include "serial_uart.h"
#include "serial_uart_impl.h" #include "serial_uart_impl.h"
// Using RX DMA disables the use of receive callbacks #ifdef USE_UART1
//#define USE_USART1_RX_DMA #ifndef UART1_TX_PIN
//#define USE_USART2_RX_DMA #define UART1_TX_PIN PA9 // PA9
//#define USE_USART2_TX_DMA #endif
//#define USE_USART3_RX_DMA #ifndef UART1_RX_PIN
//#define USE_USART3_TX_DMA #define UART1_RX_PIN PA10 // PA10
#endif
#ifndef UART1_GPIO
#define UART1_TX_PIN GPIO_Pin_9 // PA9
#define UART1_RX_PIN GPIO_Pin_10 // PA10
#define UART1_GPIO GPIOA
#define UART1_GPIO_AF GPIO_AF_7
#define UART1_TX_PINSOURCE GPIO_PinSource9
#define UART1_RX_PINSOURCE GPIO_PinSource10
#endif #endif
#ifndef UART2_GPIO #ifdef USE_UART2
#define UART2_TX_PIN GPIO_Pin_5 // PD5 #ifndef UART2_TX_PIN
#define UART2_RX_PIN GPIO_Pin_6 // PD6 #define UART2_TX_PIN PD5 // PD5
#define UART2_GPIO GPIOD #endif
#define UART2_GPIO_AF GPIO_AF_7 #ifndef UART2_RX_PIN
#define UART2_TX_PINSOURCE GPIO_PinSource5 #define UART2_RX_PIN PD6 // PD6
#define UART2_RX_PINSOURCE GPIO_PinSource6 #endif
#endif #endif
#ifndef UART3_GPIO #ifdef USE_UART3
#define UART3_TX_PIN GPIO_Pin_10 // PB10 (AF7) #ifndef UART3_TX_PIN
#define UART3_RX_PIN GPIO_Pin_11 // PB11 (AF7) #define UART3_TX_PIN PB10 // PB10 (AF7)
#define UART3_GPIO_AF GPIO_AF_7 #endif
#define UART3_GPIO GPIOB #ifndef UART3_RX_PIN
#define UART3_TX_PINSOURCE GPIO_PinSource10 #define UART3_RX_PIN PB11 // PB11 (AF7)
#define UART3_RX_PINSOURCE GPIO_PinSource11 #endif
#endif #endif
#ifndef UART4_GPIO #ifdef USE_UART4
#define UART4_TX_PIN GPIO_Pin_10 // PC10 (AF5) #ifndef UART4_TX_PIN
#define UART4_RX_PIN GPIO_Pin_11 // PC11 (AF5) #define UART4_TX_PIN PC10 // PC10 (AF5)
#define UART4_GPIO_AF GPIO_AF_5 #endif
#define UART4_GPIO GPIOC #ifndef UART4_RX_PIN
#define UART4_TX_PINSOURCE GPIO_PinSource10 #define UART4_RX_PIN PC11 // PC11 (AF5)
#define UART4_RX_PINSOURCE GPIO_PinSource11 #endif
#endif #endif
#ifndef UART5_GPIO // The real UART5_RX is on PD2, no board is using. #ifdef USE_UART5
#define UART5_TX_PIN GPIO_Pin_12 // PC12 (AF5) #ifndef UART5_TX_PIN // The real UART5_RX is on PD2, no board is using.
#define UART5_RX_PIN GPIO_Pin_12 // PC12 (AF5) #define UART5_TX_PIN PC12 // PC12 (AF5)
#define UART5_GPIO_AF GPIO_AF_5 #endif
#define UART5_GPIO GPIOC #ifndef UART5_RX_PIN
#define UART5_TX_PINSOURCE GPIO_PinSource12 #define UART5_RX_PIN PC12 // PC12 (AF5)
#define UART5_RX_PINSOURCE GPIO_PinSource12 #endif
#endif #endif
#ifdef USE_USART1 #ifdef USE_UART1
static uartPort_t uartPort1; static uartPort_t uartPort1;
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
static uartPort_t uartPort2; static uartPort_t uartPort2;
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
static uartPort_t uartPort3; static uartPort_t uartPort3;
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
static uartPort_t uartPort4; static uartPort_t uartPort4;
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
static uartPort_t uartPort5; static uartPort_t uartPort5;
#endif #endif
#ifdef USE_USART1 static void handleUsartTxDma(dmaChannelDescriptor_t* descriptor)
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) {
uartPort_t *s = (uartPort_t*)(descriptor->userParam);
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
DMA_Cmd(descriptor->channel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
void serialUARTInit(IO_t tx, IO_t rx, portMode_t mode, portOptions_t options, uint8_t af, uint8_t index)
{
if (options & SERIAL_BIDIR) {
ioConfig_t ioCfg = IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz,
(options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD,
(options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP
);
IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TXRX, index);
IOConfigGPIOAF(tx, ioCfg, af);
if (!(options & SERIAL_INVERTED))
IOLo(tx); // OpenDrain output should be inactive
} else {
ioConfig_t ioCfg = IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP);
if (mode & MODE_TX) {
IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TX, index);
IOConfigGPIOAF(tx, ioCfg, af);
}
if (mode & MODE_RX) {
IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TX, index);
IOConfigGPIOAF(rx, ioCfg, af);
}
}
}
#ifdef USE_UART1
uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE]; static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE];
static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE]; static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort1; s = &uartPort1;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -124,7 +155,7 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->port.rxBufferSize = UART1_RX_BUFFER_SIZE; s->port.rxBufferSize = UART1_RX_BUFFER_SIZE;
s->port.txBufferSize = UART1_TX_BUFFER_SIZE; s->port.txBufferSize = UART1_TX_BUFFER_SIZE;
#ifdef USE_USART1_RX_DMA #ifdef USE_UART1_RX_DMA
s->rxDMAChannel = DMA1_Channel5; s->rxDMAChannel = DMA1_Channel5;
#endif #endif
s->txDMAChannel = DMA1_Channel4; s->txDMAChannel = DMA1_Channel4;
@ -134,43 +165,16 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_ClockCmd(RCC_APB2(USART1), ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; serialUARTInit(IOGetByTag(IO_TAG(UART1_TX_PIN)), IOGetByTag(IO_TAG(UART1_RX_PIN)), mode, options, GPIO_AF_7, 1);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP;
if (options & SERIAL_BIDIR) { dmaSetHandler(DMA1_CH4_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART1_TXDMA, (uint32_t)&uartPort1);
GPIO_InitStructure.GPIO_Pin = UART1_TX_PIN;
GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD;
GPIO_PinAFConfig(UART1_GPIO, UART1_TX_PINSOURCE, UART1_GPIO_AF);
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
if(!(options & SERIAL_INVERTED))
GPIO_SetBits(UART1_GPIO, UART1_TX_PIN); // OpenDrain output should be inactive
} else {
if (mode & MODE_TX) {
GPIO_InitStructure.GPIO_Pin = UART1_TX_PIN;
GPIO_PinAFConfig(UART1_GPIO, UART1_TX_PINSOURCE, UART1_GPIO_AF);
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
}
if (mode & MODE_RX) { #ifndef USE_UART1_RX_DMA
GPIO_InitStructure.GPIO_Pin = UART1_RX_PIN; NVIC_InitTypeDef NVIC_InitStructure;
GPIO_PinAFConfig(UART1_GPIO, UART1_RX_PINSOURCE, UART1_GPIO_AF);
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
}
}
// DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#ifndef USE_USART1_RX_DMA
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_RXDMA); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_RXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_RXDMA);
@ -182,14 +186,12 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE]; static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE];
static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE]; static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort2; s = &uartPort2;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -203,57 +205,31 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->USARTx = USART2; s->USARTx = USART2;
#ifdef USE_USART2_RX_DMA #ifdef USE_UART2_RX_DMA
s->rxDMAChannel = DMA1_Channel6; s->rxDMAChannel = DMA1_Channel6;
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
#endif #endif
#ifdef USE_USART2_TX_DMA #ifdef USE_UART2_TX_DMA
s->txDMAChannel = DMA1_Channel7; s->txDMAChannel = DMA1_Channel7;
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
#endif #endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_ClockCmd(RCC_APB1(USART2), ENABLE);
#if defined(USE_USART2_TX_DMA) || defined(USE_USART2_RX_DMA) #if defined(USE_UART2_TX_DMA) || defined(USE_UART2_RX_DMA)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
#endif #endif
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; serialUARTInit(IOGetByTag(IO_TAG(UART2_TX_PIN)), IOGetByTag(IO_TAG(UART2_RX_PIN)), mode, options, GPIO_AF_7, 2);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP;
if (options & SERIAL_BIDIR) { #ifdef USE_UART2_TX_DMA
GPIO_InitStructure.GPIO_Pin = UART2_TX_PIN;
GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD;
GPIO_PinAFConfig(UART2_GPIO, UART2_TX_PINSOURCE, UART2_GPIO_AF);
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
if(!(options & SERIAL_INVERTED))
GPIO_SetBits(UART2_GPIO, UART2_TX_PIN); // OpenDrain output should be inactive
} else {
if (mode & MODE_TX) {
GPIO_InitStructure.GPIO_Pin = UART2_TX_PIN;
GPIO_PinAFConfig(UART2_GPIO, UART2_TX_PINSOURCE, UART2_GPIO_AF);
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
}
if (mode & MODE_RX) {
GPIO_InitStructure.GPIO_Pin = UART2_RX_PIN;
GPIO_PinAFConfig(UART2_GPIO, UART2_RX_PINSOURCE, UART2_GPIO_AF);
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
}
}
#ifdef USE_USART2_TX_DMA
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; dmaSetHandler(DMA1_CH7_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART2_TXDMA, (uint32_t)&uartPort2);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif #endif
#ifndef USE_USART2_RX_DMA #ifndef USE_UART2_RX_DMA
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_RXDMA); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_RXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_RXDMA);
@ -265,14 +241,12 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE]; static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE];
static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE]; static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort3; s = &uartPort3;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -286,57 +260,31 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->USARTx = USART3; s->USARTx = USART3;
#ifdef USE_USART3_RX_DMA #ifdef USE_UART3_RX_DMA
s->rxDMAChannel = DMA1_Channel3; s->rxDMAChannel = DMA1_Channel3;
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR; s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
#endif #endif
#ifdef USE_USART3_TX_DMA #ifdef USE_UART3_TX_DMA
s->txDMAChannel = DMA1_Channel2; s->txDMAChannel = DMA1_Channel2;
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR; s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
#endif #endif
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_ClockCmd(RCC_APB1(USART3), ENABLE);
#if defined(USE_USART3_TX_DMA) || defined(USE_USART3_RX_DMA) #if defined(USE_UART3_TX_DMA) || defined(USE_UART3_RX_DMA)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_AHBClockCmd(RCC_AHB(DMA1), ENABLE);
#endif #endif
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; serialUARTInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOGetByTag(IO_TAG(UART3_RX_PIN)), mode, options, GPIO_AF_7, 3);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP;
if (options & SERIAL_BIDIR) { #ifdef USE_UART3_TX_DMA
GPIO_InitStructure.GPIO_Pin = UART3_TX_PIN;
GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD;
GPIO_PinAFConfig(UART3_GPIO, UART3_TX_PINSOURCE, UART3_GPIO_AF);
GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
if(!(options & SERIAL_INVERTED))
GPIO_SetBits(UART3_GPIO, UART3_TX_PIN); // OpenDrain output should be inactive
} else {
if (mode & MODE_TX) {
GPIO_InitStructure.GPIO_Pin = UART3_TX_PIN;
GPIO_PinAFConfig(UART3_GPIO, UART3_TX_PINSOURCE, UART3_GPIO_AF);
GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
}
if (mode & MODE_RX) {
GPIO_InitStructure.GPIO_Pin = UART3_RX_PIN;
GPIO_PinAFConfig(UART3_GPIO, UART3_RX_PINSOURCE, UART3_GPIO_AF);
GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
}
}
#ifdef USE_USART3_TX_DMA
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn; dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, (uint32_t)&uartPort3);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_TXDMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif #endif
#ifndef USE_USART3_RX_DMA #ifndef USE_UART3_RX_DMA
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_RXDMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_RXDMA);
@ -348,14 +296,13 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx4Buffer[UART4_RX_BUFFER_SIZE]; static volatile uint8_t rx4Buffer[UART4_RX_BUFFER_SIZE];
static volatile uint8_t tx4Buffer[UART4_TX_BUFFER_SIZE]; static volatile uint8_t tx4Buffer[UART4_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort4; s = &uartPort4;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -369,33 +316,9 @@ uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->USARTx = UART4; s->USARTx = UART4;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); RCC_ClockCmd(RCC_APB1(UART4), ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; serialUARTInit(IOGetByTag(IO_TAG(UART4_TX_PIN)), IOGetByTag(IO_TAG(UART4_RX_PIN)), mode, options, GPIO_AF_5, 4);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP;
if (options & SERIAL_BIDIR) {
GPIO_InitStructure.GPIO_Pin = UART4_TX_PIN;
GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD;
GPIO_PinAFConfig(UART4_GPIO, UART4_TX_PINSOURCE, UART4_GPIO_AF);
GPIO_Init(UART4_GPIO, &GPIO_InitStructure);
if(!(options & SERIAL_INVERTED))
GPIO_SetBits(UART4_GPIO, UART4_TX_PIN); // OpenDrain output should be inactive
} else {
if (mode & MODE_TX) {
GPIO_InitStructure.GPIO_Pin = UART4_TX_PIN;
GPIO_PinAFConfig(UART4_GPIO, UART4_TX_PINSOURCE, UART4_GPIO_AF);
GPIO_Init(UART4_GPIO, &GPIO_InitStructure);
}
if (mode & MODE_RX) {
GPIO_InitStructure.GPIO_Pin = UART4_RX_PIN;
GPIO_PinAFConfig(UART4_GPIO, UART4_RX_PINSOURCE, UART4_GPIO_AF);
GPIO_Init(UART4_GPIO, &GPIO_InitStructure);
}
}
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART4); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART4);
@ -407,14 +330,13 @@ uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
static volatile uint8_t rx5Buffer[UART5_RX_BUFFER_SIZE]; static volatile uint8_t rx5Buffer[UART5_RX_BUFFER_SIZE];
static volatile uint8_t tx5Buffer[UART5_TX_BUFFER_SIZE]; static volatile uint8_t tx5Buffer[UART5_TX_BUFFER_SIZE];
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
s = &uartPort5; s = &uartPort5;
s->port.vTable = uartVTable; s->port.vTable = uartVTable;
@ -428,33 +350,9 @@ uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t optio
s->USARTx = UART5; s->USARTx = UART5;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); RCC_ClockCmd(RCC_APB1(UART5), ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; serialUARTInit(IOGetByTag(IO_TAG(UART5_TX_PIN)), IOGetByTag(IO_TAG(UART5_RX_PIN)), mode, options, GPIO_AF_5, 5);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP;
if (options & SERIAL_BIDIR) {
GPIO_InitStructure.GPIO_Pin = UART5_TX_PIN;
GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD;
GPIO_PinAFConfig(UART5_GPIO, UART5_TX_PINSOURCE, UART5_GPIO_AF);
GPIO_Init(UART5_GPIO, &GPIO_InitStructure);
if(!(options & SERIAL_INVERTED))
GPIO_SetBits(UART5_GPIO, UART5_TX_PIN); // OpenDrain output should be inactive
} else {
if (mode & MODE_TX) {
GPIO_InitStructure.GPIO_Pin = UART5_TX_PIN;
GPIO_PinAFConfig(UART5_GPIO, UART5_TX_PINSOURCE, UART5_GPIO_AF);
GPIO_Init(UART5_GPIO, &GPIO_InitStructure);
}
if (mode & MODE_RX) {
GPIO_InitStructure.GPIO_Pin = UART5_RX_PIN;
GPIO_PinAFConfig(UART5_GPIO, UART5_RX_PINSOURCE, UART5_GPIO_AF);
GPIO_Init(UART5_GPIO, &GPIO_InitStructure);
}
}
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART5); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART5);
@ -466,48 +364,6 @@ uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t optio
} }
#endif #endif
static void handleUsartTxDma(uartPort_t *s)
{
DMA_Cmd(s->txDMAChannel, DISABLE);
if (s->port.txBufferHead != s->port.txBufferTail)
uartStartTxDMA(s);
else
s->txDMAEmpty = true;
}
// USART1 Tx DMA Handler
void DMA1_Channel4_IRQHandler(void)
{
uartPort_t *s = &uartPort1;
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_Cmd(DMA1_Channel4, DISABLE);
handleUsartTxDma(s);
}
#ifdef USE_USART2_TX_DMA
// USART2 Tx DMA Handler
void DMA1_Channel7_IRQHandler(void)
{
uartPort_t *s = &uartPort2;
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_Cmd(DMA1_Channel7, DISABLE);
handleUsartTxDma(s);
}
#endif
// USART3 Tx DMA Handler
#ifdef USE_USART3_TX_DMA
void DMA1_Channel2_IRQHandler(void)
{
uartPort_t *s = &uartPort3;
DMA_ClearITPendingBit(DMA1_IT_TC2);
DMA_Cmd(DMA1_Channel2, DISABLE);
handleUsartTxDma(s);
}
#endif
void usartIrqHandler(uartPort_t *s) void usartIrqHandler(uartPort_t *s)
{ {
uint32_t ISR = s->USARTx->ISR; uint32_t ISR = s->USARTx->ISR;
@ -540,7 +396,7 @@ void usartIrqHandler(uartPort_t *s)
} }
} }
#ifdef USE_USART1 #ifdef USE_UART1
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
uartPort_t *s = &uartPort1; uartPort_t *s = &uartPort1;
@ -549,7 +405,7 @@ void USART1_IRQHandler(void)
} }
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
{ {
uartPort_t *s = &uartPort2; uartPort_t *s = &uartPort2;
@ -558,7 +414,7 @@ void USART2_IRQHandler(void)
} }
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
void USART3_IRQHandler(void) void USART3_IRQHandler(void)
{ {
uartPort_t *s = &uartPort3; uartPort_t *s = &uartPort3;
@ -567,7 +423,7 @@ void USART3_IRQHandler(void)
} }
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
void UART4_IRQHandler(void) void UART4_IRQHandler(void)
{ {
uartPort_t *s = &uartPort4; uartPort_t *s = &uartPort4;
@ -576,7 +432,7 @@ void UART4_IRQHandler(void)
} }
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
void UART5_IRQHandler(void) void UART5_IRQHandler(void)
{ {
uartPort_t *s = &uartPort5; uartPort_t *s = &uartPort5;

View file

@ -17,7 +17,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
@ -25,19 +24,12 @@
#include "io.h" #include "io.h"
#include "rcc.h" #include "rcc.h"
#include "nvic.h" #include "nvic.h"
#include "dma.h"
#include "serial.h" #include "serial.h"
#include "serial_uart.h" #include "serial_uart.h"
#include "serial_uart_impl.h" #include "serial_uart_impl.h"
// Using RX DMA disables the use of receive callbacks
//#define USE_USART1_RX_DMA
//#define USE_USART2_RX_DMA
//#define USE_USART3_RX_DMA
//#define USE_USART4_RX_DMA
//#define USE_USART5_RX_DMA
//#define USE_USART6_RX_DMA
#define UART_RX_BUFFER_SIZE UART1_RX_BUFFER_SIZE #define UART_RX_BUFFER_SIZE UART1_RX_BUFFER_SIZE
#define UART_TX_BUFFER_SIZE UART1_TX_BUFFER_SIZE #define UART_TX_BUFFER_SIZE UART1_TX_BUFFER_SIZE
@ -71,138 +63,138 @@ typedef struct uartDevice_s {
} uartDevice_t; } uartDevice_t;
//static uartPort_t uartPort[MAX_UARTS]; //static uartPort_t uartPort[MAX_UARTS];
#ifdef USE_USART1 #ifdef USE_UART1
static uartDevice_t uart1 = static uartDevice_t uart1 =
{ {
.DMAChannel = DMA_Channel_4, .DMAChannel = DMA_Channel_4,
.txDMAStream = DMA2_Stream7, .txDMAStream = DMA2_Stream7,
#ifdef USE_USART1_RX_DMA #ifdef USE_UART1_RX_DMA
.rxDMAStream = DMA2_Stream5, .rxDMAStream = DMA2_Stream5,
#endif #endif
.dev = USART1, .dev = USART1,
.rx = IO_TAG(USART1_RX_PIN), .rx = IO_TAG(UART1_RX_PIN),
.tx = IO_TAG(USART1_TX_PIN), .tx = IO_TAG(UART1_TX_PIN),
.af = GPIO_AF_USART1, .af = GPIO_AF_USART1,
#ifdef USART1_AHB1_PERIPHERALS #ifdef UART1_AHB1_PERIPHERALS
.rcc_ahb1 = USART1_AHB1_PERIPHERALS, .rcc_ahb1 = UART1_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb2 = RCC_APB2(USART1), .rcc_apb2 = RCC_APB2(USART1),
.txIrq = DMA2_Stream7_IRQn, .txIrq = DMA2_ST7_HANDLER,
.rxIrq = USART1_IRQn, .rxIrq = USART1_IRQn,
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA, .txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART1 .rxPriority = NVIC_PRIO_SERIALUART1
}; };
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
static uartDevice_t uart2 = static uartDevice_t uart2 =
{ {
.DMAChannel = DMA_Channel_4, .DMAChannel = DMA_Channel_4,
#ifdef USE_USART2_RX_DMA #ifdef USE_UART2_RX_DMA
.rxDMAStream = DMA1_Stream5, .rxDMAStream = DMA1_Stream5,
#endif #endif
.txDMAStream = DMA1_Stream6, .txDMAStream = DMA1_Stream6,
.dev = USART2, .dev = USART2,
.rx = IO_TAG(USART2_RX_PIN), .rx = IO_TAG(UART2_RX_PIN),
.tx = IO_TAG(USART2_TX_PIN), .tx = IO_TAG(UART2_TX_PIN),
.af = GPIO_AF_USART2, .af = GPIO_AF_USART2,
#ifdef USART2_AHB1_PERIPHERALS #ifdef UART2_AHB1_PERIPHERALS
.rcc_ahb1 = USART2_AHB1_PERIPHERALS, .rcc_ahb1 = UART2_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(USART2), .rcc_apb1 = RCC_APB1(USART2),
.txIrq = DMA1_Stream6_IRQn, .txIrq = DMA1_ST6_HANDLER,
.rxIrq = USART2_IRQn, .rxIrq = USART2_IRQn,
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA, .txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART2 .rxPriority = NVIC_PRIO_SERIALUART2
}; };
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
static uartDevice_t uart3 = static uartDevice_t uart3 =
{ {
.DMAChannel = DMA_Channel_4, .DMAChannel = DMA_Channel_4,
#ifdef USE_USART3_RX_DMA #ifdef USE_UART3_RX_DMA
.rxDMAStream = DMA1_Stream1, .rxDMAStream = DMA1_Stream1,
#endif #endif
.txDMAStream = DMA1_Stream3, .txDMAStream = DMA1_Stream3,
.dev = USART3, .dev = USART3,
.rx = IO_TAG(USART3_RX_PIN), .rx = IO_TAG(UART3_RX_PIN),
.tx = IO_TAG(USART3_TX_PIN), .tx = IO_TAG(UART3_TX_PIN),
.af = GPIO_AF_USART3, .af = GPIO_AF_USART3,
#ifdef USART3_AHB1_PERIPHERALS #ifdef UART3_AHB1_PERIPHERALS
.rcc_ahb1 = USART3_AHB1_PERIPHERALS, .rcc_ahb1 = UART3_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(USART3), .rcc_apb1 = RCC_APB1(USART3),
.txIrq = DMA1_Stream3_IRQn, .txIrq = DMA1_ST3_HANDLER,
.rxIrq = USART3_IRQn, .rxIrq = USART3_IRQn,
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA, .txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART3 .rxPriority = NVIC_PRIO_SERIALUART3
}; };
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
static uartDevice_t uart4 = static uartDevice_t uart4 =
{ {
.DMAChannel = DMA_Channel_4, .DMAChannel = DMA_Channel_4,
#ifdef USE_USART1_RX_DMA #ifdef USE_UART1_RX_DMA
.rxDMAStream = DMA1_Stream2, .rxDMAStream = DMA1_Stream2,
#endif #endif
.txDMAStream = DMA1_Stream4, .txDMAStream = DMA1_Stream4,
.dev = UART4, .dev = UART4,
.rx = IO_TAG(USART4_RX_PIN), .rx = IO_TAG(UART4_RX_PIN),
.tx = IO_TAG(USART4_TX_PIN), .tx = IO_TAG(UART4_TX_PIN),
.af = GPIO_AF_UART4, .af = GPIO_AF_UART4,
#ifdef USART4_AHB1_PERIPHERALS #ifdef UART4_AHB1_PERIPHERALS
.rcc_ahb1 = USART4_AHB1_PERIPHERALS, .rcc_ahb1 = UART4_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(UART4), .rcc_apb1 = RCC_APB1(UART4),
.txIrq = DMA1_Stream4_IRQn, .txIrq = DMA1_ST4_HANDLER,
.rxIrq = UART4_IRQn, .rxIrq = UART4_IRQn,
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA, .txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART4 .rxPriority = NVIC_PRIO_SERIALUART4
}; };
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
static uartDevice_t uart5 = static uartDevice_t uart5 =
{ {
.DMAChannel = DMA_Channel_4, .DMAChannel = DMA_Channel_4,
#ifdef USE_USART1_RX_DMA #ifdef USE_UART1_RX_DMA
.rxDMAStream = DMA1_Stream0, .rxDMAStream = DMA1_Stream0,
#endif #endif
.txDMAStream = DMA2_Stream7, .txDMAStream = DMA2_Stream7,
.dev = UART5, .dev = UART5,
.rx = IO_TAG(USART5_RX_PIN), .rx = IO_TAG(UART5_RX_PIN),
.tx = IO_TAG(USART5_TX_PIN), .tx = IO_TAG(UART5_TX_PIN),
.af = GPIO_AF_UART5, .af = GPIO_AF_UART5,
#ifdef USART5_AHB1_PERIPHERALS #ifdef UART5_AHB1_PERIPHERALS
.rcc_ahb1 = USART5_AHB1_PERIPHERALS, .rcc_ahb1 = UART5_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb1 = RCC_APB1(UART5), .rcc_apb1 = RCC_APB1(UART5),
.txIrq = DMA2_Stream7_IRQn, .txIrq = DMA2_ST7_HANDLER,
.rxIrq = UART5_IRQn, .rxIrq = UART5_IRQn,
.txPriority = NVIC_PRIO_SERIALUART5_TXDMA, .txPriority = NVIC_PRIO_SERIALUART5_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART5 .rxPriority = NVIC_PRIO_SERIALUART5
}; };
#endif #endif
#ifdef USE_USART6 #ifdef USE_UART6
static uartDevice_t uart6 = static uartDevice_t uart6 =
{ {
.DMAChannel = DMA_Channel_5, .DMAChannel = DMA_Channel_5,
#ifdef USE_USART6_RX_DMA #ifdef USE_UART6_RX_DMA
.rxDMAStream = DMA2_Stream1, .rxDMAStream = DMA2_Stream1,
#endif #endif
.txDMAStream = DMA2_Stream6, .txDMAStream = DMA2_Stream6,
.dev = USART6, .dev = USART6,
.rx = IO_TAG(USART6_RX_PIN), .rx = IO_TAG(UART6_RX_PIN),
.tx = IO_TAG(USART6_TX_PIN), .tx = IO_TAG(UART6_TX_PIN),
.af = GPIO_AF_USART6, .af = GPIO_AF_USART6,
#ifdef USART6_AHB1_PERIPHERALS #ifdef UART6_AHB1_PERIPHERALS
.rcc_ahb1 = USART6_AHB1_PERIPHERALS, .rcc_ahb1 = UART6_AHB1_PERIPHERALS,
#endif #endif
.rcc_apb2 = RCC_APB2(USART6), .rcc_apb2 = RCC_APB2(USART6),
.txIrq = DMA2_Stream6_IRQn, .txIrq = DMA2_ST6_HANDLER,
.rxIrq = USART6_IRQn, .rxIrq = USART6_IRQn,
.txPriority = NVIC_PRIO_SERIALUART6_TXDMA, .txPriority = NVIC_PRIO_SERIALUART6_TXDMA,
.rxPriority = NVIC_PRIO_SERIALUART6 .rxPriority = NVIC_PRIO_SERIALUART6
@ -210,39 +202,39 @@ static uartDevice_t uart6 =
#endif #endif
static uartDevice_t* uartHardwareMap[] = { static uartDevice_t* uartHardwareMap[] = {
#ifdef USE_USART1 #ifdef USE_UART1
&uart1, &uart1,
#else #else
NULL, NULL,
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
&uart2, &uart2,
#else #else
NULL, NULL,
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
&uart3, &uart3,
#else #else
NULL, NULL,
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
&uart4, &uart4,
#else #else
NULL, NULL,
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
&uart5, &uart5,
#else #else
NULL, NULL,
#endif #endif
#ifdef USE_USART6 #ifdef USE_UART6
&uart6, &uart6,
#else #else
NULL, NULL,
#endif #endif
}; };
void usartIrqHandler(uartPort_t *s) void uartIrqHandler(uartPort_t *s)
{ {
if (!s->rxDMAStream && (USART_GetITStatus(s->USARTx, USART_IT_RXNE) == SET)) { if (!s->rxDMAStream && (USART_GetITStatus(s->USARTx, USART_IT_RXNE) == SET)) {
if (s->port.callback) { if (s->port.callback) {
@ -278,7 +270,30 @@ static void handleUsartTxDma(uartPort_t *s)
s->txDMAEmpty = true; s->txDMAEmpty = true;
} }
uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, portOptions_t options) void dmaIRQHandler(dmaChannelDescriptor_t* descriptor)
{
uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port);
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
DMA_CLEAR_FLAG(descriptor, DMA_IT_HTIF);
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_FEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_FEIF);
}
handleUsartTxDma(s);
}
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_TEIF);
}
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_DMEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_DMEIF);
}
}
uartPort_t *serialUART(UARTDevice device, uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
uartPort_t *s; uartPort_t *s;
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
@ -320,27 +335,23 @@ uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, p
RCC_AHB1PeriphClockCmd(uart->rcc_ahb1, ENABLE); RCC_AHB1PeriphClockCmd(uart->rcc_ahb1, ENABLE);
if (options & SERIAL_BIDIR) { if (options & SERIAL_BIDIR) {
IOInit(tx, OWNER_SERIAL_TX, RESOURCE_USART); IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TXRX, RESOURCE_INDEX(device));
IOConfigGPIOAF(tx, IOCFG_AF_OD, uart->af); IOConfigGPIOAF(tx, IOCFG_AF_OD, uart->af);
} }
else { else {
if (mode & MODE_TX) { if (mode & MODE_TX) {
IOInit(tx, OWNER_SERIAL_TX, RESOURCE_USART); IOInit(tx, OWNER_SERIAL, RESOURCE_UART_TX, RESOURCE_INDEX(device));
IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af); IOConfigGPIOAF(tx, IOCFG_AF_PP, uart->af);
} }
if (mode & MODE_RX) { if (mode & MODE_RX) {
IOInit(rx, OWNER_SERIAL_RX, RESOURCE_USART); IOInit(rx, OWNER_SERIAL, RESOURCE_UART_RX, RESOURCE_INDEX(device));
IOConfigGPIOAF(rx, IOCFG_AF_PP, uart->af); IOConfigGPIOAF(rx, IOCFG_AF_PP, uart->af);
} }
} }
// DMA TX Interrupt // DMA TX Interrupt
NVIC_InitStructure.NVIC_IRQChannel = uart->txIrq; dmaSetHandler(uart->txIrq, dmaIRQHandler, uart->txPriority, (uint32_t)uart);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(uart->txPriority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(uart->txPriority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
if (!(s->rxDMAChannel)) { if (!(s->rxDMAChannel)) {
NVIC_InitStructure.NVIC_IRQChannel = uart->rxIrq; NVIC_InitStructure.NVIC_IRQChannel = uart->rxIrq;
@ -353,230 +364,86 @@ uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, p
return s; return s;
} }
#ifdef USE_USART1 #ifdef USE_UART1
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
return serialUSART(UARTDEV_1, baudRate, mode, options); return serialUART(UARTDEV_1, baudRate, mode, options);
}
// USART1 Tx DMA Handler
void DMA2_Stream7_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF7))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF7);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF7);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF7);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF7);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF7);
}
} }
// USART1 Rx/Tx IRQ Handler // USART1 Rx/Tx IRQ Handler
void USART1_IRQHandler(void) void USART1_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
usartIrqHandler(s); uartIrqHandler(s);
} }
#endif #endif
#ifdef USE_USART2 #ifdef USE_UART2
// USART2 - GPS or Spektrum or ?? (RX + TX by IRQ) // USART2 - GPS or Spektrum or ?? (RX + TX by IRQ)
uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
return serialUSART(UARTDEV_2, baudRate, mode, options); return serialUART(UARTDEV_2, baudRate, mode, options);
}
// USART2 Tx DMA Handler
void DMA1_Stream6_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF6))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF6);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF6);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF6);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF6);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF6);
}
} }
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
usartIrqHandler(s); uartIrqHandler(s);
} }
#endif #endif
#ifdef USE_USART3 #ifdef USE_UART3
// USART3 // USART3
uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
return serialUSART(UARTDEV_3, baudRate, mode, options); return serialUART(UARTDEV_3, baudRate, mode, options);
}
// USART3 Tx DMA Handler
void DMA1_Stream3_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF3))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF3);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF3);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF3)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF3);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF3)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF3);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF3)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF3);
}
} }
void USART3_IRQHandler(void) void USART3_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
usartIrqHandler(s); uartIrqHandler(s);
} }
#endif #endif
#ifdef USE_USART4 #ifdef USE_UART4
// USART4 // USART4
uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
return serialUSART(UARTDEV_4, baudRate, mode, options); return serialUART(UARTDEV_4, baudRate, mode, options);
}
// USART4 Tx DMA Handler
void DMA1_Stream4_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF4))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF4);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF4);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF4)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF4);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF4)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF4);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF4)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF4);
}
} }
void UART4_IRQHandler(void) void UART4_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
usartIrqHandler(s); uartIrqHandler(s);
} }
#endif #endif
#ifdef USE_USART5 #ifdef USE_UART5
// USART5 // USART5
uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
return serialUSART(UARTDEV_5, baudRate, mode, options); return serialUART(UARTDEV_5, baudRate, mode, options);
}
// USART5 Tx DMA Handler
void DMA1_Stream7_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF7))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF7);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF7);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF7);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF7);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF7)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF7);
}
} }
void UART5_IRQHandler(void) void UART5_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
usartIrqHandler(s); uartIrqHandler(s);
} }
#endif #endif
#ifdef USE_USART6 #ifdef USE_UART6
// USART6 // USART6
uartPort_t *serialUSART6(uint32_t baudRate, portMode_t mode, portOptions_t options) uartPort_t *serialUART6(uint32_t baudRate, portMode_t mode, portOptions_t options)
{ {
return serialUSART(UARTDEV_6, baudRate, mode, options); return serialUART(UARTDEV_6, baudRate, mode, options);
}
// USART6 Tx DMA Handler
void DMA2_Stream6_IRQHandler(void)
{
uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF6))
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF6);
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF6);
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF6);
}
handleUsartTxDma(s);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF6);
}
if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF6)==SET)
{
DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF6);
}
} }
void USART6_IRQHandler(void) void USART6_IRQHandler(void)
{ {
uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port); uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
usartIrqHandler(s); uartIrqHandler(s);
} }
#endif #endif

View file

@ -16,9 +16,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#include "platform.h" #include "platform.h"
@ -181,8 +179,8 @@ serialPort_t *usbVcpOpen(void)
vcpPort_t *s; vcpPort_t *s;
#ifdef STM32F4 #ifdef STM32F4
IOInit(IOGetByTag(IO_TAG(PA11)), OWNER_USB, RESOURCE_IO); IOInit(IOGetByTag(IO_TAG(PA11)), OWNER_USB, RESOURCE_INPUT, 0);
IOInit(IOGetByTag(IO_TAG(PA12)), OWNER_USB, RESOURCE_IO); IOInit(IOGetByTag(IO_TAG(PA12)), OWNER_USB, RESOURCE_OUTPUT, 0);
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb); USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);
#else #else
Set_System(); Set_System();

View file

@ -83,12 +83,12 @@ void hcsr04_init(sonarRange_t *sonarRange)
// trigger pin // trigger pin
triggerIO = IOGetByTag(sonarHardwareHCSR04.triggerTag); triggerIO = IOGetByTag(sonarHardwareHCSR04.triggerTag);
IOInit(triggerIO, OWNER_SONAR, RESOURCE_INPUT); IOInit(triggerIO, OWNER_SONAR, RESOURCE_OUTPUT, 0);
IOConfigGPIO(triggerIO, IOCFG_OUT_PP); IOConfigGPIO(triggerIO, IOCFG_OUT_PP);
// echo pin // echo pin
echoIO = IOGetByTag(sonarHardwareHCSR04.echoTag); echoIO = IOGetByTag(sonarHardwareHCSR04.echoTag);
IOInit(echoIO, OWNER_SONAR, RESOURCE_INPUT); IOInit(echoIO, OWNER_SONAR, RESOURCE_INPUT, 0);
IOConfigGPIO(echoIO, IOCFG_IN_FLOATING); IOConfigGPIO(echoIO, IOCFG_IN_FLOATING);
#ifdef USE_EXTI #ifdef USE_EXTI

View file

@ -17,12 +17,9 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
#include "common/utils.h"
#include "system.h" #include "system.h"
#include "io.h" #include "io.h"
@ -61,7 +58,7 @@ void beeperInit(const beeperConfig_t *config)
beeperInverted = config->isInverted; beeperInverted = config->isInverted;
if (beeperIO) { if (beeperIO) {
IOInit(beeperIO, OWNER_BEEPER, RESOURCE_OUTPUT); IOInit(beeperIO, OWNER_BEEPER, RESOURCE_OUTPUT, 0);
IOConfigGPIO(beeperIO, config->isOD ? IOCFG_OUT_OD : IOCFG_OUT_PP); IOConfigGPIO(beeperIO, config->isOD ? IOCFG_OUT_OD : IOCFG_OUT_PP);
} }
systemBeep(false); systemBeep(false);

View file

@ -15,15 +15,11 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "platform.h" #include "platform.h"
#include "build_config.h"
#include "gpio.h" #include "gpio.h"
#include "light_led.h" #include "light_led.h"
#include "sound_beeper.h" #include "sound_beeper.h"

View file

@ -42,6 +42,7 @@ void systemReset(void);
void systemResetToBootloader(void); void systemResetToBootloader(void);
bool isMPUSoftReset(void); bool isMPUSoftReset(void);
void cycleCounterInit(void); void cycleCounterInit(void);
void checkForBootLoaderRequest(void);
void enableGPIOPowerUsageAndNoiseReductions(void); void enableGPIOPowerUsageAndNoiseReductions(void);
// current crystal frequency - 8 or 12MHz // current crystal frequency - 8 or 12MHz

View file

@ -15,10 +15,9 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <string.h>
#include "platform.h" #include "platform.h"
@ -37,7 +36,8 @@ void systemReset(void)
SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04; SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04;
} }
void systemResetToBootloader(void) { void systemResetToBootloader(void)
{
// 1FFFF000 -> 20000200 -> SP // 1FFFF000 -> 20000200 -> SP
// 1FFFF004 -> 1FFFF021 -> PC // 1FFFF004 -> 1FFFF021 -> PC
@ -68,6 +68,8 @@ bool isMPUSoftReset(void)
void systemInit(void) void systemInit(void)
{ {
checkForBootLoaderRequest();
SetSysClock(false); SetSysClock(false);
#ifdef CC3D #ifdef CC3D
@ -110,3 +112,6 @@ void systemInit(void)
SysTick_Config(SystemCoreClock / 1000); SysTick_Config(SystemCoreClock / 1000);
} }
void checkForBootLoaderRequest(void)
{
}

View file

@ -15,10 +15,9 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <string.h>
#include "platform.h" #include "platform.h"
@ -35,7 +34,8 @@ void systemReset(void)
SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04; SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04;
} }
void systemResetToBootloader(void) { void systemResetToBootloader(void)
{
// 1FFFF000 -> 20000200 -> SP // 1FFFF000 -> 20000200 -> SP
// 1FFFF004 -> 1FFFF021 -> PC // 1FFFF004 -> 1FFFF021 -> PC
@ -82,6 +82,8 @@ bool isMPUSoftReset(void)
void systemInit(void) void systemInit(void)
{ {
checkForBootLoaderRequest();
// Enable FPU // Enable FPU
SCB->CPACR = (0x3 << (10 * 2)) | (0x3 << (11 * 2)); SCB->CPACR = (0x3 << (10 * 2)) | (0x3 << (11 * 2));
SetSysClock(); SetSysClock();
@ -102,3 +104,7 @@ void systemInit(void)
// SysTick // SysTick
SysTick_Config(SystemCoreClock / 1000); SysTick_Config(SystemCoreClock / 1000);
} }
void checkForBootLoaderRequest(void)
{
}

View file

@ -15,26 +15,18 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <string.h>
#include "platform.h" #include "platform.h"
#include "accgyro_mpu.h"
#include "gpio.h" #include "gpio.h"
#include "nvic.h" #include "nvic.h"
#include "system.h" #include "system.h"
#include "exti.h" #include "exti.h"
#include "debug.h"
#include "sensor.h"
#include "accgyro.h"
#include "accgyro_mpu.h"
#include "accgyro_spi_mpu6000.h"
#include "accgyro_mpu6500.h"
#include "accgyro_spi_mpu9250.h"
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) #define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
@ -169,6 +161,8 @@ bool isMPUSoftReset(void)
void systemInit(void) void systemInit(void)
{ {
checkForBootLoaderRequest();
SetSysClock(); SetSysClock();
// Configure NVIC preempt/priority groups // Configure NVIC preempt/priority groups
@ -194,3 +188,18 @@ void systemInit(void)
SysTick_Config(SystemCoreClock / 1000); SysTick_Config(SystemCoreClock / 1000);
} }
void(*bootJump)(void);
void checkForBootLoaderRequest(void)
{
if (*((uint32_t *)0x2001FFFC) == 0xDEADBEEF) {
*((uint32_t *)0x2001FFFC) = 0x0;
__enable_irq();
__set_MSP(0x20001000);
bootJump = (void(*)(void))(*((uint32_t *) 0x1fff0004));
bootJump();
while (1);
}
}

View file

@ -17,7 +17,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "platform.h" #include "platform.h"
@ -26,7 +25,6 @@
#include "nvic.h" #include "nvic.h"
#include "gpio.h"
#include "gpio.h" #include "gpio.h"
#include "rcc.h" #include "rcc.h"
#include "system.h" #include "system.h"
@ -90,9 +88,36 @@ static uint8_t lookupTimerIndex(const TIM_TypeDef *tim)
#if USED_TIMERS & TIM_N(4) #if USED_TIMERS & TIM_N(4)
_CASE(4); _CASE(4);
#endif #endif
#if USED_TIMERS & TIM_N(5)
_CASE(5);
#endif
#if USED_TIMERS & TIM_N(6)
_CASE(6);
#endif
#if USED_TIMERS & TIM_N(7)
_CASE(7);
#endif
#if USED_TIMERS & TIM_N(8) #if USED_TIMERS & TIM_N(8)
_CASE(8); _CASE(8);
#endif #endif
#if USED_TIMERS & TIM_N(9)
_CASE(9);
#endif
#if USED_TIMERS & TIM_N(10)
_CASE(10);
#endif
#if USED_TIMERS & TIM_N(11)
_CASE(11);
#endif
#if USED_TIMERS & TIM_N(12)
_CASE(12);
#endif
#if USED_TIMERS & TIM_N(13)
_CASE(13);
#endif
#if USED_TIMERS & TIM_N(14)
_CASE(14);
#endif
#if USED_TIMERS & TIM_N(15) #if USED_TIMERS & TIM_N(15)
_CASE(15); _CASE(15);
#endif #endif
@ -123,9 +148,36 @@ TIM_TypeDef * const usedTimers[USED_TIMER_COUNT] = {
#if USED_TIMERS & TIM_N(4) #if USED_TIMERS & TIM_N(4)
_DEF(4), _DEF(4),
#endif #endif
#if USED_TIMERS & TIM_N(5)
_DEF(5),
#endif
#if USED_TIMERS & TIM_N(6)
_DEF(6),
#endif
#if USED_TIMERS & TIM_N(7)
_DEF(7),
#endif
#if USED_TIMERS & TIM_N(8) #if USED_TIMERS & TIM_N(8)
_DEF(8), _DEF(8),
#endif #endif
#if USED_TIMERS & TIM_N(9)
_DEF(9),
#endif
#if USED_TIMERS & TIM_N(10)
_DEF(10),
#endif
#if USED_TIMERS & TIM_N(11)
_DEF(11),
#endif
#if USED_TIMERS & TIM_N(12)
_DEF(12),
#endif
#if USED_TIMERS & TIM_N(13)
_DEF(13),
#endif
#if USED_TIMERS & TIM_N(14)
_DEF(14),
#endif
#if USED_TIMERS & TIM_N(15) #if USED_TIMERS & TIM_N(15)
_DEF(15), _DEF(15),
#endif #endif
@ -153,6 +205,18 @@ rccPeriphTag_t timerRCC(TIM_TypeDef *tim)
return 0; return 0;
} }
#if defined(STM32F3) || defined(STM32F4)
uint8_t timerGPIOAF(TIM_TypeDef *tim)
{
for (uint8_t i = 0; i < HARDWARE_TIMER_DEFINITION_COUNT; i++) {
if (timerDefinitions[i].TIMx == tim) {
return timerDefinitions[i].alternateFunction;
}
}
return 0;
}
#endif
void timerNVICConfigure(uint8_t irq) void timerNVICConfigure(uint8_t irq)
{ {
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
@ -364,7 +428,7 @@ void timerChClearCCFlag(const timerHardware_t *timHw)
// configure timer channel GPIO mode // configure timer channel GPIO mode
void timerChConfigGPIO(const timerHardware_t* timHw, ioConfig_t mode) void timerChConfigGPIO(const timerHardware_t* timHw, ioConfig_t mode)
{ {
IOInit(IOGetByTag(timHw->tag), OWNER_TIMER, RESOURCE_TIMER); IOInit(IOGetByTag(timHw->tag), OWNER_TIMER, RESOURCE_TIMER, 0);
IOConfigGPIO(IOGetByTag(timHw->tag), mode); IOConfigGPIO(IOGetByTag(timHw->tag), mode);
} }
@ -458,7 +522,7 @@ void timerChConfigOC(const timerHardware_t* timHw, bool outEnable, bool stateHig
if(outEnable) { if(outEnable) {
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
if (timHw->outputInverted) { if (timHw->output & TIMER_OUTPUT_INVERTED) {
stateHigh = !stateHigh; stateHigh = !stateHigh;
} }
TIM_OCInitStructure.TIM_OCPolarity = stateHigh ? TIM_OCPolarity_High : TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCPolarity = stateHigh ? TIM_OCPolarity_High : TIM_OCPolarity_Low;

View file

@ -69,6 +69,9 @@ typedef struct timerOvrHandlerRec_s {
typedef struct timerDef_s { typedef struct timerDef_s {
TIM_TypeDef *TIMx; TIM_TypeDef *TIMx;
rccPeriphTag_t rcc; rccPeriphTag_t rcc;
#if defined(STM32F3) || defined(STM32F4)
uint8_t alternateFunction;
#endif
} timerDef_t; } timerDef_t;
typedef struct timerHardware_s { typedef struct timerHardware_s {
@ -76,14 +79,18 @@ typedef struct timerHardware_s {
ioTag_t tag; ioTag_t tag;
uint8_t channel; uint8_t channel;
uint8_t irq; uint8_t irq;
uint8_t outputEnable; uint8_t output;
ioConfig_t ioMode; ioConfig_t ioMode;
#if defined(STM32F3) || defined(STM32F4) #if defined(STM32F3) || defined(STM32F4)
uint8_t alternateFunction; uint8_t alternateFunction;
#endif #endif
uint8_t outputInverted;
} timerHardware_t; } timerHardware_t;
enum {
TIMER_OUTPUT_ENABLED = 0x01,
TIMER_OUTPUT_INVERTED = 0x02
};
#ifdef STM32F1 #ifdef STM32F1
#if defined(STM32F10X_XL) || defined(STM32F10X_HD_VL) #if defined(STM32F10X_XL) || defined(STM32F10X_HD_VL)
#define HARDWARE_TIMER_DEFINITION_COUNT 14 #define HARDWARE_TIMER_DEFINITION_COUNT 14
@ -148,3 +155,7 @@ void timerForceOverflow(TIM_TypeDef *tim);
void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint8_t mhz); // TODO - just for migration void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint8_t mhz); // TODO - just for migration
rccPeriphTag_t timerRCC(TIM_TypeDef *tim); rccPeriphTag_t timerRCC(TIM_TypeDef *tim);
#if defined(STM32F3) || defined(STM32F4)
uint8_t timerGPIOAF(TIM_TypeDef *tim);
#endif

View file

@ -67,8 +67,7 @@ void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t
tmp = (uint32_t) TIMx; tmp = (uint32_t) TIMx;
tmp += CCMR_Offset; tmp += CCMR_Offset;
if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) {
{
tmp += (TIM_Channel>>1); tmp += (TIM_Channel>>1);
/* Reset the OCxM bits in the CCMRx register */ /* Reset the OCxM bits in the CCMRx register */
@ -76,10 +75,8 @@ void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t
/* Configure the OCxM bits in the CCMRx register */ /* Configure the OCxM bits in the CCMRx register */
*(__IO uint32_t *) tmp |= TIM_OCMode; *(__IO uint32_t *) tmp |= TIM_OCMode;
} } else {
else tmp += (uint16_t)(TIM_Channel - (uint16_t)4) >> (uint16_t)1;
{
tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
/* Reset the OCxM bits in the CCMRx register */ /* Reset the OCxM bits in the CCMRx register */
*(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M); *(__IO uint32_t *) tmp &= (uint32_t)~((uint32_t)TIM_CCMR1_OC2M);

View file

@ -10,16 +10,16 @@
#include "timer.h" #include "timer.h"
const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = { const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
{ .TIMx = TIM1, .rcc = RCC_APB2(TIM1) }, { .TIMx = TIM1, .rcc = RCC_APB2(TIM1), GPIO_AF_6 },
{ .TIMx = TIM2, .rcc = RCC_APB1(TIM2) }, { .TIMx = TIM2, .rcc = RCC_APB1(TIM2), GPIO_AF_1 },
{ .TIMx = TIM3, .rcc = RCC_APB1(TIM3) }, { .TIMx = TIM3, .rcc = RCC_APB1(TIM3), GPIO_AF_2 },
{ .TIMx = TIM4, .rcc = RCC_APB1(TIM4) }, { .TIMx = TIM4, .rcc = RCC_APB1(TIM4), GPIO_AF_10 },
{ .TIMx = TIM6, .rcc = RCC_APB1(TIM6) }, { .TIMx = TIM6, .rcc = RCC_APB1(TIM6), 0 },
{ .TIMx = TIM7, .rcc = RCC_APB1(TIM7) }, { .TIMx = TIM7, .rcc = RCC_APB1(TIM7), 0 },
{ .TIMx = TIM8, .rcc = RCC_APB2(TIM8) }, { .TIMx = TIM8, .rcc = RCC_APB2(TIM8), GPIO_AF_5 },
{ .TIMx = TIM15, .rcc = RCC_APB2(TIM15) }, { .TIMx = TIM15, .rcc = RCC_APB2(TIM15), GPIO_AF_9 },
{ .TIMx = TIM16, .rcc = RCC_APB2(TIM16) }, { .TIMx = TIM16, .rcc = RCC_APB2(TIM16), GPIO_AF_1 },
{ .TIMx = TIM17, .rcc = RCC_APB2(TIM17) }, { .TIMx = TIM17, .rcc = RCC_APB2(TIM17), GPIO_AF_1 },
}; };
@ -77,7 +77,7 @@ void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint32_t
/* Configure the OCxM bits in the CCMRx register */ /* Configure the OCxM bits in the CCMRx register */
*(__IO uint32_t *) tmp |= TIM_OCMode; *(__IO uint32_t *) tmp |= TIM_OCMode;
} else { } else {
tmp += (uint32_t)(TIM_Channel - (uint32_t)4)>> (uint32_t)1; tmp += (uint32_t)(TIM_Channel - (uint32_t)4) >> (uint32_t)1;
/* Reset the OCxM bits in the CCMRx register */ /* Reset the OCxM bits in the CCMRx register */
*(__IO uint32_t *) tmp &= CCMR_OC24M_MASK; *(__IO uint32_t *) tmp &= CCMR_OC24M_MASK;

View file

@ -35,20 +35,20 @@
#define CCMR_Offset ((uint16_t)0x0018) #define CCMR_Offset ((uint16_t)0x0018)
const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = { const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
{ .TIMx = TIM1, .rcc = RCC_APB2(TIM1) }, { .TIMx = TIM1, .rcc = RCC_APB2(TIM1), GPIO_AF_TIM1 },
{ .TIMx = TIM2, .rcc = RCC_APB1(TIM2) }, { .TIMx = TIM2, .rcc = RCC_APB1(TIM2), GPIO_AF_TIM2 },
{ .TIMx = TIM3, .rcc = RCC_APB1(TIM3) }, { .TIMx = TIM3, .rcc = RCC_APB1(TIM3), GPIO_AF_TIM3 },
{ .TIMx = TIM4, .rcc = RCC_APB1(TIM4) }, { .TIMx = TIM4, .rcc = RCC_APB1(TIM4), GPIO_AF_TIM4 },
{ .TIMx = TIM5, .rcc = RCC_APB1(TIM5) }, { .TIMx = TIM5, .rcc = RCC_APB1(TIM5), GPIO_AF_TIM5 },
{ .TIMx = TIM6, .rcc = RCC_APB1(TIM6) }, { .TIMx = TIM6, .rcc = RCC_APB1(TIM6), 0 },
{ .TIMx = TIM7, .rcc = RCC_APB1(TIM7) }, { .TIMx = TIM7, .rcc = RCC_APB1(TIM7), 0 },
{ .TIMx = TIM8, .rcc = RCC_APB2(TIM8) }, { .TIMx = TIM8, .rcc = RCC_APB2(TIM8), GPIO_AF_TIM8 },
{ .TIMx = TIM9, .rcc = RCC_APB2(TIM9) }, { .TIMx = TIM9, .rcc = RCC_APB2(TIM9), GPIO_AF_TIM9 },
{ .TIMx = TIM10, .rcc = RCC_APB2(TIM10) }, { .TIMx = TIM10, .rcc = RCC_APB2(TIM10), GPIO_AF_TIM10 },
{ .TIMx = TIM11, .rcc = RCC_APB2(TIM11) }, { .TIMx = TIM11, .rcc = RCC_APB2(TIM11), GPIO_AF_TIM11 },
{ .TIMx = TIM12, .rcc = RCC_APB1(TIM12) }, { .TIMx = TIM12, .rcc = RCC_APB1(TIM12), GPIO_AF_TIM12 },
{ .TIMx = TIM13, .rcc = RCC_APB1(TIM13) }, { .TIMx = TIM13, .rcc = RCC_APB1(TIM13), GPIO_AF_TIM13 },
{ .TIMx = TIM14, .rcc = RCC_APB1(TIM14) }, { .TIMx = TIM14, .rcc = RCC_APB1(TIM14), GPIO_AF_TIM14 },
}; };
void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode) void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode)
@ -63,8 +63,7 @@ void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t
tmp = (uint32_t) TIMx; tmp = (uint32_t) TIMx;
tmp += CCMR_Offset; tmp += CCMR_Offset;
if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3)) {
{
tmp += (TIM_Channel>>1); tmp += (TIM_Channel>>1);
/* Reset the OCxM bits in the CCMRx register */ /* Reset the OCxM bits in the CCMRx register */
@ -72,9 +71,7 @@ void TIM_SelectOCxM_NoDisable(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t
/* Configure the OCxM bits in the CCMRx register */ /* Configure the OCxM bits in the CCMRx register */
*(__IO uint32_t *) tmp |= TIM_OCMode; *(__IO uint32_t *) tmp |= TIM_OCMode;
} } else {
else
{
tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1; tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
/* Reset the OCxM bits in the CCMRx register */ /* Reset the OCxM bits in the CCMRx register */

View file

@ -21,9 +21,8 @@
#include <platform.h> #include <platform.h>
#include "build_config.h"
#include "drivers/dma.h" #include "drivers/dma.h"
#include "drivers/nvic.h"
#include "drivers/transponder_ir.h" #include "drivers/transponder_ir.h"
/* /*
@ -38,19 +37,19 @@ uint8_t transponderIrDMABuffer[TRANSPONDER_DMA_BUFFER_SIZE];
volatile uint8_t transponderIrDataTransferInProgress = 0; volatile uint8_t transponderIrDataTransferInProgress = 0;
void transponderDMAHandler(DMA_Channel_TypeDef *channel) void transponderDMAHandler(dmaChannelDescriptor_t* descriptor)
{ {
if (DMA_GetFlagStatus(TRANSPONDER_DMA_TC_FLAG)) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
transponderIrDataTransferInProgress = 0; transponderIrDataTransferInProgress = 0;
DMA_Cmd(channel, DISABLE); DMA_Cmd(descriptor->channel, DISABLE);
DMA_ClearFlag(TRANSPONDER_DMA_TC_FLAG); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
} }
} }
void transponderIrInit(void) void transponderIrInit(void)
{ {
memset(&transponderIrDMABuffer, 0, TRANSPONDER_DMA_BUFFER_SIZE); memset(&transponderIrDMABuffer, 0, TRANSPONDER_DMA_BUFFER_SIZE);
dmaSetHandler(TRANSPONDER_DMA_HANDLER_IDENTIFER, transponderDMAHandler); dmaSetHandler(TRANSPONDER_DMA_HANDLER_IDENTIFER, transponderDMAHandler, NVIC_PRIO_TRANSPONDER_DMA, 0);
transponderIrHardwareInit(); transponderIrHardwareInit();
} }

View file

@ -86,7 +86,7 @@ void transponderIrHardwareInit(void)
/* configure DMA */ /* configure DMA */
/* DMA clock enable */ /* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA1 Channel6 Config */ /* DMA1 Channel6 Config */
DMA_DeInit(TRANSPONDER_DMA_CHANNEL); DMA_DeInit(TRANSPONDER_DMA_CHANNEL);
@ -110,13 +110,6 @@ void transponderIrHardwareInit(void)
DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE); DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TRANSPONDER_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_TRANSPONDER_DMA);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_TRANSPONDER_DMA);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} }
void transponderIrDMAEnable(void) void transponderIrDMAEnable(void)

View file

@ -15,7 +15,6 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>

View file

@ -15,19 +15,19 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "sdcard.h"
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "platform.h" #include "platform.h"
#ifdef USB_IO
#include "io.h" #include "io.h"
#include "system.h" #include "system.h"
#include "usb_io.h" #include "usb_io.h"
#include "sdcard.h"
#ifdef USB_IO
#ifdef USB_DETECT_PIN #ifdef USB_DETECT_PIN
static IO_t usbDetectPin = IO_NONE; static IO_t usbDetectPin = IO_NONE;
@ -36,7 +36,7 @@ static IO_t usbDetectPin = IO_NONE;
void usbCableDetectDeinit(void) void usbCableDetectDeinit(void)
{ {
#ifdef USB_DETECT_PIN #ifdef USB_DETECT_PIN
IOInit(usbDetectPin, OWNER_FREE, RESOURCE_NONE); IOInit(usbDetectPin, OWNER_FREE, RESOURCE_NONE, 0);
IOConfigGPIO(usbDetectPin, IOCFG_IN_FLOATING); IOConfigGPIO(usbDetectPin, IOCFG_IN_FLOATING);
usbDetectPin = IO_NONE; usbDetectPin = IO_NONE;
#endif #endif
@ -47,7 +47,7 @@ void usbCableDetectInit(void)
#ifdef USB_DETECT_PIN #ifdef USB_DETECT_PIN
usbDetectPin = IOGetByTag(IO_TAG(USB_DETECT_PIN)); usbDetectPin = IOGetByTag(IO_TAG(USB_DETECT_PIN));
IOInit(usbDetectPin, OWNER_USB, RESOURCE_INPUT); IOInit(usbDetectPin, OWNER_USB, RESOURCE_INPUT, 0);
IOConfigGPIO(usbDetectPin, IOCFG_OUT_PP); IOConfigGPIO(usbDetectPin, IOCFG_OUT_PP);
#endif #endif
} }

View file

@ -22,7 +22,6 @@
* as this header is maintained with the file at all times. * as this header is maintained with the file at all times.
*/ */
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>

View file

@ -15,7 +15,6 @@
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>. * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -53,23 +52,24 @@ static IO_t rtc6705DataPin = IO_NONE;
static IO_t rtc6705LePin = IO_NONE; static IO_t rtc6705LePin = IO_NONE;
static IO_t rtc6705ClkPin = IO_NONE; static IO_t rtc6705ClkPin = IO_NONE;
void rtc6705_soft_spi_init(void) { void rtc6705_soft_spi_init(void)
{
rtc6705DataPin = IOGetByTag(IO_TAG(RTC6705_SPIDATA_PIN)); rtc6705DataPin = IOGetByTag(IO_TAG(RTC6705_SPIDATA_PIN));
rtc6705LePin = IOGetByTag(IO_TAG(RTC6705_SPILE_PIN)); rtc6705LePin = IOGetByTag(IO_TAG(RTC6705_SPILE_PIN));
rtc6705ClkPin = IOGetByTag(IO_TAG(RTC6705_SPICLK_PIN)); rtc6705ClkPin = IOGetByTag(IO_TAG(RTC6705_SPICLK_PIN));
IOInit(rtc6705DataPin, OWNER_SYSTEM, RESOURCE_OUTPUT); IOInit(rtc6705DataPin, OWNER_TX, RESOURCE_SPI_MOSI, 0);
IOConfigGPIO(rtc6705DataPin, IOCFG_OUT_PP); IOConfigGPIO(rtc6705DataPin, IOCFG_OUT_PP);
IOInit(rtc6705LePin, OWNER_SYSTEM, RESOURCE_OUTPUT); IOInit(rtc6705LePin, OWNER_TX, RESOURCE_SPI_CS, 0);
IOConfigGPIO(rtc6705LePin, IOCFG_OUT_PP); IOConfigGPIO(rtc6705LePin, IOCFG_OUT_PP);
IOInit(rtc6705ClkPin, OWNER_SYSTEM, RESOURCE_OUTPUT); IOInit(rtc6705ClkPin, OWNER_TX, RESOURCE_SPI_SCK, 0);
IOConfigGPIO(rtc6705ClkPin, IOCFG_OUT_PP); IOConfigGPIO(rtc6705ClkPin, IOCFG_OUT_PP);
} }
static void rtc6705_write_register(uint8_t addr, uint32_t data) { static void rtc6705_write_register(uint8_t addr, uint32_t data)
{
uint8_t i; uint8_t i;
RTC6705_SPILE_OFF; RTC6705_SPILE_OFF;
@ -107,7 +107,8 @@ static void rtc6705_write_register(uint8_t addr, uint32_t data) {
} }
void rtc6705_soft_spi_set_channel(uint16_t channel_freq) { void rtc6705_soft_spi_set_channel(uint16_t channel_freq)
{
uint32_t freq = (uint32_t)channel_freq * 1000; uint32_t freq = (uint32_t)channel_freq * 1000;
uint32_t N, A; uint32_t N, A;
@ -119,7 +120,8 @@ void rtc6705_soft_spi_set_channel(uint16_t channel_freq) {
rtc6705_write_register(1, (N << 7) | A); rtc6705_write_register(1, (N << 7) | A);
} }
void rtc6705_soft_spi_set_rf_power(uint8_t reduce_power) { void rtc6705_soft_spi_set_rf_power(uint8_t reduce_power)
{
rtc6705_write_register(7, (reduce_power ? (PA_CONTROL_DEFAULT | PD_Q5G_MASK) & (~(PA5G_PW_MASK | PA5G_BS_MASK)) : PA_CONTROL_DEFAULT)); rtc6705_write_register(7, (reduce_power ? (PA_CONTROL_DEFAULT | PD_Q5G_MASK) & (~(PA5G_PW_MASK | PA5G_BS_MASK)) : PA_CONTROL_DEFAULT));
} }

View file

@ -28,7 +28,6 @@
#include "debug.h" #include "debug.h"
#include "common/axis.h" #include "common/axis.h"
#include "common/filter.h"
#include "drivers/system.h" #include "drivers/system.h"
#include "drivers/sensor.h" #include "drivers/sensor.h"

View file

@ -36,7 +36,6 @@
#include "drivers/sensor.h" #include "drivers/sensor.h"
#include "drivers/accgyro.h" #include "drivers/accgyro.h"
#include "drivers/system.h" #include "drivers/system.h"
#include "drivers/gyro_sync.h"
#include "rx/rx.h" #include "rx/rx.h"
@ -667,9 +666,10 @@ void stopMotors(void)
delay(50); // give the timers and ESCs a chance to react. delay(50); // give the timers and ESCs a chance to react.
} }
void StopPwmAllMotors() void stopPwmAllMotors()
{ {
pwmShutdownPulsesForAllMotors(motorCount); pwmShutdownPulsesForAllMotors(motorCount);
delayMicroseconds(1500);
} }
#ifndef USE_QUAD_MIXER_ONLY #ifndef USE_QUAD_MIXER_ONLY
@ -947,7 +947,7 @@ void filterServos(void)
#ifdef USE_SERVOS #ifdef USE_SERVOS
static int16_t servoIdx; static int16_t servoIdx;
static bool servoFilterIsSet; static bool servoFilterIsSet;
static biquad_t servoFilterState[MAX_SUPPORTED_SERVOS]; static biquadFilter_t servoFilter[MAX_SUPPORTED_SERVOS];
#if defined(MIXER_DEBUG) #if defined(MIXER_DEBUG)
uint32_t startTime = micros(); uint32_t startTime = micros();
@ -956,11 +956,11 @@ void filterServos(void)
if (mixerConfig->servo_lowpass_enable) { if (mixerConfig->servo_lowpass_enable) {
for (servoIdx = 0; servoIdx < MAX_SUPPORTED_SERVOS; servoIdx++) { for (servoIdx = 0; servoIdx < MAX_SUPPORTED_SERVOS; servoIdx++) {
if (!servoFilterIsSet) { if (!servoFilterIsSet) {
BiQuadNewLpf(mixerConfig->servo_lowpass_freq, &servoFilterState[servoIdx], targetPidLooptime); biquadFilterInit(&servoFilter[servoIdx], mixerConfig->servo_lowpass_freq, targetPidLooptime);
servoFilterIsSet = true; servoFilterIsSet = true;
} }
servo[servoIdx] = lrintf(applyBiQuadFilter((float) servo[servoIdx], &servoFilterState[servoIdx])); servo[servoIdx] = lrintf(biquadFilterApply(&servoFilter[servoIdx], (float)servo[servoIdx]));
// Sanity check // Sanity check
servo[servoIdx] = constrain(servo[servoIdx], servoConf[servoIdx].min, servoConf[servoIdx].max); servo[servoIdx] = constrain(servo[servoIdx], servoConf[servoIdx].min, servoConf[servoIdx].max);
} }

View file

@ -215,4 +215,4 @@ void mixTable(void);
void syncMotors(bool enabled); void syncMotors(bool enabled);
void writeMotors(void); void writeMotors(void);
void stopMotors(void); void stopMotors(void);
void StopPwmAllMotors(void); void stopPwmAllMotors(void);

View file

@ -29,7 +29,6 @@
#include "common/filter.h" #include "common/filter.h"
#include "drivers/sensor.h" #include "drivers/sensor.h"
#include "drivers/gyro_sync.h"
#include "drivers/accgyro.h" #include "drivers/accgyro.h"
#include "sensors/sensors.h" #include "sensors/sensors.h"
@ -74,7 +73,7 @@ pidControllerFuncPtr pid_controller = pidInteger; // which pid controller are we
void setTargetPidLooptime(uint8_t pidProcessDenom) void setTargetPidLooptime(uint8_t pidProcessDenom)
{ {
targetPidLooptime = targetLooptime * pidProcessDenom; targetPidLooptime = gyro.targetLooptime * pidProcessDenom;
} }
uint16_t getDynamicKi(int axis, const pidProfile_t *pidProfile, int32_t angleRate) uint16_t getDynamicKi(int axis, const pidProfile_t *pidProfile, int32_t angleRate)
@ -113,8 +112,8 @@ float getdT (void)
const angle_index_t rcAliasToAngleIndexMap[] = { AI_ROLL, AI_PITCH }; const angle_index_t rcAliasToAngleIndexMap[] = { AI_ROLL, AI_PITCH };
static filterStatePt1_t deltaFilterState[3]; static pt1Filter_t deltaFilter[3];
static filterStatePt1_t yawFilterState; static pt1Filter_t yawFilter;
#ifndef SKIP_PID_LUXFLOAT #ifndef SKIP_PID_LUXFLOAT
static void pidFloat(const pidProfile_t *pidProfile, uint16_t max_angle_inclination, static void pidFloat(const pidProfile_t *pidProfile, uint16_t max_angle_inclination,
@ -206,7 +205,7 @@ static void pidFloat(const pidProfile_t *pidProfile, uint16_t max_angle_inclinat
//-----calculate D-term //-----calculate D-term
if (axis == YAW) { if (axis == YAW) {
if (pidProfile->yaw_lpf_hz) PTerm = filterApplyPt1(PTerm, &yawFilterState, pidProfile->yaw_lpf_hz, getdT()); if (pidProfile->yaw_lpf_hz) PTerm = pt1FilterApply4(&yawFilter, PTerm, pidProfile->yaw_lpf_hz, getdT());
axisPID[axis] = lrintf(PTerm + ITerm); axisPID[axis] = lrintf(PTerm + ITerm);
@ -231,7 +230,7 @@ static void pidFloat(const pidProfile_t *pidProfile, uint16_t max_angle_inclinat
delta *= (1.0f / getdT()); delta *= (1.0f / getdT());
// Filter delta // Filter delta
if (pidProfile->dterm_lpf_hz) delta = filterApplyPt1(delta, &deltaFilterState[axis], pidProfile->dterm_lpf_hz, getdT()); if (pidProfile->dterm_lpf_hz) delta = pt1FilterApply4(&deltaFilter[axis], delta, pidProfile->dterm_lpf_hz, getdT());
DTerm = constrainf(luxDTermScale * delta * (float)pidProfile->D8[axis] * tpaFactor, -300.0f, 300.0f); DTerm = constrainf(luxDTermScale * delta * (float)pidProfile->D8[axis] * tpaFactor, -300.0f, 300.0f);
@ -345,7 +344,7 @@ static void pidInteger(const pidProfile_t *pidProfile, uint16_t max_angle_inclin
//-----calculate D-term //-----calculate D-term
if (axis == YAW) { if (axis == YAW) {
if (pidProfile->yaw_lpf_hz) PTerm = filterApplyPt1(PTerm, &yawFilterState, pidProfile->yaw_lpf_hz, getdT()); if (pidProfile->yaw_lpf_hz) PTerm = pt1FilterApply4(&yawFilter, PTerm, pidProfile->yaw_lpf_hz, getdT());
axisPID[axis] = PTerm + ITerm; axisPID[axis] = PTerm + ITerm;
@ -370,7 +369,7 @@ static void pidInteger(const pidProfile_t *pidProfile, uint16_t max_angle_inclin
delta = (delta * ((uint16_t) 0xFFFF / ((uint16_t)targetPidLooptime >> 4))) >> 5; delta = (delta * ((uint16_t) 0xFFFF / ((uint16_t)targetPidLooptime >> 4))) >> 5;
// Filter delta // Filter delta
if (pidProfile->dterm_lpf_hz) delta = filterApplyPt1((float)delta, &deltaFilterState[axis], pidProfile->dterm_lpf_hz, getdT()); if (pidProfile->dterm_lpf_hz) delta = pt1FilterApply4(&deltaFilter[axis], (float)delta, pidProfile->dterm_lpf_hz, getdT());
DTerm = (delta * pidProfile->D8[axis] * PIDweight[axis] / 100) >> 8; DTerm = (delta * pidProfile->D8[axis] * PIDweight[axis] / 100) >> 8;

View file

@ -17,10 +17,12 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include "platform.h" #include "platform.h"
#ifdef DISPLAY
#include "version.h" #include "version.h"
#include "debug.h" #include "debug.h"
@ -38,16 +40,12 @@
#include "common/axis.h" #include "common/axis.h"
#include "common/typeconversion.h" #include "common/typeconversion.h"
#ifdef DISPLAY
#include "sensors/battery.h" #include "sensors/battery.h"
#include "sensors/sensors.h" #include "sensors/sensors.h"
#include "sensors/compass.h" #include "sensors/compass.h"
#include "sensors/acceleration.h" #include "sensors/acceleration.h"
#include "sensors/gyro.h" #include "sensors/gyro.h"
#include "rx/rx.h"
#include "io/rc_controls.h" #include "io/rc_controls.h"
#include "flight/pid.h" #include "flight/pid.h"

View file

@ -23,6 +23,9 @@
#include <math.h> #include <math.h>
#include "platform.h" #include "platform.h"
#ifdef GPS
#include "build_config.h" #include "build_config.h"
#include "debug.h" #include "debug.h"
@ -50,8 +53,6 @@
#include "config/runtime_config.h" #include "config/runtime_config.h"
#ifdef GPS
#define LOG_ERROR '?' #define LOG_ERROR '?'
#define LOG_IGNORED '!' #define LOG_IGNORED '!'
#define LOG_SKIPPED '>' #define LOG_SKIPPED '>'

Some files were not shown because too many files have changed in this diff Show more