mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 14:25:20 +03:00
Merge remote-tracking branch 'refs/remotes/betaflight/master' into betaflight
This commit is contained in:
commit
b15e2ed62c
250 changed files with 5240 additions and 4128 deletions
44
Makefile
44
Makefile
|
@ -600,6 +600,7 @@ LDFLAGS = -lm \
|
|||
-Wl,-gc-sections,-Map,$(TARGET_MAP) \
|
||||
-Wl,-L$(LINKER_DIR) \
|
||||
-Wl,--cref \
|
||||
-Wl,--no-wchar-size-warning \
|
||||
-T$(LD_SCRIPT)
|
||||
|
||||
###############################################################################
|
||||
|
@ -664,27 +665,39 @@ all: $(VALID_TARGETS)
|
|||
$(VALID_TARGETS):
|
||||
echo "" && \
|
||||
echo "Building $@" && \
|
||||
$(MAKE) -j binary hex TARGET=$@ && \
|
||||
$(MAKE) binary hex TARGET=$@ && \
|
||||
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:
|
||||
echo "Cleaning $(TARGET)"
|
||||
rm -f $(CLEAN_ARTIFACTS)
|
||||
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:
|
||||
cd src/test && $(MAKE) clean || true
|
||||
|
||||
## clean_all_targets : clean all valid target platforms
|
||||
clean_all:
|
||||
for clean_target in $(VALID_TARGETS); do \
|
||||
echo "" && \
|
||||
echo "Cleaning $$clean_target" && \
|
||||
$(MAKE) -j TARGET=$$clean_target clean || \
|
||||
break; \
|
||||
echo "Cleaning $$clean_target succeeded."; \
|
||||
done
|
||||
## clean_<TARGET> : clean up one specific target
|
||||
$(CLEAN_TARGETS) :
|
||||
$(MAKE) -j TARGET=$(subst clean_,,$@) clean
|
||||
|
||||
## <TARGET>_clean : clean up one specific target (alias for above)
|
||||
$(TARGETS_CLEAN) :
|
||||
$(MAKE) -j TARGET=$(subst _clean,,$@) clean
|
||||
|
||||
## 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)
|
||||
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: st-flash_$(TARGET)
|
||||
|
||||
binary: $(TARGET_BIN)
|
||||
hex: $(TARGET_HEX)
|
||||
binary:
|
||||
$(MAKE) -j $(TARGET_BIN)
|
||||
|
||||
hex:
|
||||
$(MAKE) -j $(TARGET_HEX)
|
||||
|
||||
unbrick_$(TARGET): $(TARGET_HEX)
|
||||
stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Betaflight
|
||||
|
||||

|
||||

|
||||
|
||||
Clean-code version of baseflight flight-controller - flight controllers are used to fly multi-rotor craft and fixed wing craft.
|
||||
|
||||
|
|
|
@ -20,7 +20,10 @@ targets=("PUBLISHMETA=True" \
|
|||
"TARGET=ALIENFLIGHTF3" \
|
||||
"TARGET=DOGE" \
|
||||
"TARGET=SINGULARITY" \
|
||||
"TARGET=SIRINFPV")
|
||||
"TARGET=SIRINFPV" \
|
||||
"TARGET=X_RACERSPI")
|
||||
|
||||
|
||||
|
||||
#fake a travis build environment
|
||||
export TRAVIS_BUILD_NUMBER=$(date +%s)
|
||||
|
@ -30,9 +33,9 @@ export TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG:=$USER/simulated}
|
|||
for target in "${targets[@]}"
|
||||
do
|
||||
unset RUNTESTS PUBLISHMETA TARGET
|
||||
echo
|
||||
echo
|
||||
echo "BUILDING '$target'"
|
||||
echo
|
||||
echo
|
||||
echo "BUILDING '$target'"
|
||||
eval "export $target"
|
||||
make -f Makefile clean
|
||||
./.travis.sh
|
||||
|
|
|
@ -325,9 +325,6 @@ extern uint32_t currentTime;
|
|||
//From rx.c:
|
||||
extern uint16_t rssi;
|
||||
|
||||
//From gyro.c
|
||||
extern uint32_t targetLooptime;
|
||||
|
||||
//From rc_controls.c
|
||||
extern uint32_t rcModeActivationMask;
|
||||
|
||||
|
@ -404,7 +401,7 @@ static bool testBlackboxConditionUncached(FlightLogFieldCondition condition)
|
|||
case FLIGHT_LOG_FIELD_CONDITION_AT_LEAST_MOTORS_7:
|
||||
case FLIGHT_LOG_FIELD_CONDITION_AT_LEAST_MOTORS_8:
|
||||
return motorCount >= condition - FLIGHT_LOG_FIELD_CONDITION_AT_LEAST_MOTORS_1 + 1;
|
||||
|
||||
|
||||
case FLIGHT_LOG_FIELD_CONDITION_TRICOPTER:
|
||||
return masterConfig.mixerMode == MIXER_TRI || masterConfig.mixerMode == MIXER_CUSTOM_TRI;
|
||||
|
||||
|
@ -641,7 +638,7 @@ static void writeInterframe(void)
|
|||
*/
|
||||
arraySubInt32(deltas, blackboxCurrent->axisPID_I, blackboxLast->axisPID_I, XYZ_AXIS_COUNT);
|
||||
blackboxWriteTag2_3S32(deltas);
|
||||
|
||||
|
||||
/*
|
||||
* The PID D term is frequently set to zero for yaw, which makes the result from the calculation
|
||||
* always zero. So don't bother recording D results when PID D terms are zero.
|
||||
|
@ -855,7 +852,7 @@ void startBlackbox(void)
|
|||
* cache those now.
|
||||
*/
|
||||
blackboxBuildConditionCache();
|
||||
|
||||
|
||||
blackboxModeActivationConditionPresent = isModeActivationConditionPresent(masterConfig.modeActivationConditions, BOXBLACKBOX);
|
||||
|
||||
blackboxIteration = 0;
|
||||
|
@ -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("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);
|
||||
|
@ -1362,7 +1359,7 @@ static void blackboxLogIteration()
|
|||
} else {
|
||||
blackboxCheckAndLogArmingBeep();
|
||||
blackboxCheckAndLogFlightMode(); // Check for FlightMode status change event
|
||||
|
||||
|
||||
if (blackboxShouldLogPFrame(blackboxPFrameIndex)) {
|
||||
/*
|
||||
* We assume that slow frames are only interesting in that they aid the interpretation of the main data stream.
|
||||
|
@ -1499,7 +1496,7 @@ void handleBlackbox(void)
|
|||
|
||||
blackboxLogEvent(FLIGHT_LOG_EVENT_LOGGING_RESUME, (flightLogEventData_t *) &resume);
|
||||
blackboxSetState(BLACKBOX_STATE_RUNNING);
|
||||
|
||||
|
||||
blackboxLogIteration();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "drivers/accgyro.h"
|
||||
#include "drivers/light_led.h"
|
||||
#include "drivers/sound_beeper.h"
|
||||
#include "drivers/gyro_sync.h"
|
||||
|
||||
#include "sensors/sensors.h"
|
||||
#include "sensors/boardalignment.h"
|
||||
|
|
|
@ -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
|
||||
// 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"
|
||||
// increment version number is BARRIER works
|
||||
// TODO - use flag to disable ATOMIC_BARRIER and use full barrier instead
|
||||
|
|
|
@ -17,76 +17,81 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/filter.h"
|
||||
#include "common/maths.h"
|
||||
|
||||
#define M_LN2_FLOAT 0.69314718055994530942f
|
||||
#define M_PI_FLOAT 3.14159265358979323846f
|
||||
#define M_LN2_FLOAT 0.69314718055994530942f
|
||||
#define M_PI_FLOAT 3.14159265358979323846f
|
||||
|
||||
#define BIQUAD_BANDWIDTH 1.9f /* bandwidth in octaves */
|
||||
#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)
|
||||
float filterApplyPt1(float input, filterStatePt1_t *filter, float f_cut, float dT) {
|
||||
// PT1 Low Pass filter
|
||||
|
||||
// Pre calculate and store RC
|
||||
if (!filter->RC) {
|
||||
filter->RC = 1.0f / ( 2.0f * M_PI_FLOAT * f_cut );
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
filter->state = filter->state + dT / (filter->RC + dT) * (input - filter->state);
|
||||
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
|
||||
if (!filter->RC) {
|
||||
filter->RC = 1.0f / ( 2.0f * M_PI_FLOAT * f_cut );
|
||||
filter->dT = dT;
|
||||
}
|
||||
|
||||
filter->state = filter->state + filter->dT / (filter->RC + filter->dT) * (input - filter->state);
|
||||
|
||||
return filter->state;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
float omega, sn, cs, alpha;
|
||||
float a0, a1, a2, b0, b1, b2;
|
||||
|
||||
/* setup variables */
|
||||
omega = 2 * M_PI_FLOAT * filterCutFreq / sampleRate;
|
||||
sn = sinf(omega);
|
||||
cs = cosf(omega);
|
||||
// setup variables
|
||||
const float omega = 2 * M_PI_FLOAT * filterCutFreq / sampleRate;
|
||||
const float sn = sinf(omega);
|
||||
const float cs = cosf(omega);
|
||||
//this is wrong, should be hyperbolic sine
|
||||
//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;
|
||||
b1 = 1 - cs;
|
||||
b2 = (1 - cs) / 2;
|
||||
a0 = 1 + alpha;
|
||||
a1 = -2 * cs;
|
||||
a2 = 1 - alpha;
|
||||
const float b0 = (1 - cs) / 2;
|
||||
const float b1 = 1 - cs;
|
||||
const float b2 = (1 - cs) / 2;
|
||||
const float a0 = 1 + alpha;
|
||||
const float a1 = -2 * cs;
|
||||
const float a2 = 1 - alpha;
|
||||
|
||||
/* precompute the coefficients */
|
||||
newState->b0 = b0 / a0;
|
||||
newState->b1 = b1 / a0;
|
||||
newState->b2 = b2 / a0;
|
||||
newState->a1 = a1 / a0;
|
||||
newState->a2 = a2 / a0;
|
||||
// precompute the coefficients
|
||||
filter->b0 = b0 / a0;
|
||||
filter->b1 = b1 / a0;
|
||||
filter->b2 = b2 / a0;
|
||||
filter->a1 = a1 / a0;
|
||||
filter->a2 = a2 / a0;
|
||||
|
||||
/* zero initial samples */
|
||||
newState->d1 = newState->d2 = 1;
|
||||
// zero initial samples
|
||||
filter->d1 = filter->d2 = 0;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
result = state->b0 * sample + state->d1;
|
||||
state->d1 = state->b1 * sample - state->a1 * result + state->d2;
|
||||
state->d2 = state->b2 * sample - state->a2 * result;
|
||||
const float result = filter->b0 * input + filter->d1;
|
||||
filter->d1 = filter->b1 * input - filter->a1 * result + filter->d2;
|
||||
filter->d2 = filter->b2 * input - filter->a2 * result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,20 +17,26 @@
|
|||
|
||||
#define DELTA_MAX_SAMPLES 12
|
||||
|
||||
typedef struct filterStatePt1_s {
|
||||
float state;
|
||||
float RC;
|
||||
float constdT;
|
||||
} filterStatePt1_t;
|
||||
typedef struct pt1Filter_s {
|
||||
float state;
|
||||
float RC;
|
||||
float dT;
|
||||
} pt1Filter_t;
|
||||
|
||||
/* 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 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]);
|
||||
float filterApplyAveragef(float input, uint8_t averageCount, float averageState[DELTA_MAX_SAMPLES]);
|
||||
void BiQuadNewLpf(float filterCutFreq, biquad_t *newState, uint32_t refreshRate);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ int tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
|
|||
putf(putp, ch); written++;
|
||||
} else {
|
||||
char lz = 0;
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
char lng = 0;
|
||||
#endif
|
||||
int w = 0;
|
||||
|
@ -99,7 +99,7 @@ int tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
|
|||
if (ch >= '0' && ch <= '9') {
|
||||
ch = a2i(ch, &fmt, 10, &w);
|
||||
}
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
if (ch == 'l') {
|
||||
ch = *(fmt++);
|
||||
lng = 1;
|
||||
|
@ -109,7 +109,7 @@ int tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
|
|||
case 0:
|
||||
goto abort;
|
||||
case 'u':{
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
uli2a(va_arg(va, unsigned long int), 10, 0, bf);
|
||||
else
|
||||
|
@ -119,7 +119,7 @@ int tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
|
|||
break;
|
||||
}
|
||||
case 'd':{
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
li2a(va_arg(va, unsigned long int), bf);
|
||||
else
|
||||
|
@ -130,7 +130,7 @@ int tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
|
|||
}
|
||||
case 'x':
|
||||
case 'X':
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
#ifdef REQUIRE_PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf);
|
||||
else
|
||||
|
|
|
@ -66,10 +66,10 @@ To use the printf you need to supply your own character output function,
|
|||
something like :
|
||||
|
||||
void putc ( void* p, char c)
|
||||
{
|
||||
while (!SERIAL_PORT_EMPTY) ;
|
||||
SERIAL_PORT_TX_REGISTER = c;
|
||||
}
|
||||
{
|
||||
while (!SERIAL_PORT_EMPTY) ;
|
||||
SERIAL_PORT_TX_REGISTER = c;
|
||||
}
|
||||
|
||||
Before you can call printf you need to initialize it to use your
|
||||
character output function with something like:
|
||||
|
|
|
@ -56,7 +56,7 @@ http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html
|
|||
(32*((v)/2L>>31 > 0) \
|
||||
+ LOG2_32BIT((v)*1L >>16*((v)/2L>>31 > 0) \
|
||||
>>16*((v)/2L>>31 > 0)))
|
||||
|
||||
|
||||
#if 0
|
||||
// ISO C version, but no type checking
|
||||
#define container_of(ptr, type, member) \
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "drivers/timer.h"
|
||||
#include "drivers/pwm_rx.h"
|
||||
#include "drivers/serial.h"
|
||||
#include "drivers/gyro_sync.h"
|
||||
#include "drivers/pwm_output.h"
|
||||
#include "drivers/max7456.h"
|
||||
|
||||
|
@ -90,6 +89,7 @@
|
|||
#endif
|
||||
|
||||
void useRcControlsConfig(modeActivationCondition_t *modeActivationConditions, escAndServoConfig_t *escAndServoConfigToUse, pidProfile_t *pidProfileToUse);
|
||||
void targetConfiguration(void);
|
||||
|
||||
#if !defined(FLASH_SIZE)
|
||||
#error "Flash size not defined for target. (specify in KB)"
|
||||
|
@ -269,8 +269,13 @@ void resetSensorAlignment(sensorAlignmentConfig_t *sensorAlignmentConfig)
|
|||
|
||||
void resetEscAndServoConfig(escAndServoConfig_t *escAndServoConfig)
|
||||
{
|
||||
#ifdef BRUSHED_MOTORS
|
||||
escAndServoConfig->minthrottle = 1000;
|
||||
escAndServoConfig->maxthrottle = 2000;
|
||||
#else
|
||||
escAndServoConfig->minthrottle = 1150;
|
||||
escAndServoConfig->maxthrottle = 1850;
|
||||
#endif
|
||||
escAndServoConfig->mincommand = 1000;
|
||||
escAndServoConfig->servoCenterPulse = 1500;
|
||||
escAndServoConfig->escDesyncProtection = 0;
|
||||
|
@ -416,8 +421,6 @@ uint16_t getCurrentMinthrottle(void)
|
|||
// Default settings
|
||||
static void resetConf(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Clear all configuration
|
||||
memset(&masterConfig, 0, sizeof(master_t));
|
||||
setProfile(0);
|
||||
|
@ -478,7 +481,11 @@ static void resetConf(void)
|
|||
|
||||
resetTelemetryConfig(&masterConfig.telemetryConfig);
|
||||
|
||||
#ifdef SERIALRX_PROVIDER
|
||||
masterConfig.rxConfig.serialrx_provider = SERIALRX_PROVIDER;
|
||||
#else
|
||||
masterConfig.rxConfig.serialrx_provider = 0;
|
||||
#endif
|
||||
masterConfig.rxConfig.sbus_inversion = 1;
|
||||
masterConfig.rxConfig.spektrum_sat_bind = 0;
|
||||
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_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];
|
||||
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);
|
||||
|
@ -531,7 +538,7 @@ static void resetConf(void)
|
|||
masterConfig.motor_pwm_protocol = PWM_TYPE_ONESHOT125;
|
||||
#endif
|
||||
masterConfig.servo_pwm_rate = 50;
|
||||
|
||||
|
||||
#ifdef CC3D
|
||||
masterConfig.use_buzzer_p6 = 0;
|
||||
#endif
|
||||
|
@ -549,9 +556,8 @@ static void resetConf(void)
|
|||
masterConfig.emf_avoidance = 0; // TODO - needs removal
|
||||
|
||||
resetPidProfile(¤tProfile->pidProfile);
|
||||
|
||||
uint8_t rI;
|
||||
for (rI = 0; rI<MAX_RATEPROFILES; rI++) {
|
||||
|
||||
for (int rI = 0; rI<MAX_RATEPROFILES; rI++) {
|
||||
resetControlRateConfig(&masterConfig.profile[0].controlRateProfile[rI]);
|
||||
}
|
||||
resetRollAndPitchTrims(&masterConfig.accelerometerTrims);
|
||||
|
@ -582,7 +588,7 @@ static void resetConf(void)
|
|||
|
||||
#ifdef USE_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].max = DEFAULT_SERVO_MAX;
|
||||
masterConfig.servoConf[i].middle = DEFAULT_SERVO_MIDDLE;
|
||||
|
@ -601,8 +607,9 @@ static void resetConf(void)
|
|||
#endif
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#ifdef LED_STRIP
|
||||
applyDefaultColors(masterConfig.colors, CONFIGURABLE_COLOR_COUNT);
|
||||
|
@ -639,62 +646,19 @@ static void resetConf(void)
|
|||
masterConfig.blackbox_rate_denom = 1;
|
||||
|
||||
#endif // BLACKBOX
|
||||
|
||||
// alternative defaults settings for COLIBRI RACE targets
|
||||
#if defined(COLIBRI_RACE)
|
||||
masterConfig.escAndServoConfig.minthrottle = 1025;
|
||||
masterConfig.escAndServoConfig.maxthrottle = 1980;
|
||||
masterConfig.batteryConfig.vbatmaxcellvoltage = 45;
|
||||
masterConfig.batteryConfig.vbatmincellvoltage = 30;
|
||||
|
||||
#ifdef SERIALRX_UART
|
||||
if (featureConfigured(FEATURE_RX_SERIAL)) {
|
||||
masterConfig.serialConfig.portConfigs[SERIALRX_UART].functionMask = FUNCTION_RX_SERIAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_CONFIG)
|
||||
targetConfiguration(&masterConfig);
|
||||
#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;
|
||||
targetConfiguration();
|
||||
#endif
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
@ -751,7 +715,7 @@ void activateConfig(void)
|
|||
¤tProfile->pidProfile
|
||||
);
|
||||
|
||||
useGyroConfig(&masterConfig.gyroConfig, masterConfig.gyro_soft_lpf_hz);
|
||||
gyroUseConfig(&masterConfig.gyroConfig, masterConfig.gyro_soft_lpf_hz);
|
||||
|
||||
#ifdef TELEMETRY
|
||||
telemetryUseConfig(&masterConfig.telemetryConfig);
|
||||
|
@ -806,7 +770,7 @@ void activateConfig(void)
|
|||
void validateAndFixConfig(void)
|
||||
{
|
||||
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)) {
|
||||
|
@ -848,10 +812,10 @@ void validateAndFixConfig(void)
|
|||
if (featureConfigured(FEATURE_SOFTSERIAL) && (
|
||||
0
|
||||
#ifdef USE_SOFTSERIAL1
|
||||
|| (LED_STRIP_TIMER == SOFTSERIAL_1_TIMER)
|
||||
|| (WS2811_TIMER == SOFTSERIAL_1_TIMER)
|
||||
#endif
|
||||
#ifdef USE_SOFTSERIAL2
|
||||
|| (LED_STRIP_TIMER == SOFTSERIAL_2_TIMER)
|
||||
|| (WS2811_TIMER == SOFTSERIAL_2_TIMER)
|
||||
#endif
|
||||
)) {
|
||||
// led strip needs the same timer as softserial
|
||||
|
@ -871,7 +835,7 @@ void validateAndFixConfig(void)
|
|||
}
|
||||
#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)) {
|
||||
featureClear(FEATURE_DISPLAY);
|
||||
}
|
||||
|
@ -901,15 +865,11 @@ void validateAndFixConfig(void)
|
|||
|
||||
#if defined(COLIBRI_RACE)
|
||||
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_MSP);
|
||||
featureSet(FEATURE_RX_PPM);
|
||||
}
|
||||
if(featureConfigured(FEATURE_RX_SERIAL)) {
|
||||
masterConfig.serialConfig.portConfigs[2].functionMask = FUNCTION_RX_SERIAL;
|
||||
//masterConfig.rxConfig.serialrx_provider = SERIALRX_SBUS;
|
||||
}
|
||||
#endif
|
||||
|
||||
useRxConfig(&masterConfig.rxConfig);
|
||||
|
@ -1047,12 +1007,12 @@ void changeProfile(uint8_t profileIndex)
|
|||
}
|
||||
|
||||
void changeControlRateProfile(uint8_t profileIndex)
|
||||
{
|
||||
if (profileIndex > MAX_RATEPROFILES) {
|
||||
profileIndex = MAX_RATEPROFILES - 1;
|
||||
}
|
||||
setControlRateProfile(profileIndex);
|
||||
activateControlRateConfig();
|
||||
{
|
||||
if (profileIndex > MAX_RATEPROFILES) {
|
||||
profileIndex = MAX_RATEPROFILES - 1;
|
||||
}
|
||||
setControlRateProfile(profileIndex);
|
||||
activateControlRateConfig();
|
||||
}
|
||||
|
||||
void latchActiveFeatures()
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if FLASH_SIZE <= 128
|
||||
#define MAX_PROFILE_COUNT 2
|
||||
#else
|
||||
#define MAX_PROFILE_COUNT 3
|
||||
#endif
|
||||
#define MAX_RATEPROFILES 3
|
||||
#define ONESHOT_FEATURE_CHANGED_DELAY_ON_BOOT_MS 1500
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef struct gyro_s {
|
|||
sensorReadFuncPtr temperature; // read temperature if available
|
||||
sensorInterruptFuncPtr intStatus;
|
||||
float scale; // scalefactor
|
||||
uint32_t targetLooptime;
|
||||
} gyro_t;
|
||||
|
||||
typedef struct acc_s {
|
||||
|
|
|
@ -40,7 +40,7 @@ bool bma280Detect(acc_t *acc)
|
|||
bool ack = false;
|
||||
uint8_t sig = 0;
|
||||
|
||||
ack = i2cRead(MPU_I2C_INSTANCE, BMA280_ADDRESS, 0x00, 1, &sig);
|
||||
ack = i2cRead(MPU_I2C_INSTANCE, BMA280_ADDRESS, 0x00, 1, &sig);
|
||||
if (!ack || sig != 0xFB)
|
||||
return false;
|
||||
|
||||
|
@ -51,8 +51,8 @@ bool bma280Detect(acc_t *acc)
|
|||
|
||||
static void bma280Init(acc_t *acc)
|
||||
{
|
||||
i2cWrite(MPU_I2C_INSTANCE, BMA280_ADDRESS, BMA280_PMU_RANGE, 0x08); // +-8g range
|
||||
i2cWrite(MPU_I2C_INSTANCE, BMA280_ADDRESS, BMA280_PMU_BW, 0x0E); // 500Hz BW
|
||||
i2cWrite(MPU_I2C_INSTANCE, BMA280_ADDRESS, BMA280_PMU_RANGE, 0x08); // +-8g range
|
||||
i2cWrite(MPU_I2C_INSTANCE, BMA280_ADDRESS, BMA280_PMU_BW, 0x0E); // 500Hz BW
|
||||
|
||||
acc->acc_1G = 512 * 8;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ static bool bma280Read(int16_t *accelData)
|
|||
{
|
||||
uint8_t buf[6];
|
||||
|
||||
if (!i2cRead(MPU_I2C_INSTANCE, BMA280_ADDRESS, BMA280_ACC_X_LSB, 6, buf)) {
|
||||
if (!i2cRead(MPU_I2C_INSTANCE, BMA280_ADDRESS, BMA280_ACC_X_LSB, 6, buf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ bool l3g4200dDetect(gyro_t *gyro)
|
|||
|
||||
delay(25);
|
||||
|
||||
i2cRead(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_WHO_AM_I, 1, &deviceid);
|
||||
i2cRead(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_WHO_AM_I, 1, &deviceid);
|
||||
if (deviceid != L3G4200D_ID)
|
||||
return false;
|
||||
|
||||
|
@ -100,12 +100,12 @@ static void l3g4200dInit(uint8_t lpf)
|
|||
|
||||
delay(100);
|
||||
|
||||
ack = i2cWrite(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_CTRL_REG4, L3G4200D_FS_SEL_2000DPS);
|
||||
ack = i2cWrite(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_CTRL_REG4, L3G4200D_FS_SEL_2000DPS);
|
||||
if (!ack)
|
||||
failureMode(FAILURE_ACC_INIT);
|
||||
|
||||
delay(5);
|
||||
i2cWrite(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_CTRL_REG1, L3G4200D_POWER_ON | mpuLowPassFilter);
|
||||
i2cWrite(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_CTRL_REG1, L3G4200D_POWER_ON | mpuLowPassFilter);
|
||||
}
|
||||
|
||||
// Read 3 gyro values into user-provided buffer. No overrun checking is done.
|
||||
|
@ -113,7 +113,7 @@ static bool l3g4200dRead(int16_t *gyroADC)
|
|||
{
|
||||
uint8_t buf[6];
|
||||
|
||||
if (!i2cRead(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_AUTOINCR | L3G4200D_GYRO_OUT, 6, buf)) {
|
||||
if (!i2cRead(MPU_I2C_INSTANCE, L3G4200D_ADDRESS, L3G4200D_AUTOINCR | L3G4200D_GYRO_OUT, 6, buf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
#define BLOCK_DATA_UPDATE_CONTINUOUS ((uint8_t)0x00)
|
||||
|
||||
#define BLE_MSB ((uint8_t)0x40)
|
||||
#define BLE_MSB ((uint8_t)0x40)
|
||||
|
||||
#define BOOT ((uint8_t)0x80)
|
||||
|
||||
|
@ -76,7 +76,7 @@ static void l3gd20SpiInit(SPI_TypeDef *SPIx)
|
|||
UNUSED(SPIx); // FIXME
|
||||
|
||||
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);
|
||||
|
||||
DISABLE_L3GD20;
|
||||
|
|
|
@ -19,14 +19,13 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "common/maths.h"
|
||||
#include "common/axis.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "bus_i2c.h"
|
||||
|
||||
#include "sensor.h"
|
||||
|
@ -115,15 +114,15 @@ int32_t accelSummedSamples500Hz[3];
|
|||
|
||||
void lsm303dlhcAccInit(acc_t *acc)
|
||||
{
|
||||
i2cWrite(MPU_I2C_INSTANCE, LSM303DLHC_ACCEL_ADDRESS, CTRL_REG5_A, BOOT);
|
||||
i2cWrite(MPU_I2C_INSTANCE, LSM303DLHC_ACCEL_ADDRESS, CTRL_REG5_A, BOOT);
|
||||
|
||||
delay(100);
|
||||
|
||||
i2cWrite(MPU_I2C_INSTANCE, LSM303DLHC_ACCEL_ADDRESS, CTRL_REG1_A, ODR_1344_HZ | AXES_ENABLE);
|
||||
i2cWrite(MPU_I2C_INSTANCE, LSM303DLHC_ACCEL_ADDRESS, CTRL_REG1_A, ODR_1344_HZ | AXES_ENABLE);
|
||||
|
||||
delay(10);
|
||||
|
||||
i2cWrite(MPU_I2C_INSTANCE, LSM303DLHC_ACCEL_ADDRESS, CTRL_REG4_A, FULLSCALE_4G);
|
||||
i2cWrite(MPU_I2C_INSTANCE, LSM303DLHC_ACCEL_ADDRESS, CTRL_REG4_A, FULLSCALE_4G);
|
||||
|
||||
delay(100);
|
||||
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
*/
|
||||
|
||||
/* LSM303DLHC ACC struct */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t Power_Mode; /* Power-down/Normal Mode */
|
||||
uint8_t AccOutput_DataRate; /* OUT data rate */
|
||||
uint8_t Axes_Enable; /* Axes enable */
|
||||
|
@ -31,25 +30,23 @@ typedef struct
|
|||
uint8_t BlockData_Update; /* Block Data Update */
|
||||
uint8_t Endianness; /* Endian Data selection */
|
||||
uint8_t AccFull_Scale; /* Full Scale selection */
|
||||
}LSM303DLHCAcc_InitTypeDef;
|
||||
} LSM303DLHCAcc_InitTypeDef;
|
||||
|
||||
/* LSM303DLHC Acc High Pass Filter struct */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t HighPassFilter_Mode_Selection; /* Internal filter mode */
|
||||
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_AOI2; /* HPF_enabling/disabling for AOI function on interrupt 2 */
|
||||
}LSM303DLHCAcc_FilterConfigTypeDef;
|
||||
} LSM303DLHCAcc_FilterConfigTypeDef;
|
||||
|
||||
/* LSM303DLHC Mag struct */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t Temperature_Sensor; /* Temperature sensor enable/disable */
|
||||
uint8_t MagOutput_DataRate; /* OUT data rate */
|
||||
uint8_t Working_Mode; /* operating mode */
|
||||
uint8_t MagFull_Scale; /* Full Scale selection */
|
||||
}LSM303DLHCMag_InitTypeDef;
|
||||
} LSM303DLHCMag_InitTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -78,43 +75,11 @@ typedef struct
|
|||
* @brief LSM303DLHC I2C Interface pins
|
||||
*/
|
||||
#define LSM303DLHC_I2C I2C1
|
||||
#define LSM303DLHC_I2C_CLK RCC_APB1Periph_I2C1
|
||||
|
||||
#define LSM303DLHC_I2C_SCK_PIN GPIO_Pin_6 /* PB.06 */
|
||||
#define LSM303DLHC_I2C_SCK_GPIO_PORT GPIOB /* GPIOB */
|
||||
#define LSM303DLHC_I2C_SCK_GPIO_CLK RCC_AHBPeriph_GPIOB
|
||||
#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
|
||||
#define LSM303DLHC_I2C_SCK_PIN PB6 /* PB.06 */
|
||||
#define LSM303DLHC_I2C_SDA_PIN PB7 /* PB.7 */
|
||||
#define LSM303DLHC_DRDY_PIN PE2 /* PE.02 */
|
||||
#define LSM303DLHC_I2C_INT1_PIN PE4 /* PE.04 */
|
||||
#define LSM303DLHC_I2C_INT2_PIN PE5 /* PE.05 */
|
||||
|
||||
/******************************************************************************/
|
||||
/*************************** START REGISTER MAPPING **************************/
|
||||
|
|
|
@ -89,7 +89,7 @@ bool mma8452Detect(acc_t *acc)
|
|||
bool ack = false;
|
||||
uint8_t sig = 0;
|
||||
|
||||
ack = i2cRead(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_WHO_AM_I, 1, &sig);
|
||||
ack = i2cRead(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_WHO_AM_I, 1, &sig);
|
||||
if (!ack || (sig != MMA8452_DEVICE_SIGNATURE && sig != MMA8451_DEVICE_SIGNATURE))
|
||||
return false;
|
||||
|
||||
|
@ -105,13 +105,13 @@ static inline void mma8451ConfigureInterrupt(void)
|
|||
// PA5 - ACC_INT2 output on NAZE rev3/4 hardware
|
||||
// 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.
|
||||
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 ?
|
||||
#endif
|
||||
|
||||
i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG3, MMA8452_CTRL_REG3_IPOL); // Interrupt polarity (active HIGH)
|
||||
i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG4, MMA8452_CTRL_REG4_INT_EN_DRDY); // Enable DRDY interrupt (unused by this driver)
|
||||
i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG5, 0); // DRDY routed to INT2
|
||||
i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG3, MMA8452_CTRL_REG3_IPOL); // Interrupt polarity (active HIGH)
|
||||
i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG4, MMA8452_CTRL_REG4_INT_EN_DRDY); // Enable DRDY interrupt (unused by this driver)
|
||||
i2cWrite(MPU_I2C_INSTANCE, MMA8452_ADDRESS, MMA8452_CTRL_REG5, 0); // DRDY routed to INT2
|
||||
}
|
||||
|
||||
static void mma8452Init(acc_t *acc)
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "gpio.h"
|
||||
#include "exti.h"
|
||||
#include "bus_i2c.h"
|
||||
#include "gyro_sync.h"
|
||||
|
||||
#include "sensor.h"
|
||||
#include "accgyro.h"
|
||||
|
@ -166,7 +165,7 @@ static bool detectSPISensorsAndUpdateDetectionResult(void)
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -228,43 +227,43 @@ void mpuIntExtiHandler(extiCallbackRec_t *cb)
|
|||
|
||||
void mpuIntExtiInit(void)
|
||||
{
|
||||
static bool mpuExtiInitDone = false;
|
||||
static bool mpuExtiInitDone = false;
|
||||
|
||||
if (mpuExtiInitDone || !mpuIntExtiConfig) {
|
||||
return;
|
||||
}
|
||||
if (mpuExtiInitDone || !mpuIntExtiConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(USE_MPU_DATA_READY_SIGNAL) && defined(USE_EXTI)
|
||||
|
||||
IO_t mpuIntIO = IOGetByTag(mpuIntExtiConfig->tag);
|
||||
|
||||
IO_t mpuIntIO = IOGetByTag(mpuIntExtiConfig->tag);
|
||||
|
||||
#ifdef ENSURE_MPU_DATA_READY_IS_LOW
|
||||
uint8_t status = IORead(mpuIntIO);
|
||||
if (status) {
|
||||
return;
|
||||
}
|
||||
uint8_t status = IORead(mpuIntIO);
|
||||
if (status) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
IOInit(mpuIntIO, OWNER_SYSTEM, RESOURCE_INPUT | RESOURCE_EXTI);
|
||||
IOConfigGPIO(mpuIntIO, IOCFG_IN_FLOATING); // TODO - maybe pullup / pulldown ?
|
||||
IOInit(mpuIntIO, OWNER_MPU, RESOURCE_EXTI, 0);
|
||||
IOConfigGPIO(mpuIntIO, IOCFG_IN_FLOATING); // TODO - maybe pullup / pulldown ?
|
||||
|
||||
EXTIHandlerInit(&mpuIntCallbackRec, mpuIntExtiHandler);
|
||||
EXTIConfig(mpuIntIO, &mpuIntCallbackRec, NVIC_PRIO_MPU_INT_EXTI, EXTI_Trigger_Rising);
|
||||
EXTIEnable(mpuIntIO, true);
|
||||
EXTIHandlerInit(&mpuIntCallbackRec, mpuIntExtiHandler);
|
||||
EXTIConfig(mpuIntIO, &mpuIntCallbackRec, NVIC_PRIO_MPU_INT_EXTI, EXTI_Trigger_Rising);
|
||||
EXTIEnable(mpuIntIO, true);
|
||||
#endif
|
||||
|
||||
mpuExtiInitDone = true;
|
||||
|
||||
mpuExtiInitDone = true;
|
||||
}
|
||||
|
||||
static bool mpuReadRegisterI2C(uint8_t reg, uint8_t length, uint8_t* data)
|
||||
{
|
||||
bool ack = i2cRead(MPU_I2C_INSTANCE, MPU_ADDRESS, reg, length, data);
|
||||
bool ack = i2cRead(MPU_I2C_INSTANCE, MPU_ADDRESS, reg, length, data);
|
||||
return ack;
|
||||
}
|
||||
|
||||
static bool mpuWriteRegisterI2C(uint8_t reg, uint8_t data)
|
||||
{
|
||||
bool ack = i2cWrite(MPU_I2C_INSTANCE, MPU_ADDRESS, reg, data);
|
||||
bool ack = i2cWrite(MPU_I2C_INSTANCE, MPU_ADDRESS, reg, data);
|
||||
return ack;
|
||||
}
|
||||
|
||||
|
@ -300,11 +299,14 @@ bool mpuGyroRead(int16_t *gyroADC)
|
|||
return true;
|
||||
}
|
||||
|
||||
void checkMPUDataReady(bool *mpuDataReadyPtr) {
|
||||
bool checkMPUDataReady(void)
|
||||
{
|
||||
bool ret;
|
||||
if (mpuDataReady) {
|
||||
*mpuDataReadyPtr = true;
|
||||
ret = true;
|
||||
mpuDataReady= false;
|
||||
} else {
|
||||
*mpuDataReadyPtr = false;
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "exti.h"
|
||||
|
||||
// MPU6050
|
||||
#define MPU_RA_WHO_AM_I 0x75
|
||||
#define MPU_RA_WHO_AM_I_LEGACY 0x00
|
||||
|
@ -120,12 +122,12 @@ typedef bool (*mpuWriteRegisterFunc)(uint8_t reg, uint8_t data);
|
|||
typedef void(*mpuResetFuncPtr)(void);
|
||||
|
||||
typedef struct mpuConfiguration_s {
|
||||
uint8_t gyroReadXRegister; // Y and Z must registers follow this, 2 words each
|
||||
mpuReadRegisterFunc read;
|
||||
mpuWriteRegisterFunc write;
|
||||
mpuReadRegisterFunc slowread;
|
||||
mpuWriteRegisterFunc verifywrite;
|
||||
mpuResetFuncPtr reset;
|
||||
uint8_t gyroReadXRegister; // Y and Z must registers follow this, 2 words each
|
||||
mpuReadRegisterFunc read;
|
||||
mpuWriteRegisterFunc write;
|
||||
mpuReadRegisterFunc slowread;
|
||||
mpuWriteRegisterFunc verifywrite;
|
||||
mpuResetFuncPtr reset;
|
||||
} mpuConfiguration_t;
|
||||
|
||||
extern mpuConfiguration_t mpuConfiguration;
|
||||
|
@ -185,4 +187,4 @@ void mpuIntExtiInit(void);
|
|||
bool mpuAccRead(int16_t *accData);
|
||||
bool mpuGyroRead(int16_t *gyroADC);
|
||||
mpuDetectionResult_t *detectMpu(const extiConfig_t *configToUse);
|
||||
void checkMPUDataReady(bool *mpuDataReadyPtr);
|
||||
bool checkMPUDataReady(void);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "accgyro.h"
|
||||
#include "accgyro_mpu.h"
|
||||
#include "accgyro_mpu3050.h"
|
||||
#include "gyro_sync.h"
|
||||
|
||||
// MPU3050, Standard address 0x68
|
||||
#define MPU3050_ADDRESS 0x68
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
|
@ -38,8 +38,6 @@
|
|||
#include "accgyro_mpu.h"
|
||||
#include "accgyro_mpu6050.h"
|
||||
|
||||
extern uint8_t mpuLowPassFilter;
|
||||
|
||||
//#define DEBUG_MPU_DATA_READY_INTERRUPT
|
||||
|
||||
// MPU6050, Standard address 0x68
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -41,6 +40,9 @@
|
|||
#include "sensor.h"
|
||||
#include "accgyro.h"
|
||||
#include "accgyro_mpu.h"
|
||||
|
||||
#if defined(USE_GYRO_SPI_MPU6000) || defined(USE_ACC_SPI_MPU6000)
|
||||
|
||||
#include "accgyro_spi_mpu6000.h"
|
||||
|
||||
static void mpu6000AccAndGyroInit(void);
|
||||
|
@ -49,12 +51,12 @@ static bool mpuSpi6000InitDone = false;
|
|||
|
||||
|
||||
// Bits
|
||||
#define BIT_SLEEP 0x40
|
||||
#define BIT_H_RESET 0x80
|
||||
#define BITS_CLKSEL 0x07
|
||||
#define MPU_CLK_SEL_PLLGYROX 0x01
|
||||
#define MPU_CLK_SEL_PLLGYROZ 0x03
|
||||
#define MPU_EXT_SYNC_GYROX 0x02
|
||||
#define BIT_SLEEP 0x40
|
||||
#define BIT_H_RESET 0x80
|
||||
#define BITS_CLKSEL 0x07
|
||||
#define MPU_CLK_SEL_PLLGYROX 0x01
|
||||
#define MPU_CLK_SEL_PLLGYROZ 0x03
|
||||
#define MPU_EXT_SYNC_GYROX 0x02
|
||||
#define BITS_FS_250DPS 0x00
|
||||
#define BITS_FS_500DPS 0x08
|
||||
#define BITS_FS_1000DPS 0x10
|
||||
|
@ -74,9 +76,9 @@ static bool mpuSpi6000InitDone = false;
|
|||
#define BITS_DLPF_CFG_2100HZ_NOLPF 0x07
|
||||
#define BITS_DLPF_CFG_MASK 0x07
|
||||
#define BIT_INT_ANYRD_2CLEAR 0x10
|
||||
#define BIT_RAW_RDY_EN 0x01
|
||||
#define BIT_RAW_RDY_EN 0x01
|
||||
#define BIT_I2C_IF_DIS 0x10
|
||||
#define BIT_INT_STATUS_DATA 0x01
|
||||
#define BIT_INT_STATUS_DATA 0x01
|
||||
#define BIT_GYRO 3
|
||||
#define BIT_ACC 2
|
||||
#define BIT_TEMP 1
|
||||
|
@ -156,12 +158,12 @@ bool mpu6000SpiDetect(void)
|
|||
uint8_t in;
|
||||
uint8_t attemptsRemaining = 5;
|
||||
|
||||
#ifdef MPU6000_CS_PIN
|
||||
#ifdef MPU6000_CS_PIN
|
||||
mpuSpi6000CsPin = IOGetByTag(IO_TAG(MPU6000_CS_PIN));
|
||||
#endif
|
||||
IOInit(mpuSpi6000CsPin, OWNER_SYSTEM, RESOURCE_SPI);
|
||||
IOInit(mpuSpi6000CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(mpuSpi6000CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
|
||||
spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON);
|
||||
|
||||
mpu6000WriteRegister(MPU_RA_PWR_MGMT_1, BIT_H_RESET);
|
||||
|
@ -283,3 +285,5 @@ bool mpu6000SpiGyroDetect(gyro_t *gyro)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define MPU6000_CONFIG 0x1A
|
||||
#define MPU6000_CONFIG 0x1A
|
||||
|
||||
#define BITS_DLPF_CFG_256HZ 0x00
|
||||
#define BITS_DLPF_CFG_188HZ 0x01
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -69,10 +68,10 @@ static void mpu6500SpiInit(void)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
|
||||
hardwareInitialised = true;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "light_led.h"
|
||||
|
@ -64,7 +63,7 @@ void mpu9250ResetGyro(void)
|
|||
|
||||
bool mpu9250WriteRegister(uint8_t reg, uint8_t data)
|
||||
{
|
||||
ENABLE_MPU9250;
|
||||
ENABLE_MPU9250;
|
||||
delayMicroseconds(1);
|
||||
spiTransferByte(MPU9250_SPI_INSTANCE, reg);
|
||||
spiTransferByte(MPU9250_SPI_INSTANCE, data);
|
||||
|
@ -76,7 +75,7 @@ bool mpu9250WriteRegister(uint8_t reg, uint8_t data)
|
|||
|
||||
bool mpu9250ReadRegister(uint8_t reg, uint8_t length, uint8_t *data)
|
||||
{
|
||||
ENABLE_MPU9250;
|
||||
ENABLE_MPU9250;
|
||||
spiTransferByte(MPU9250_SPI_INSTANCE, reg | 0x80); // read transaction
|
||||
spiTransfer(MPU9250_SPI_INSTANCE, data, NULL, length);
|
||||
DISABLE_MPU9250;
|
||||
|
@ -86,7 +85,7 @@ bool mpu9250ReadRegister(uint8_t reg, uint8_t length, uint8_t *data)
|
|||
|
||||
bool mpu9250SlowReadRegister(uint8_t reg, uint8_t length, uint8_t *data)
|
||||
{
|
||||
ENABLE_MPU9250;
|
||||
ENABLE_MPU9250;
|
||||
delayMicroseconds(1);
|
||||
spiTransferByte(MPU9250_SPI_INSTANCE, reg | 0x80); // read transaction
|
||||
spiTransfer(MPU9250_SPI_INSTANCE, data, NULL, length);
|
||||
|
@ -98,7 +97,7 @@ bool mpu9250SlowReadRegister(uint8_t reg, uint8_t length, uint8_t *data)
|
|||
|
||||
void mpu9250SpiGyroInit(uint8_t lpf)
|
||||
{
|
||||
(void)(lpf);
|
||||
(void)(lpf);
|
||||
|
||||
mpuIntExtiInit();
|
||||
|
||||
|
@ -126,55 +125,55 @@ void mpu9250SpiAccInit(acc_t *acc)
|
|||
|
||||
bool verifympu9250WriteRegister(uint8_t reg, uint8_t data)
|
||||
{
|
||||
uint8_t in;
|
||||
uint8_t attemptsRemaining = 20;
|
||||
uint8_t in;
|
||||
uint8_t attemptsRemaining = 20;
|
||||
|
||||
mpu9250WriteRegister(reg, data);
|
||||
delayMicroseconds(100);
|
||||
mpu9250WriteRegister(reg, data);
|
||||
delayMicroseconds(100);
|
||||
|
||||
do {
|
||||
mpu9250SlowReadRegister(reg, 1, &in);
|
||||
if (in == data) {
|
||||
return true;
|
||||
} else {
|
||||
debug[3]++;
|
||||
mpu9250WriteRegister(reg, data);
|
||||
delayMicroseconds(100);
|
||||
}
|
||||
mpu9250SlowReadRegister(reg, 1, &in);
|
||||
if (in == data) {
|
||||
return true;
|
||||
} else {
|
||||
debug[3]++;
|
||||
mpu9250WriteRegister(reg, data);
|
||||
delayMicroseconds(100);
|
||||
}
|
||||
} while (attemptsRemaining--);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void mpu9250AccAndGyroInit(uint8_t lpf) {
|
||||
|
||||
if (mpuSpi9250InitDone) {
|
||||
return;
|
||||
}
|
||||
if (mpuSpi9250InitDone) {
|
||||
return;
|
||||
}
|
||||
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); //low speed for writing to slow registers
|
||||
|
||||
mpu9250WriteRegister(MPU_RA_PWR_MGMT_1, MPU9250_BIT_RESET);
|
||||
delay(50);
|
||||
delay(50);
|
||||
|
||||
verifympu9250WriteRegister(MPU_RA_PWR_MGMT_1, INV_CLK_PLL);
|
||||
verifympu9250WriteRegister(MPU_RA_PWR_MGMT_1, INV_CLK_PLL);
|
||||
|
||||
verifympu9250WriteRegister(MPU_RA_GYRO_CONFIG, INV_FSR_2000DPS << 3 | FCB_DISABLED); //Fchoice_b defaults to 00 which makes fchoice 11
|
||||
verifympu9250WriteRegister(MPU_RA_GYRO_CONFIG, INV_FSR_2000DPS << 3 | FCB_DISABLED); //Fchoice_b defaults to 00 which makes fchoice 11
|
||||
|
||||
if (lpf == 4) {
|
||||
verifympu9250WriteRegister(MPU_RA_CONFIG, 1); //1KHz, 184DLPF
|
||||
verifympu9250WriteRegister(MPU_RA_CONFIG, 1); //1KHz, 184DLPF
|
||||
} else if (lpf < 4) {
|
||||
verifympu9250WriteRegister(MPU_RA_CONFIG, 7); //8KHz, 3600DLPF
|
||||
verifympu9250WriteRegister(MPU_RA_CONFIG, 7); //8KHz, 3600DLPF
|
||||
} else if (lpf > 4) {
|
||||
verifympu9250WriteRegister(MPU_RA_CONFIG, 0); //8KHz, 250DLPF
|
||||
verifympu9250WriteRegister(MPU_RA_CONFIG, 0); //8KHz, 250DLPF
|
||||
}
|
||||
|
||||
verifympu9250WriteRegister(MPU_RA_SMPLRT_DIV, gyroMPU6xxxGetDividerDrops()); // Get Divider Drops
|
||||
verifympu9250WriteRegister(MPU_RA_SMPLRT_DIV, gyroMPU6xxxGetDividerDrops()); // Get Divider Drops
|
||||
|
||||
verifympu9250WriteRegister(MPU_RA_ACCEL_CONFIG, INV_FSR_8G << 3);
|
||||
verifympu9250WriteRegister(MPU_RA_INT_PIN_CFG, 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0); // INT_ANYRD_2CLEAR, BYPASS_EN
|
||||
verifympu9250WriteRegister(MPU_RA_ACCEL_CONFIG, INV_FSR_8G << 3);
|
||||
verifympu9250WriteRegister(MPU_RA_INT_PIN_CFG, 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 1 << 1 | 0 << 0); // INT_ANYRD_2CLEAR, BYPASS_EN
|
||||
|
||||
#if defined(USE_MPU_DATA_READY_SIGNAL)
|
||||
verifympu9250WriteRegister(MPU_RA_INT_ENABLE, 0x01); //this resets register MPU_RA_PWR_MGMT_1 and won't read back correctly.
|
||||
verifympu9250WriteRegister(MPU_RA_INT_ENABLE, 0x01); //this resets register MPU_RA_PWR_MGMT_1 and won't read back correctly.
|
||||
#endif
|
||||
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_FAST);
|
||||
|
@ -191,10 +190,10 @@ bool mpu9250SpiDetect(void)
|
|||
#ifdef MPU9250_CS_PIN
|
||||
mpuSpi9250CsPin = IOGetByTag(IO_TAG(MPU9250_CS_PIN));
|
||||
#endif
|
||||
IOInit(mpuSpi9250CsPin, OWNER_SYSTEM, RESOURCE_SPI);
|
||||
IOConfigGPIO(mpuSpi9250CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); //low speed
|
||||
IOInit(mpuSpi9250CsPin, OWNER_MPU, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(mpuSpi9250CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
spiSetDivisor(MPU9250_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); //low speed
|
||||
mpu9250WriteRegister(MPU_RA_PWR_MGMT_1, MPU9250_BIT_RESET);
|
||||
|
||||
do {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define mpu9250_CONFIG 0x1A
|
||||
#define mpu9250_CONFIG 0x1A
|
||||
|
||||
/* We should probably use these. :)
|
||||
#define BITS_DLPF_CFG_256HZ 0x00
|
||||
|
|
|
@ -35,11 +35,11 @@ volatile uint16_t adcValues[ADC_CHANNEL_COUNT];
|
|||
|
||||
uint8_t adcChannelByTag(ioTag_t ioTag)
|
||||
{
|
||||
for (uint8_t i = 0; i < ARRAYLEN(adcTagMap); i++) {
|
||||
if (ioTag == adcTagMap[i].tag)
|
||||
return adcTagMap[i].channel;
|
||||
}
|
||||
return 0;
|
||||
for (uint8_t i = 0; i < ARRAYLEN(adcTagMap); i++) {
|
||||
if (ioTag == adcTagMap[i].tag)
|
||||
return adcTagMap[i].channel;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t adcGetChannel(uint8_t channel)
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "io.h"
|
||||
|
||||
typedef enum {
|
||||
ADC_BATTERY = 0,
|
||||
ADC_RSSI = 1,
|
||||
|
@ -28,6 +30,7 @@ typedef enum {
|
|||
#define ADC_CHANNEL_COUNT (ADC_CHANNEL_MAX + 1)
|
||||
|
||||
typedef struct adc_config_s {
|
||||
ioTag_t tag;
|
||||
uint8_t adcChannel; // ADC1_INxx channel number
|
||||
uint8_t dmaIndex; // index into DMA buffer in case of sparse channels
|
||||
bool enabled;
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef enum ADCDevice {
|
|||
#elif defined(STM32F4)
|
||||
ADCDEV_2,
|
||||
ADCDEV_3,
|
||||
ADCDEV_MAX = ADCDEV_3,
|
||||
ADCDEV_MAX = ADCDEV_3,
|
||||
#else
|
||||
ADCDEV_MAX = ADCDEV_1,
|
||||
#endif
|
||||
|
@ -47,7 +47,7 @@ typedef struct adcTagMap_s {
|
|||
ioTag_t tag;
|
||||
uint8_t channel;
|
||||
} adcTagMap_t;
|
||||
|
||||
|
||||
typedef struct adcDevice_s {
|
||||
ADC_TypeDef* ADCx;
|
||||
rccPeriphTag_t rccADC;
|
||||
|
|
|
@ -79,9 +79,9 @@ const adcTagMap_t adcTagMap[] = {
|
|||
|
||||
void adcInit(drv_adc_config_t *init)
|
||||
{
|
||||
|
||||
|
||||
#if !defined(VBAT_ADC_PIN) && !defined(EXTERNAL1_ADC_PIN) && !defined(RSSI_ADC_PIN) && !defined(CURRENT_METER_ADC_PIN)
|
||||
UNUSED(init);
|
||||
UNUSED(init);
|
||||
#endif
|
||||
|
||||
uint8_t i;
|
||||
|
@ -91,59 +91,49 @@ void adcInit(drv_adc_config_t *init)
|
|||
|
||||
#ifdef VBAT_ADC_PIN
|
||||
if (init->enableVBat) {
|
||||
IOInit(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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;
|
||||
adcConfig[ADC_BATTERY].tag = IO_TAG(VBAT_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RSSI_ADC_PIN
|
||||
if (init->enableRSSI) {
|
||||
IOInit(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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;
|
||||
adcConfig[ADC_RSSI].tag = IO_TAG(RSSI_ADC_PIN);
|
||||
}
|
||||
#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_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;
|
||||
adcConfig[ADC_EXTERNAL1].tag = IO_TAG(EXTERNAL1_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CURRENT_METER_ADC_PIN
|
||||
if (init->enableCurrentMeter) {
|
||||
IOInit(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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;
|
||||
adcConfig[ADC_CURRENT].tag = IO_TAG(CURRENT_METER_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
ADCDevice device = adcDeviceByInstance(ADC_INSTANCE);
|
||||
if (device == ADCINVALID)
|
||||
return;
|
||||
|
||||
|
||||
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_ClockCmd(adc.rccADC, 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_InitTypeDef DMA_InitStructure;
|
||||
|
|
|
@ -107,61 +107,45 @@ void adcInit(drv_adc_config_t *init)
|
|||
|
||||
#ifdef VBAT_ADC_PIN
|
||||
if (init->enableVBat) {
|
||||
IOInit(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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++;
|
||||
adcConfig[ADC_BATTERY].tag = IO_TAG(VBAT_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RSSI_ADC_PIN
|
||||
if (init->enableRSSI) {
|
||||
IOInit(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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++;
|
||||
adcConfig[ADC_RSSI].tag = IO_TAG(RSSI_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CURRENT_METER_ADC_GPIO
|
||||
#ifdef CURRENT_METER_ADC_PIN
|
||||
if (init->enableCurrentMeter) {
|
||||
IOInit(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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++;
|
||||
adcConfig[ADC_CURRENT].tag = IO_TAG(CURRENT_METER_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL1_ADC_GPIO
|
||||
#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));
|
||||
adcConfig[ADC_EXTERNAL1].dmaIndex = adcChannelCount;
|
||||
adcConfig[ADC_EXTERNAL1].sampleTime = ADC_SampleTime_601Cycles5;
|
||||
adcConfig[ADC_EXTERNAL1].enabled = true;
|
||||
adcChannelCount++;
|
||||
adcConfig[ADC_EXTERNAL1].tag = IO_TAG(EXTERNAL1_ADC_PIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
ADCDevice device = adcDeviceByInstance(ADC_INSTANCE);
|
||||
if (device == ADCINVALID)
|
||||
return;
|
||||
|
||||
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_ClockCmd(adc.rccADC, ENABLE);
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
#endif
|
||||
|
||||
const adcDevice_t adcHardware[] = {
|
||||
{ .ADCx = ADC1, .rccADC = RCC_APB2(ADC1), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream4, .channel = DMA_Channel_0 },
|
||||
//{ .ADCx = ADC2, .rccADC = RCC_APB2(ADC2), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream1, .channel = DMA_Channel_0 }
|
||||
{ .ADCx = ADC1, .rccADC = RCC_APB2(ADC1), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream4, .channel = DMA_Channel_0 },
|
||||
//{ .ADCx = ADC2, .rccADC = RCC_APB2(ADC2), .rccDMA = RCC_AHB1(DMA2), .DMAy_Streamx = DMA2_Stream1, .channel = DMA_Channel_0 }
|
||||
};
|
||||
|
||||
/* note these could be packed up for saving space */
|
||||
|
@ -70,18 +70,18 @@ const adcTagMap_t adcTagMap[] = {
|
|||
{ DEFIO_TAG_E__PA4, ADC_Channel_4 },
|
||||
{ DEFIO_TAG_E__PA5, ADC_Channel_5 },
|
||||
{ DEFIO_TAG_E__PA6, ADC_Channel_6 },
|
||||
{ DEFIO_TAG_E__PA7, ADC_Channel_7 },
|
||||
{ DEFIO_TAG_E__PA7, ADC_Channel_7 },
|
||||
};
|
||||
|
||||
ADCDevice adcDeviceByInstance(ADC_TypeDef *instance)
|
||||
{
|
||||
if (instance == ADC1)
|
||||
return ADCDEV_1;
|
||||
if (instance == ADC1)
|
||||
return ADCDEV_1;
|
||||
/*
|
||||
if (instance == ADC2) // TODO add ADC2 and 3
|
||||
return ADCDEV_2;
|
||||
if (instance == ADC2) // TODO add ADC2 and 3
|
||||
return ADCDEV_2;
|
||||
*/
|
||||
return ADCINVALID;
|
||||
return ADCINVALID;
|
||||
}
|
||||
|
||||
void adcInit(drv_adc_config_t *init)
|
||||
|
@ -100,56 +100,48 @@ void adcInit(drv_adc_config_t *init)
|
|||
|
||||
#ifdef VBAT_ADC_PIN
|
||||
if (init->enableVBat) {
|
||||
IOInit(IOGetByTag(IO_TAG(VBAT_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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;
|
||||
adcConfig[ADC_BATTERY].tag = IO_TAG(VBAT_ADC_PIN); //VBAT_ADC_CHANNEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RSSI_ADC_PIN
|
||||
if (init->enableRSSI) {
|
||||
IOInit(IOGetByTag(IO_TAG(RSSI_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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;
|
||||
adcConfig[ADC_RSSI].dmaIndex = configuredAdcChannels++;
|
||||
adcConfig[ADC_RSSI].enabled = true;
|
||||
adcConfig[ADC_RSSI].sampleTime = ADC_SampleTime_480Cycles;
|
||||
adcConfig[ADC_RSSI].tag = IO_TAG(RSSI_ADC_PIN); //RSSI_ADC_CHANNEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL1_ADC_PIN
|
||||
if (init->enableExternal1) {
|
||||
adcConfig[ADC_EXTERNAL1].tag = IO_TAG(EXTERNAL1_ADC_PIN); //EXTERNAL1_ADC_CHANNEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CURRENT_METER_ADC_PIN
|
||||
if (init->enableCurrentMeter) {
|
||||
IOInit(IOGetByTag(IO_TAG(CURRENT_METER_ADC_PIN)), OWNER_SYSTEM, RESOURCE_ADC);
|
||||
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;
|
||||
adcConfig[ADC_CURRENT].tag = IO_TAG(CURRENT_METER_ADC_PIN); //CURRENT_METER_ADC_CHANNEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div256); // 72 MHz divided by 256 = 281.25 kHz
|
||||
|
||||
|
||||
ADCDevice device = adcDeviceByInstance(ADC_INSTANCE);
|
||||
if (device == ADCINVALID)
|
||||
return;
|
||||
|
||||
|
||||
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.rccADC, ENABLE);
|
||||
|
||||
|
@ -174,21 +166,21 @@ void adcInit(drv_adc_config_t *init)
|
|||
ADC_CommonInitTypeDef ADC_CommonInitStructure;
|
||||
|
||||
ADC_CommonStructInit(&ADC_CommonInitStructure);
|
||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
|
||||
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
||||
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
|
||||
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
|
||||
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
|
||||
ADC_CommonInit(&ADC_CommonInitStructure);
|
||||
|
||||
ADC_StructInit(&ADC_InitStructure);
|
||||
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
|
||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
|
||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
ADC_InitStructure.ADC_NbrOfConversion = configuredAdcChannels;
|
||||
ADC_InitStructure.ADC_ScanConvMode = configuredAdcChannels > 1 ? ENABLE : DISABLE; // 1=scan more that one channel in group
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
|
||||
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
|
||||
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
ADC_InitStructure.ADC_NbrOfConversion = configuredAdcChannels;
|
||||
ADC_InitStructure.ADC_ScanConvMode = configuredAdcChannels > 1 ? ENABLE : DISABLE; // 1=scan more that one channel in group
|
||||
|
||||
ADC_Init(adc.ADCx, &ADC_InitStructure);
|
||||
|
||||
|
|
|
@ -45,8 +45,8 @@ static bool isEOCConnected = true;
|
|||
// EXTI14 for BMP085 End of Conversion Interrupt
|
||||
void bmp085_extiHandler(extiCallbackRec_t* cb)
|
||||
{
|
||||
UNUSED(cb);
|
||||
isConversionComplete = true;
|
||||
UNUSED(cb);
|
||||
isConversionComplete = true;
|
||||
}
|
||||
|
||||
bool bmp085TestEOCConnected(const bmp085Config_t *config);
|
||||
|
@ -143,7 +143,7 @@ void bmp085InitXclrIO(const bmp085Config_t *config)
|
|||
{
|
||||
if (!xclrIO && config && config->xclrIO) {
|
||||
xclrIO = IOGetByTag(config->xclrIO);
|
||||
IOInit(xclrIO, OWNER_SYSTEM, RESOURCE_OUTPUT);
|
||||
IOInit(xclrIO, OWNER_BARO, RESOURCE_OUTPUT, 0);
|
||||
IOConfigGPIO(xclrIO, IOCFG_OUT_PP);
|
||||
}
|
||||
}
|
||||
|
@ -184,13 +184,13 @@ bool bmp085Detect(const bmp085Config_t *config, baro_t *baro)
|
|||
|
||||
delay(20); // datasheet says 10ms, we'll be careful and do 20.
|
||||
|
||||
ack = i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CHIP_ID__REG, 1, &data); /* read Chip Id */
|
||||
ack = i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CHIP_ID__REG, 1, &data); /* read Chip Id */
|
||||
if (ack) {
|
||||
bmp085.chip_id = BMP085_GET_BITSLICE(data, BMP085_CHIP_ID);
|
||||
bmp085.oversampling_setting = 3;
|
||||
|
||||
if (bmp085.chip_id == BMP085_CHIP_ID) { /* get bitslice */
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_VERSION_REG, 1, &data); /* read Version reg */
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_VERSION_REG, 1, &data); /* read Version reg */
|
||||
bmp085.ml_version = BMP085_GET_BITSLICE(data, BMP085_ML_VERSION); /* get ML Version */
|
||||
bmp085.al_version = BMP085_GET_BITSLICE(data, BMP085_AL_VERSION); /* get AL Version */
|
||||
bmp085_get_cal_param(); /* readout bmp085 calibparam structure */
|
||||
|
@ -277,7 +277,7 @@ static void bmp085_start_ut(void)
|
|||
#if defined(BARO_EOC_GPIO)
|
||||
isConversionComplete = false;
|
||||
#endif
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CTRL_MEAS_REG, BMP085_T_MEASURE);
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CTRL_MEAS_REG, BMP085_T_MEASURE);
|
||||
}
|
||||
|
||||
static void bmp085_get_ut(void)
|
||||
|
@ -291,7 +291,7 @@ static void bmp085_get_ut(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_ADC_OUT_MSB_REG, 2, data);
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_ADC_OUT_MSB_REG, 2, data);
|
||||
bmp085_ut = (data[0] << 8) | data[1];
|
||||
}
|
||||
|
||||
|
@ -305,7 +305,7 @@ static void bmp085_start_up(void)
|
|||
isConversionComplete = false;
|
||||
#endif
|
||||
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CTRL_MEAS_REG, ctrl_reg_data);
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_CTRL_MEAS_REG, ctrl_reg_data);
|
||||
}
|
||||
|
||||
/** read out up for pressure conversion
|
||||
|
@ -323,7 +323,7 @@ static void bmp085_get_up(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_ADC_OUT_MSB_REG, 3, data);
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_ADC_OUT_MSB_REG, 3, data);
|
||||
bmp085_up = (((uint32_t) data[0] << 16) | ((uint32_t) data[1] << 8) | (uint32_t) data[2])
|
||||
>> (8 - bmp085.oversampling_setting);
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ STATIC_UNIT_TESTED void bmp085_calculate(int32_t *pressure, int32_t *temperature
|
|||
static void bmp085_get_cal_param(void)
|
||||
{
|
||||
uint8_t data[22];
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_PROM_START__ADDR, BMP085_PROM_DATA__LEN, data);
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP085_I2C_ADDR, BMP085_PROM_START__ADDR, BMP085_PROM_DATA__LEN, data);
|
||||
|
||||
/*parameters AC1-AC6*/
|
||||
bmp085.cal_param.ac1 = (data[0] << 8) | data[1];
|
||||
|
@ -367,7 +367,7 @@ static void bmp085_get_cal_param(void)
|
|||
bool bmp085TestEOCConnected(const bmp085Config_t *config)
|
||||
{
|
||||
UNUSED(config);
|
||||
|
||||
|
||||
if (!bmp085InitDone && eocIO) {
|
||||
bmp085_start_ut();
|
||||
delayMicroseconds(UT_DELAY * 2); // wait twice as long as normal, just to be sure
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#pragma once
|
||||
|
||||
typedef struct bmp085Config_s {
|
||||
ioTag_t xclrIO;
|
||||
ioTag_t eocIO;
|
||||
ioTag_t xclrIO;
|
||||
ioTag_t eocIO;
|
||||
} bmp085Config_t;
|
||||
|
||||
bool bmp085Detect(const bmp085Config_t *config, baro_t *baro);
|
||||
|
|
|
@ -83,14 +83,14 @@ bool bmp280Detect(baro_t *baro)
|
|||
// set oversampling + power mode (forced), and start sampling
|
||||
bmp280WriteRegister(BMP280_CTRL_MEAS_REG, BMP280_MODE);
|
||||
#else
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CHIP_ID_REG, 1, &bmp280_chip_id); /* read Chip Id */
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CHIP_ID_REG, 1, &bmp280_chip_id); /* read Chip Id */
|
||||
if (bmp280_chip_id != BMP280_DEFAULT_CHIP_ID)
|
||||
return false;
|
||||
|
||||
// read calibration
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG, 24, (uint8_t *)&bmp280_cal);
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG, 24, (uint8_t *)&bmp280_cal);
|
||||
// set oversampling + power mode (forced), and start sampling
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, BMP280_MODE);
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, BMP280_MODE);
|
||||
#endif
|
||||
|
||||
bmp280InitDone = true;
|
||||
|
@ -129,7 +129,7 @@ static void bmp280_start_up(void)
|
|||
{
|
||||
// start measurement
|
||||
// set oversampling + power mode (forced), and start sampling
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, BMP280_MODE);
|
||||
i2cWrite(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, BMP280_MODE);
|
||||
}
|
||||
|
||||
static void bmp280_get_up(void)
|
||||
|
@ -137,7 +137,7 @@ static void bmp280_get_up(void)
|
|||
uint8_t data[BMP280_DATA_FRAME_SIZE];
|
||||
|
||||
// read data from sensor
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_PRESSURE_MSB_REG, BMP280_DATA_FRAME_SIZE, data);
|
||||
i2cRead(BARO_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_PRESSURE_MSB_REG, BMP280_DATA_FRAME_SIZE, data);
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ bool ms5611Detect(baro_t *baro)
|
|||
|
||||
delay(10); // No idea how long the chip takes to power-up, but let's make it 10ms
|
||||
|
||||
ack = i2cRead(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD, 1, &sig);
|
||||
ack = i2cRead(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD, 1, &sig);
|
||||
if (!ack)
|
||||
return false;
|
||||
|
||||
|
@ -93,14 +93,14 @@ bool ms5611Detect(baro_t *baro)
|
|||
|
||||
static void ms5611_reset(void)
|
||||
{
|
||||
i2cWrite(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_RESET, 1);
|
||||
i2cWrite(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_RESET, 1);
|
||||
delayMicroseconds(2800);
|
||||
}
|
||||
|
||||
static uint16_t ms5611_prom(int8_t coef_num)
|
||||
{
|
||||
uint8_t rxbuf[2] = { 0, 0 };
|
||||
i2cRead(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD + coef_num * 2, 2, rxbuf); // send PROM READ command
|
||||
i2cRead(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD + coef_num * 2, 2, rxbuf); // send PROM READ command
|
||||
return rxbuf[0] << 8 | rxbuf[1];
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,13 @@ STATIC_UNIT_TESTED int8_t ms5611_crc(uint16_t *prom)
|
|||
static uint32_t ms5611_read_adc(void)
|
||||
{
|
||||
uint8_t rxbuf[3];
|
||||
i2cRead(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_READ, 3, rxbuf); // read ADC
|
||||
i2cRead(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_READ, 3, rxbuf); // read ADC
|
||||
return (rxbuf[0] << 16) | (rxbuf[1] << 8) | rxbuf[2];
|
||||
}
|
||||
|
||||
static void ms5611_start_ut(void)
|
||||
{
|
||||
i2cWrite(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D2 + ms5611_osr, 1); // D2 (temperature) conversion start!
|
||||
i2cWrite(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D2 + ms5611_osr, 1); // D2 (temperature) conversion start!
|
||||
}
|
||||
|
||||
static void ms5611_get_ut(void)
|
||||
|
@ -153,7 +153,7 @@ static void ms5611_get_ut(void)
|
|||
|
||||
static void ms5611_start_up(void)
|
||||
{
|
||||
i2cWrite(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D1 + ms5611_osr, 1); // D1 (pressure) conversion start!
|
||||
i2cWrite(BARO_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D1 + ms5611_osr, 1); // D1 (pressure) conversion start!
|
||||
}
|
||||
|
||||
static void ms5611_get_up(void)
|
||||
|
|
|
@ -17,17 +17,15 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "bus_spi.h"
|
||||
|
||||
#include "barometer.h"
|
||||
#include "barometer_bmp280.h"
|
||||
|
||||
#ifdef USE_BARO_SPI_BMP280
|
||||
#define DISABLE_BMP280 IOHi(bmp280CsPin)
|
||||
#define ENABLE_BMP280 IOLo(bmp280CsPin)
|
||||
|
||||
|
@ -65,7 +63,7 @@ void bmp280SpiInit(void)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
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_ut = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -48,218 +48,218 @@ static volatile uint16_t i2cErrorCount = 0;
|
|||
|
||||
static void I2C_delay(void)
|
||||
{
|
||||
volatile int i = 7;
|
||||
while (i) {
|
||||
i--;
|
||||
}
|
||||
volatile int i = 7;
|
||||
while (i) {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
static bool I2C_Start(void)
|
||||
{
|
||||
SDA_H;
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
if (!SDA_read) {
|
||||
return false;
|
||||
}
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
if (SDA_read) {
|
||||
return false;
|
||||
}
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
return true;
|
||||
SDA_H;
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
if (!SDA_read) {
|
||||
return false;
|
||||
}
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
if (SDA_read) {
|
||||
return false;
|
||||
}
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void I2C_Stop(void)
|
||||
{
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
SDA_H;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
SDA_H;
|
||||
I2C_delay();
|
||||
}
|
||||
|
||||
static void I2C_Ack(void)
|
||||
{
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_L;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
}
|
||||
|
||||
static void I2C_NoAck(void)
|
||||
{
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_H;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_H;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
}
|
||||
|
||||
static bool I2C_WaitAck(void)
|
||||
{
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_H;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
if (SDA_read) {
|
||||
SCL_L;
|
||||
return false;
|
||||
}
|
||||
SCL_L;
|
||||
return true;
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SDA_H;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
if (SDA_read) {
|
||||
SCL_L;
|
||||
return false;
|
||||
}
|
||||
SCL_L;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void I2C_SendByte(uint8_t byte)
|
||||
{
|
||||
uint8_t i = 8;
|
||||
while (i--) {
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
if (byte & 0x80) {
|
||||
SDA_H;
|
||||
}
|
||||
else {
|
||||
SDA_L;
|
||||
}
|
||||
byte <<= 1;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
}
|
||||
SCL_L;
|
||||
uint8_t i = 8;
|
||||
while (i--) {
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
if (byte & 0x80) {
|
||||
SDA_H;
|
||||
}
|
||||
else {
|
||||
SDA_L;
|
||||
}
|
||||
byte <<= 1;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
}
|
||||
SCL_L;
|
||||
}
|
||||
|
||||
static uint8_t I2C_ReceiveByte(void)
|
||||
{
|
||||
uint8_t i = 8;
|
||||
uint8_t byte = 0;
|
||||
uint8_t i = 8;
|
||||
uint8_t byte = 0;
|
||||
|
||||
SDA_H;
|
||||
while (i--) {
|
||||
byte <<= 1;
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
if (SDA_read) {
|
||||
byte |= 0x01;
|
||||
}
|
||||
}
|
||||
SCL_L;
|
||||
return byte;
|
||||
SDA_H;
|
||||
while (i--) {
|
||||
byte <<= 1;
|
||||
SCL_L;
|
||||
I2C_delay();
|
||||
SCL_H;
|
||||
I2C_delay();
|
||||
if (SDA_read) {
|
||||
byte |= 0x01;
|
||||
}
|
||||
}
|
||||
SCL_L;
|
||||
return byte;
|
||||
}
|
||||
|
||||
void i2cInit(I2CDevice device)
|
||||
{
|
||||
UNUSED(device);
|
||||
UNUSED(device);
|
||||
|
||||
scl = IOGetByTag(IO_TAG(SOFT_I2C_SCL));
|
||||
sda = IOGetByTag(IO_TAG(SOFT_I2C_SDA));
|
||||
scl = IOGetByTag(IO_TAG(SOFT_I2C_SCL));
|
||||
sda = IOGetByTag(IO_TAG(SOFT_I2C_SDA));
|
||||
|
||||
IOConfigGPIO(scl, IOCFG_OUT_OD);
|
||||
IOConfigGPIO(sda, IOCFG_OUT_OD);
|
||||
IOConfigGPIO(scl, IOCFG_OUT_OD);
|
||||
IOConfigGPIO(sda, IOCFG_OUT_OD);
|
||||
}
|
||||
|
||||
bool i2cWriteBuffer(I2CDevice device, uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
int i;
|
||||
if (!I2C_Start()) {
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(reg);
|
||||
I2C_WaitAck();
|
||||
for (i = 0; i < len; i++) {
|
||||
I2C_SendByte(data[i]);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
I2C_Stop();
|
||||
return true;
|
||||
|
||||
int i;
|
||||
if (!I2C_Start()) {
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(reg);
|
||||
I2C_WaitAck();
|
||||
for (i = 0; i < len; i++) {
|
||||
I2C_SendByte(data[i]);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
I2C_Stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool i2cWrite(I2CDevice device, uint8_t addr, uint8_t reg, uint8_t data)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
if (!I2C_Start()) {
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(reg);
|
||||
I2C_WaitAck();
|
||||
I2C_SendByte(data);
|
||||
I2C_WaitAck();
|
||||
I2C_Stop();
|
||||
return true;
|
||||
|
||||
if (!I2C_Start()) {
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(reg);
|
||||
I2C_WaitAck();
|
||||
I2C_SendByte(data);
|
||||
I2C_WaitAck();
|
||||
I2C_Stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool i2cRead(I2CDevice device, uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
if (!I2C_Start()) {
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(reg);
|
||||
I2C_WaitAck();
|
||||
I2C_Start();
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
|
||||
I2C_WaitAck();
|
||||
while (len) {
|
||||
*buf = I2C_ReceiveByte();
|
||||
if (len == 1) {
|
||||
I2C_NoAck();
|
||||
}
|
||||
else {
|
||||
I2C_Ack();
|
||||
}
|
||||
buf++;
|
||||
len--;
|
||||
}
|
||||
I2C_Stop();
|
||||
return true;
|
||||
|
||||
if (!I2C_Start()) {
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Transmitter);
|
||||
if (!I2C_WaitAck()) {
|
||||
I2C_Stop();
|
||||
i2cErrorCount++;
|
||||
return false;
|
||||
}
|
||||
I2C_SendByte(reg);
|
||||
I2C_WaitAck();
|
||||
I2C_Start();
|
||||
I2C_SendByte(addr << 1 | I2C_Direction_Receiver);
|
||||
I2C_WaitAck();
|
||||
while (len) {
|
||||
*buf = I2C_ReceiveByte();
|
||||
if (len == 1) {
|
||||
I2C_NoAck();
|
||||
}
|
||||
else {
|
||||
I2C_Ack();
|
||||
}
|
||||
buf++;
|
||||
len--;
|
||||
}
|
||||
I2C_Stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t i2cGetErrorCounter(void)
|
||||
{
|
||||
return i2cErrorCount;
|
||||
return i2cErrorCount;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "system.h"
|
||||
|
||||
|
@ -133,7 +131,7 @@ static bool i2cHandleHardwareFailure(I2CDevice device)
|
|||
|
||||
bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_, uint8_t *data)
|
||||
{
|
||||
|
||||
|
||||
if (device == I2CINVALID)
|
||||
return false;
|
||||
|
||||
|
@ -141,10 +139,10 @@ bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_,
|
|||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
|
||||
i2cState_t *state;
|
||||
state = &(i2cState[device]);
|
||||
|
||||
|
||||
state->addr = addr_ << 1;
|
||||
state->reg = reg_;
|
||||
state->writing = 1;
|
||||
|
@ -182,12 +180,12 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t
|
|||
{
|
||||
if (device == I2CINVALID)
|
||||
return false;
|
||||
|
||||
|
||||
uint32_t timeout = I2C_DEFAULT_TIMEOUT;
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
|
||||
i2cState_t *state;
|
||||
state = &(i2cState[device]);
|
||||
|
||||
|
@ -220,13 +218,13 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t
|
|||
}
|
||||
|
||||
static void i2c_er_handler(I2CDevice device) {
|
||||
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
|
||||
i2cState_t *state;
|
||||
state = &(i2cState[device]);
|
||||
|
||||
|
||||
// Read the I2C1 status register
|
||||
volatile uint32_t SR1Register = I2Cx->SR1;
|
||||
|
||||
|
@ -255,13 +253,13 @@ static void i2c_er_handler(I2CDevice device) {
|
|||
}
|
||||
|
||||
void i2c_ev_handler(I2CDevice device) {
|
||||
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
|
||||
i2cState_t *state;
|
||||
state = &(i2cState[device]);
|
||||
|
||||
|
||||
static uint8_t subaddress_sent, final_stop; // flag to indicate if subaddess sent, flag to indicate final bus condition
|
||||
static int8_t index; // index is signed -1 == send the subaddress
|
||||
uint8_t SReg_1 = I2Cx->SR1; // read the status register here
|
||||
|
@ -384,17 +382,17 @@ void i2cInit(I2CDevice device)
|
|||
|
||||
IO_t scl = IOGetByTag(i2c->scl);
|
||||
IO_t sda = IOGetByTag(i2c->sda);
|
||||
|
||||
IOInit(scl, OWNER_SYSTEM, RESOURCE_I2C);
|
||||
IOInit(sda, OWNER_SYSTEM, RESOURCE_I2C);
|
||||
|
||||
IOInit(scl, OWNER_I2C, RESOURCE_I2C_SCL, RESOURCE_INDEX(device));
|
||||
IOInit(sda, OWNER_I2C, RESOURCE_I2C_SDA, RESOURCE_INDEX(device));
|
||||
|
||||
// Enable RCC
|
||||
RCC_ClockCmd(i2c->rcc, ENABLE);
|
||||
|
||||
|
||||
I2C_ITConfig(i2c->dev, I2C_IT_EVT | I2C_IT_ERR, DISABLE);
|
||||
|
||||
|
||||
i2cUnstick(scl, sda);
|
||||
|
||||
|
||||
// Init pins
|
||||
#ifdef STM32F4
|
||||
IOConfigGPIOAF(scl, IOCFG_I2C, GPIO_AF_I2C);
|
||||
|
@ -403,10 +401,10 @@ void i2cInit(I2CDevice device)
|
|||
IOConfigGPIO(scl, IOCFG_AF_OD);
|
||||
IOConfigGPIO(sda, IOCFG_AF_OD);
|
||||
#endif
|
||||
|
||||
|
||||
I2C_DeInit(i2c->dev);
|
||||
I2C_StructInit(&i2cInit);
|
||||
|
||||
|
||||
I2C_ITConfig(i2c->dev, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts - they are enabled by the first request
|
||||
i2cInit.I2C_Mode = I2C_Mode_I2C;
|
||||
i2cInit.I2C_DutyCycle = I2C_DutyCycle_2;
|
||||
|
@ -422,7 +420,10 @@ void i2cInit(I2CDevice device)
|
|||
|
||||
I2C_Cmd(i2c->dev, ENABLE);
|
||||
I2C_Init(i2c->dev, &i2cInit);
|
||||
|
||||
|
||||
I2C_StretchClockCmd(i2c->dev, ENABLE);
|
||||
|
||||
|
||||
// I2C ER Interrupt
|
||||
nvic.NVIC_IRQChannel = i2c->er_irq;
|
||||
nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER);
|
||||
|
|
|
@ -17,12 +17,9 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "gpio.h"
|
||||
#include "system.h"
|
||||
#include "drivers/io_impl.h"
|
||||
|
@ -31,6 +28,15 @@
|
|||
|
||||
#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_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT))
|
||||
#define I2C_GPIO_AF GPIO_AF_4
|
||||
|
@ -70,21 +76,24 @@ uint32_t i2cTimeoutUserCallback(void)
|
|||
|
||||
void i2cInit(I2CDevice device)
|
||||
{
|
||||
|
||||
|
||||
i2cDevice_t *i2c;
|
||||
i2c = &(i2cHardwareMap[device]);
|
||||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2c->dev;
|
||||
|
||||
|
||||
IO_t scl = IOGetByTag(i2c->scl);
|
||||
IO_t sda = IOGetByTag(i2c->sda);
|
||||
|
||||
|
||||
RCC_ClockCmd(i2c->rcc, ENABLE);
|
||||
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);
|
||||
IOConfigGPIOAF(sda, 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(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_Mode = I2C_Mode_I2C,
|
||||
|
@ -93,14 +102,13 @@ void i2cInit(I2CDevice device)
|
|||
.I2C_OwnAddress1 = 0x00,
|
||||
.I2C_Ack = I2C_Ack_Enable,
|
||||
.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
|
||||
.I2C_Timing = i2c->overClock ?
|
||||
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_Timing = (i2c->overClock ? I2C_HIGHSPEED_TIMING : I2C_STANDARD_TIMING)
|
||||
};
|
||||
|
||||
|
||||
I2C_Init(I2Cx, &i2cInit);
|
||||
|
||||
I2C_StretchClockCmd(I2Cx, ENABLE);
|
||||
|
||||
I2C_Cmd(I2Cx, ENABLE);
|
||||
}
|
||||
|
||||
|
@ -115,7 +123,7 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
|
||||
/* Test on BUSY Flag */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
||||
|
@ -181,7 +189,7 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
|
||||
I2C_TypeDef *I2Cx;
|
||||
I2Cx = i2cHardwareMap[device].dev;
|
||||
|
||||
|
||||
/* Test on BUSY Flag */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "bus_spi.h"
|
||||
#include "io.h"
|
||||
#include "io_impl.h"
|
||||
|
@ -113,33 +111,27 @@ void spiInitDevice(SPIDevice device)
|
|||
RCC_ClockCmd(spi->rcc, ENABLE);
|
||||
RCC_ResetCmd(spi->rcc, ENABLE);
|
||||
|
||||
IOInit(IOGetByTag(spi->sck), OWNER_SYSTEM, RESOURCE_SPI);
|
||||
IOInit(IOGetByTag(spi->miso), OWNER_SYSTEM, RESOURCE_SPI);
|
||||
IOInit(IOGetByTag(spi->mosi), OWNER_SYSTEM, RESOURCE_SPI);
|
||||
|
||||
#if defined(STM32F303xC) || 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->miso), SPI_IO_AF_CFG, spi->af);
|
||||
}
|
||||
IOInit(IOGetByTag(spi->sck), OWNER_SPI, RESOURCE_SPI_SCK, device + 1);
|
||||
IOInit(IOGetByTag(spi->miso), OWNER_SPI, RESOURCE_SPI_MISO, device + 1);
|
||||
IOInit(IOGetByTag(spi->mosi), OWNER_SPI, RESOURCE_SPI_MOSI, device + 1);
|
||||
|
||||
#if defined(STM32F3) || defined(STM32F4)
|
||||
IOConfigGPIOAF(IOGetByTag(spi->sck), 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);
|
||||
|
||||
if (spi->nss)
|
||||
IOConfigGPIOAF(IOGetByTag(spi->nss), SPI_IO_CS_CFG, spi->af);
|
||||
#endif
|
||||
#if defined(STM32F10X)
|
||||
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_CFG);
|
||||
|
||||
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_CFG);
|
||||
|
||||
if (spi->nss)
|
||||
IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);
|
||||
#endif
|
||||
|
||||
|
||||
// Init SPI hardware
|
||||
SPI_I2S_DeInit(spi->dev);
|
||||
|
||||
|
@ -355,4 +347,4 @@ void spiResetErrorCounter(SPI_TypeDef *instance)
|
|||
SPIDevice device = spiDeviceByInstance(instance);
|
||||
if (device != SPIINVALID)
|
||||
spiHardwareMap[device].errorCount = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_CS_CFG IO_CONFIG(GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL)
|
||||
#elif defined(STM32F1)
|
||||
#define SPI_IO_AF_CFG IO_CONFIG(GPIO_Mode_AF_OD, GPIO_Speed_50MHz)
|
||||
#define SPI_IO_CS_CFG IO_CONFIG(GPIO_Mode_Out_OD, GPIO_Speed_50MHz)
|
||||
#define SPI_IO_AF_SCK_CFG IO_CONFIG(GPIO_Mode_AF_PP, 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
|
||||
#error "Unknown processor"
|
||||
#endif
|
||||
|
@ -52,23 +54,23 @@ typedef enum {
|
|||
} SPIClockDivider_e;
|
||||
|
||||
typedef enum SPIDevice {
|
||||
SPIINVALID = -1,
|
||||
SPIDEV_1 = 0,
|
||||
SPIDEV_2,
|
||||
SPIDEV_3,
|
||||
SPIDEV_MAX = SPIDEV_3,
|
||||
SPIINVALID = -1,
|
||||
SPIDEV_1 = 0,
|
||||
SPIDEV_2,
|
||||
SPIDEV_3,
|
||||
SPIDEV_MAX = SPIDEV_3,
|
||||
} SPIDevice;
|
||||
|
||||
typedef struct SPIDevice_s {
|
||||
SPI_TypeDef *dev;
|
||||
ioTag_t nss;
|
||||
ioTag_t sck;
|
||||
ioTag_t mosi;
|
||||
ioTag_t miso;
|
||||
rccPeriphTag_t rcc;
|
||||
uint8_t af;
|
||||
volatile uint16_t errorCount;
|
||||
bool sdcard;
|
||||
SPI_TypeDef *dev;
|
||||
ioTag_t nss;
|
||||
ioTag_t sck;
|
||||
ioTag_t mosi;
|
||||
ioTag_t miso;
|
||||
rccPeriphTag_t rcc;
|
||||
uint8_t af;
|
||||
volatile uint16_t errorCount;
|
||||
bool sdcard;
|
||||
} spiDevice_t;
|
||||
|
||||
bool spiInit(SPIDevice device);
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "common/maths.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "gpio.h"
|
||||
#include "exti.h"
|
||||
#include "bus_i2c.h"
|
||||
#include "bus_spi.h"
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ bool ak8975detect(mag_t *mag)
|
|||
bool ack = false;
|
||||
uint8_t sig = 0;
|
||||
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_WHO_AM_I, 1, &sig);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_WHO_AM_I, 1, &sig);
|
||||
if (!ack || sig != 'H') // 0x48 / 01001000 / 'H'
|
||||
return false;
|
||||
|
||||
|
@ -86,24 +86,24 @@ void ak8975Init()
|
|||
|
||||
UNUSED(ack);
|
||||
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x00); // power down before entering fuse mode
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x00); // power down before entering fuse mode
|
||||
delay(20);
|
||||
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x0F); // Enter Fuse ROM access mode
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x0F); // Enter Fuse ROM access mode
|
||||
delay(10);
|
||||
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975A_ASAX, 3, &buffer[0]); // Read the x-, y-, and z-axis calibration values
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975A_ASAX, 3, &buffer[0]); // Read the x-, y-, and z-axis calibration values
|
||||
delay(10);
|
||||
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x00); // power down after reading.
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x00); // power down after reading.
|
||||
delay(10);
|
||||
|
||||
// Clear status registers
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS1, 1, &status);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS2, 1, &status);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS1, 1, &status);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS2, 1, &status);
|
||||
|
||||
// Trigger first measurement
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x01);
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x01);
|
||||
}
|
||||
|
||||
#define BIT_STATUS1_REG_DATA_READY (1 << 0)
|
||||
|
@ -118,13 +118,13 @@ bool ak8975Read(int16_t *magData)
|
|||
uint8_t status;
|
||||
uint8_t buf[6];
|
||||
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS1, 1, &status);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS1, 1, &status);
|
||||
if (!ack || (status & BIT_STATUS1_REG_DATA_READY) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 1 // USE_I2C_SINGLE_BYTE_READS
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_HXL, 6, buf); // read from AK8975_MAG_REG_HXL to AK8975_MAG_REG_HZH
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_HXL, 6, buf); // read from AK8975_MAG_REG_HXL to AK8975_MAG_REG_HZH
|
||||
#else
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
ack = i2cRead(AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_HXL + i, 1, &buf[i]); // read from AK8975_MAG_REG_HXL to AK8975_MAG_REG_HZH
|
||||
|
@ -134,7 +134,7 @@ bool ak8975Read(int16_t *magData)
|
|||
}
|
||||
#endif
|
||||
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS2, 1, &status);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_STATUS2, 1, &status);
|
||||
if (!ack) {
|
||||
return false;
|
||||
}
|
||||
|
@ -152,6 +152,6 @@ bool ak8975Read(int16_t *magData)
|
|||
magData[Z] = -(int16_t)(buf[5] << 8 | buf[4]) * 4;
|
||||
|
||||
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x01); // start reading again
|
||||
ack = i2cWrite(MAG_I2C_INSTANCE, AK8975_MAG_I2C_ADDRESS, AK8975_MAG_REG_CNTL, 0x01); // start reading again
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -29,7 +28,8 @@
|
|||
|
||||
#include "system.h"
|
||||
#include "nvic.h"
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "exti.h"
|
||||
#include "bus_i2c.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;
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
EXTI_ClearITPendingBit(hmc5883Config->exti_line);
|
||||
|
||||
UNUSED(cb);
|
||||
#ifdef DEBUG_MAG_DATA_READY_INTERRUPT
|
||||
// Measure the delta between calls to the interrupt handler
|
||||
// currently should be around 65/66 milli seconds / 15hz output rate
|
||||
|
@ -143,57 +143,26 @@ void MAG_DATA_READY_EXTI_Handler(void)
|
|||
lastCalledAt = now;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void hmc5883lConfigureDataReadyInterruptHandling(void)
|
||||
{
|
||||
#ifdef USE_MAG_DATA_READY_SIGNAL
|
||||
|
||||
if (!(hmc5883Config->exti_port_source && hmc5883Config->exti_pin_source)) {
|
||||
if (!(hmc5883Config->intTag)) {
|
||||
return;
|
||||
}
|
||||
#ifdef STM32F10X
|
||||
// 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
|
||||
|
||||
intIO = IOGetByTag(hmc5883Config->intTag);
|
||||
#ifdef ENSURE_MAG_DATA_READY_IS_HIGH
|
||||
uint8_t status = GPIO_ReadInputDataBit(hmc5883Config->gpioPort, hmc5883Config->gpioPin);
|
||||
uint8_t status = IORead(intIO);
|
||||
if (!status) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
registerExtiCallbackHandler(hmc5883Config->exti_irqn, MAG_DATA_READY_EXTI_Handler);
|
||||
|
||||
EXTI_ClearITPendingBit(hmc5883Config->exti_line);
|
||||
|
||||
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);
|
||||
EXTIHandlerInit(&hmc5883_extiCallbackRec, hmc5883_extiHandler);
|
||||
EXTIConfig(intIO, &hmc5883_extiCallbackRec, NVIC_PRIO_MAG_INT_EXTI, EXTI_Trigger_Rising);
|
||||
EXTIEnable(intIO, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -204,7 +173,7 @@ bool hmc5883lDetect(mag_t* mag, const hmc5883Config_t *hmc5883ConfigToUse)
|
|||
|
||||
hmc5883Config = hmc5883ConfigToUse;
|
||||
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, MAG_ADDRESS, 0x0A, 1, &sig);
|
||||
ack = i2cRead(MAG_I2C_INSTANCE, MAG_ADDRESS, 0x0A, 1, &sig);
|
||||
if (!ack || sig != 'H')
|
||||
return false;
|
||||
|
||||
|
@ -221,35 +190,16 @@ void hmc5883lInit(void)
|
|||
int32_t xyz_total[3] = { 0, 0, 0 }; // 32 bit totals so they won't overflow.
|
||||
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);
|
||||
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.
|
||||
// The new gain setting is effective from the second measurement and on.
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFB, 0x60); // Set the Gain to 2.5Ga (7:5->011)
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFB, 0x60); // Set the Gain to 2.5Ga (7:5->011)
|
||||
delay(100);
|
||||
hmc5883lRead(magADC);
|
||||
|
||||
for (i = 0; i < 10; i++) { // Collect 10 samples
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 1);
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 1);
|
||||
delay(50);
|
||||
hmc5883lRead(magADC); // Get the raw values in case the scales have already been changed.
|
||||
|
||||
|
@ -267,9 +217,9 @@ void hmc5883lInit(void)
|
|||
}
|
||||
|
||||
// Apply the negative bias. (Same gain)
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x010 + HMC_NEG_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to negative bias.
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x010 + HMC_NEG_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to negative bias.
|
||||
for (i = 0; i < 10; i++) {
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 1);
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 1);
|
||||
delay(50);
|
||||
hmc5883lRead(magADC); // Get the raw values in case the scales have already been changed.
|
||||
|
||||
|
@ -291,9 +241,9 @@ void hmc5883lInit(void)
|
|||
magGain[Z] = fabsf(660.0f * HMC58X3_Z_SELF_TEST_GAUSS * 2.0f * 10.0f / xyz_total[Z]);
|
||||
|
||||
// leave test mode
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x70); // Configuration Register A -- 0 11 100 00 num samples: 8 ; output rate: 15Hz ; normal measurement mode
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFB, 0x20); // Configuration Register B -- 001 00000 configuration gain 1.3Ga
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 0x00); // Mode register -- 000000 00 continuous Conversion Mode
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x70); // Configuration Register A -- 0 11 100 00 num samples: 8 ; output rate: 15Hz ; normal measurement mode
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFB, 0x20); // Configuration Register B -- 001 00000 configuration gain 1.3Ga
|
||||
i2cWrite(MAG_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 0x00); // Mode register -- 000000 00 continuous Conversion Mode
|
||||
delay(100);
|
||||
|
||||
if (!bret) { // Something went wrong so get a best guess
|
||||
|
@ -309,7 +259,7 @@ bool hmc5883lRead(int16_t *magData)
|
|||
{
|
||||
uint8_t buf[6];
|
||||
|
||||
bool ack = i2cRead(MAG_I2C_INSTANCE, MAG_ADDRESS, MAG_DATA_REGISTER, 6, buf);
|
||||
bool ack = i2cRead(MAG_I2C_INSTANCE, MAG_ADDRESS, MAG_DATA_REGISTER, 6, buf);
|
||||
if (!ack) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,20 +17,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
typedef struct hmc5883Config_s {
|
||||
#ifdef STM32F303
|
||||
uint32_t gpioAHBPeripherals;
|
||||
#endif
|
||||
#ifdef STM32F10X
|
||||
uint32_t gpioAPB2Peripherals;
|
||||
#endif
|
||||
uint16_t gpioPin;
|
||||
GPIO_TypeDef *gpioPort;
|
||||
#include "io.h"
|
||||
|
||||
uint8_t exti_port_source;
|
||||
uint32_t exti_line;
|
||||
uint8_t exti_pin_source;
|
||||
IRQn_Type exti_irqn;
|
||||
typedef struct hmc5883Config_s {
|
||||
ioTag_t intTag;
|
||||
} hmc5883Config_t;
|
||||
|
||||
bool hmc5883lDetect(mag_t* mag, const hmc5883Config_t *hmc5883ConfigToUse);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
|
|
@ -21,63 +21,66 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "drivers/nvic.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)
|
||||
{
|
||||
UNUSED(channel);
|
||||
}
|
||||
/*
|
||||
* DMA IRQ Handlers
|
||||
*/
|
||||
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)
|
||||
{
|
||||
dmaHandlers.dma1Channel2IRQHandler(DMA1_Channel2);
|
||||
}
|
||||
#if defined(STM32F3) || defined(STM32F10X_CL)
|
||||
DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER)
|
||||
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)
|
||||
{
|
||||
memset(&dmaHandlers, 0, sizeof(dmaHandlers));
|
||||
dmaHandlers.dma1Channel2IRQHandler = dmaNoOpHandler;
|
||||
dmaHandlers.dma1Channel3IRQHandler = dmaNoOpHandler;
|
||||
dmaHandlers.dma1Channel6IRQHandler = dmaNoOpHandler;
|
||||
dmaHandlers.dma1Channel7IRQHandler = dmaNoOpHandler;
|
||||
// TODO: Do we need this?
|
||||
}
|
||||
|
||||
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback)
|
||||
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
|
||||
{
|
||||
switch (identifier) {
|
||||
case DMA1_CH2_HANDLER:
|
||||
dmaHandlers.dma1Channel2IRQHandler = callback;
|
||||
break;
|
||||
case DMA1_CH3_HANDLER:
|
||||
dmaHandlers.dma1Channel3IRQHandler = callback;
|
||||
break;
|
||||
case DMA1_CH6_HANDLER:
|
||||
dmaHandlers.dma1Channel6IRQHandler = callback;
|
||||
break;
|
||||
case DMA1_CH7_HANDLER:
|
||||
dmaHandlers.dma1Channel7IRQHandler = callback;
|
||||
break;
|
||||
}
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
|
||||
dmaDescriptors[identifier].irqHandlerCallback = callback;
|
||||
dmaDescriptors[identifier].userParam = userParam;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,37 +15,97 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
struct dmaChannelDescriptor_s;
|
||||
typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor);
|
||||
|
||||
#ifdef STM32F4
|
||||
typedef void(*dmaCallbackHandlerFuncPtr)(DMA_Stream_TypeDef *stream);
|
||||
|
||||
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,
|
||||
DMA2_ST1_HANDLER,
|
||||
DMA2_ST2_HANDLER,
|
||||
DMA2_ST3_HANDLER,
|
||||
DMA2_ST4_HANDLER,
|
||||
DMA2_ST5_HANDLER,
|
||||
DMA2_ST6_HANDLER,
|
||||
DMA2_ST7_HANDLER,
|
||||
} dmaHandlerIdentifier_e;
|
||||
|
||||
typedef struct dmaHandlers_s {
|
||||
dmaCallbackHandlerFuncPtr dma1Stream2IRQHandler;
|
||||
dmaCallbackHandlerFuncPtr dma1Stream7IRQHandler;
|
||||
} dmaHandlers_t;
|
||||
typedef struct dmaChannelDescriptor_s {
|
||||
DMA_TypeDef* dma;
|
||||
DMA_Stream_TypeDef* stream;
|
||||
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
|
||||
|
||||
typedef void (*dmaCallbackHandlerFuncPtr)(DMA_Channel_TypeDef *channel);
|
||||
|
||||
typedef enum {
|
||||
DMA1_CH2_HANDLER = 0,
|
||||
DMA1_CH1_HANDLER = 0,
|
||||
DMA1_CH2_HANDLER,
|
||||
DMA1_CH3_HANDLER,
|
||||
DMA1_CH4_HANDLER,
|
||||
DMA1_CH5_HANDLER,
|
||||
DMA1_CH6_HANDLER,
|
||||
DMA1_CH7_HANDLER,
|
||||
DMA2_CH1_HANDLER,
|
||||
DMA2_CH2_HANDLER,
|
||||
DMA2_CH3_HANDLER,
|
||||
DMA2_CH4_HANDLER,
|
||||
DMA2_CH5_HANDLER,
|
||||
} dmaHandlerIdentifier_e;
|
||||
|
||||
typedef struct dmaHandlers_s {
|
||||
dmaCallbackHandlerFuncPtr dma1Channel2IRQHandler;
|
||||
dmaCallbackHandlerFuncPtr dma1Channel3IRQHandler;
|
||||
dmaCallbackHandlerFuncPtr dma1Channel6IRQHandler;
|
||||
dmaCallbackHandlerFuncPtr dma1Channel7IRQHandler;
|
||||
} dmaHandlers_t;
|
||||
typedef struct dmaChannelDescriptor_s {
|
||||
DMA_TypeDef* dma;
|
||||
DMA_Channel_TypeDef* channel;
|
||||
dmaCallbackHandlerFuncPtr irqHandlerCallback;
|
||||
uint8_t flagsShift;
|
||||
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
|
||||
|
||||
void dmaInit(void);
|
||||
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback);
|
||||
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam);
|
||||
|
||||
|
|
|
@ -16,50 +16,72 @@
|
|||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "drivers/nvic.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)
|
||||
{
|
||||
UNUSED(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),
|
||||
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)
|
||||
{
|
||||
memset(&dmaHandlers, 0, sizeof(dmaHandlers));
|
||||
dmaHandlers.dma1Stream2IRQHandler = dmaNoOpHandler;
|
||||
dmaHandlers.dma1Stream7IRQHandler = dmaNoOpHandler;
|
||||
// TODO: Do we need this?
|
||||
}
|
||||
|
||||
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback)
|
||||
void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
|
||||
{
|
||||
switch (identifier) {
|
||||
case DMA1_ST2_HANDLER:
|
||||
dmaHandlers.dma1Stream2IRQHandler = callback;
|
||||
break;
|
||||
case DMA1_ST7_HANDLER:
|
||||
dmaHandlers.dma1Stream7IRQHandler = callback;
|
||||
break;
|
||||
}
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
|
||||
dmaDescriptors[identifier].irqHandlerCallback = callback;
|
||||
dmaDescriptors[identifier].userParam = userParam;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -199,13 +198,13 @@ static bool m25p16_readIdentification()
|
|||
*/
|
||||
bool m25p16_init()
|
||||
{
|
||||
|
||||
#ifdef M25P16_CS_PIN
|
||||
|
||||
#ifdef M25P16_CS_PIN
|
||||
m25p16CsPin = IOGetByTag(IO_TAG(M25P16_CS_PIN));
|
||||
#endif
|
||||
IOInit(m25p16CsPin, OWNER_FLASH, RESOURCE_SPI);
|
||||
IOInit(m25p16CsPin, OWNER_FLASH, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(m25p16CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
|
||||
DISABLE_M25P16;
|
||||
|
||||
#ifndef M25P16_SPI_SHARED
|
||||
|
|
|
@ -102,8 +102,8 @@ typedef struct
|
|||
|
||||
#ifndef UNIT_TEST
|
||||
#ifdef STM32F4
|
||||
static inline void digitalHi(GPIO_TypeDef *p, uint16_t i) { p->BSRRL = i; }
|
||||
static inline void digitalLo(GPIO_TypeDef *p, uint16_t i) { p->BSRRH = i; }
|
||||
static inline void digitalHi(GPIO_TypeDef *p, uint16_t i) { p->BSRRL = i; }
|
||||
static inline void digitalLo(GPIO_TypeDef *p, uint16_t i) { p->BSRRH = i; }
|
||||
#else
|
||||
static inline void digitalHi(GPIO_TypeDef *p, uint16_t i) { p->BSRR = i; }
|
||||
static inline void digitalLo(GPIO_TypeDef *p, uint16_t i) { p->BRR = i; }
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
#define MODE_OFFSET 0
|
||||
|
|
|
@ -4,48 +4,39 @@
|
|||
* Created on: 3 aug. 2015
|
||||
* Author: borisb
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "build_config.h"
|
||||
|
||||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/accgyro.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;
|
||||
|
||||
bool getMpuDataStatus(gyro_t *gyro)
|
||||
bool gyroSyncCheckUpdate(const gyro_t *gyro)
|
||||
{
|
||||
bool mpuDataStatus;
|
||||
if (!gyro->intStatus)
|
||||
return false;
|
||||
gyro->intStatus(&mpuDataStatus);
|
||||
return mpuDataStatus;
|
||||
return false;
|
||||
return gyro->intStatus();
|
||||
}
|
||||
|
||||
bool gyroSyncCheckUpdate(void) {
|
||||
return getMpuDataStatus(&gyro);
|
||||
}
|
||||
#define GYRO_LPF_256HZ 0
|
||||
#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;
|
||||
|
||||
if (!lpf || lpf == 7) {
|
||||
if (lpf == GYRO_LPF_256HZ || lpf == GYRO_LPF_NONE) {
|
||||
gyroSamplePeriod = 125;
|
||||
} else {
|
||||
gyroSamplePeriod = 1000;
|
||||
|
@ -54,9 +45,11 @@ void gyroUpdateSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator) {
|
|||
|
||||
// calculate gyro divider and targetLooptime (expected cycleTime)
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* Author: borisb
|
||||
*/
|
||||
|
||||
extern uint32_t targetLooptime;
|
||||
|
||||
bool gyroSyncCheckUpdate(void);
|
||||
struct gyro_s;
|
||||
bool gyroSyncCheckUpdate(const struct gyro_s *gyro);
|
||||
uint8_t gyroMPU6xxxGetDividerDrops(void);
|
||||
void gyroUpdateSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator);
|
||||
uint32_t gyroSetSampleRate(uint8_t lpf, uint8_t gyroSyncDenominator);
|
||||
|
|
|
@ -31,15 +31,15 @@ static const IO_t pin = DEFIO_IO(INVERTER);
|
|||
|
||||
void initInverter(void)
|
||||
{
|
||||
IOInit(pin, OWNER_SYSTEM, RESOURCE_OUTPUT);
|
||||
IOConfigGPIO(pin, IOCFG_OUT_PP);
|
||||
|
||||
IOInit(pin, OWNER_INVERTER, RESOURCE_OUTPUT, 0);
|
||||
IOConfigGPIO(pin, IOCFG_OUT_PP);
|
||||
|
||||
inverterSet(false);
|
||||
}
|
||||
|
||||
void inverterSet(bool on)
|
||||
{
|
||||
IOWrite(pin, on);
|
||||
IOWrite(pin, on);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,19 @@ const struct ioPortDef_s ioPortDefs[] = {
|
|||
};
|
||||
# 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)
|
||||
{
|
||||
return io;
|
||||
|
@ -190,12 +203,12 @@ void IOToggle(IO_t io)
|
|||
}
|
||||
|
||||
// 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);
|
||||
if (owner != OWNER_FREE) // pass OWNER_FREE to keep old owner
|
||||
ioRec->owner = owner;
|
||||
ioRec->resourcesUsed |= resources;
|
||||
ioRec->owner = owner;
|
||||
ioRec->resource = resource;
|
||||
ioRec->index = index;
|
||||
}
|
||||
|
||||
void IORelease(IO_t io)
|
||||
|
@ -210,10 +223,10 @@ resourceOwner_t IOGetOwner(IO_t io)
|
|||
return ioRec->owner;
|
||||
}
|
||||
|
||||
resourceType_t IOGetResources(IO_t io)
|
||||
resourceType_t IOGetResource(IO_t io)
|
||||
{
|
||||
ioRec_t *ioRec = IO_Rec(io);
|
||||
return ioRec->resourcesUsed;
|
||||
return ioRec->resource;
|
||||
}
|
||||
|
||||
#if defined(STM32F1)
|
||||
|
|
|
@ -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 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_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)
|
||||
|
@ -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_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_IPU_25 IO_CONFIG(GPIO_Mode_IN, GPIO_Speed_25MHz, 0, GPIO_PuPd_UP)
|
||||
|
||||
#elif defined(UNIT_TEST)
|
||||
|
||||
|
@ -84,7 +86,7 @@ void IOHi(IO_t io);
|
|||
void IOLo(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
|
||||
resourceOwner_t IOGetOwner(IO_t io);
|
||||
resourceType_t IOGetResources(IO_t io);
|
||||
|
|
|
@ -12,7 +12,8 @@ typedef struct ioRec_s {
|
|||
GPIO_TypeDef *gpio;
|
||||
uint16_t pin;
|
||||
resourceOwner_t owner;
|
||||
resourceType_t resourcesUsed; // TODO!
|
||||
resourceType_t resource;
|
||||
uint8_t index;
|
||||
} ioRec_t;
|
||||
|
||||
extern ioRec_t ioRecs[DEFIO_IO_USED_COUNT];
|
||||
|
|
|
@ -26,17 +26,17 @@ static const IO_t leds[] = {
|
|||
#ifdef LED0
|
||||
DEFIO_IO(LED0),
|
||||
#else
|
||||
DEFIO_IO(NONE),
|
||||
DEFIO_IO(NONE),
|
||||
#endif
|
||||
#ifdef LED1
|
||||
DEFIO_IO(LED1),
|
||||
#else
|
||||
DEFIO_IO(NONE),
|
||||
DEFIO_IO(NONE),
|
||||
#endif
|
||||
#ifdef LED2
|
||||
DEFIO_IO(LED2),
|
||||
#else
|
||||
DEFIO_IO(NONE),
|
||||
DEFIO_IO(NONE),
|
||||
#endif
|
||||
#if defined(LED0_A) || defined(LED1_A) || defined(LED2_A)
|
||||
#ifdef LED0_A
|
||||
|
@ -82,25 +82,25 @@ uint8_t ledOffset = 0;
|
|||
|
||||
void ledInit(bool alternative_led)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t i;
|
||||
|
||||
#if defined(LED0_A) || defined(LED1_A) || defined(LED2_A)
|
||||
if (alternative_led)
|
||||
ledOffset = LED_NUMBER;
|
||||
if (alternative_led)
|
||||
ledOffset = LED_NUMBER;
|
||||
#else
|
||||
UNUSED(alternative_led);
|
||||
UNUSED(alternative_led);
|
||||
#endif
|
||||
|
||||
LED0_OFF;
|
||||
LED1_OFF;
|
||||
LED2_OFF;
|
||||
LED0_OFF;
|
||||
LED1_OFF;
|
||||
LED2_OFF;
|
||||
|
||||
for (i = 0; i < LED_NUMBER; i++) {
|
||||
if (leds[i + ledOffset]) {
|
||||
IOInit(leds[i + ledOffset], OWNER_SYSTEM, RESOURCE_OUTPUT);
|
||||
IOConfigGPIO(leds[i + ledOffset], IOCFG_OUT_PP);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < LED_NUMBER; i++) {
|
||||
if (leds[i + ledOffset]) {
|
||||
IOInit(leds[i + ledOffset], OWNER_LED, RESOURCE_OUTPUT, RESOURCE_INDEX(i));
|
||||
IOConfigGPIO(leds[i + ledOffset], IOCFG_OUT_PP);
|
||||
}
|
||||
}
|
||||
|
||||
LED0_OFF;
|
||||
LED1_OFF;
|
||||
|
@ -109,11 +109,11 @@ void ledInit(bool alternative_led)
|
|||
|
||||
void ledToggle(int led)
|
||||
{
|
||||
IOToggle(leds[led + ledOffset]);
|
||||
IOToggle(leds[led + ledOffset]);
|
||||
}
|
||||
|
||||
void ledSet(int led, bool on)
|
||||
{
|
||||
bool inverted = (1 << (led + ledOffset)) & ledPolarity;
|
||||
IOWrite(leds[led + ledOffset], on ? inverted : !inverted);
|
||||
bool inverted = (1 << (led + ledOffset)) & ledPolarity;
|
||||
IOWrite(leds[led + ledOffset], on ? inverted : !inverted);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE);
|
||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, ws2811DMAHandler);
|
||||
ws2811LedStripHardwareInit();
|
||||
ws2811UpdateStrip();
|
||||
}
|
||||
|
@ -141,12 +132,11 @@ STATIC_UNIT_TESTED void updateLEDDMABuffer(uint8_t componentValue)
|
|||
*/
|
||||
void ws2811UpdateStrip(void)
|
||||
{
|
||||
static uint32_t waitCounter = 0;
|
||||
static rgbColor24bpp_t *rgb24;
|
||||
|
||||
// wait until previous transfer completes
|
||||
while(ws2811LedDataTransferInProgress) {
|
||||
waitCounter++;
|
||||
// don't wait - risk of infinite block, just get an update next time round
|
||||
if (ws2811LedDataTransferInProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
dmaBufferOffset = 0; // reset buffer memory index
|
||||
|
@ -173,4 +163,4 @@ void ws2811UpdateStrip(void)
|
|||
ws2811LedStripDMAEnable();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
|
||||
#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_0 9 // timer compare value for logical 0
|
||||
#endif
|
||||
|
||||
void ws2811LedStripInit(void);
|
||||
|
||||
|
|
|
@ -23,35 +23,40 @@
|
|||
#include "common/color.h"
|
||||
#include "drivers/light_ws2811strip.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)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
uint16_t prescalerValue;
|
||||
|
||||
#ifdef CC3D
|
||||
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);
|
||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
||||
|
||||
/* GPIOA Configuration: TIM3 Channel 1 as alternate function push-pull */
|
||||
GPIO_StructInit(&GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
#endif
|
||||
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
||||
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
||||
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
||||
IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP));
|
||||
|
||||
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
|
||||
/* Compute the prescaler value */
|
||||
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
|
||||
/* Time base configuration */
|
||||
|
@ -100,24 +105,20 @@ void ws2811LedStripHardwareInit(void)
|
|||
|
||||
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
|
||||
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
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);
|
||||
|
||||
ws2811Initialised = true;
|
||||
setStripColor(&hsv_white);
|
||||
ws2811UpdateStrip();
|
||||
}
|
||||
|
||||
void ws2811LedStripDMAEnable(void)
|
||||
{
|
||||
if (!ws2811Initialised)
|
||||
return;
|
||||
|
||||
DMA_SetCurrDataCounter(DMA1_Channel6, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
||||
TIM_SetCounter(TIM3, 0);
|
||||
TIM_Cmd(TIM3, ENABLE);
|
||||
DMA_Cmd(DMA1_Channel6, ENABLE);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,51 +20,51 @@
|
|||
|
||||
#include <platform.h>
|
||||
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "nvic.h"
|
||||
|
||||
#include "common/color.h"
|
||||
#include "drivers/light_ws2811strip.h"
|
||||
#include "dma.h"
|
||||
#include "rcc.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifndef WS2811_GPIO
|
||||
#define WS2811_GPIO GPIOB
|
||||
#define WS2811_GPIO_AHB_PERIPHERAL RCC_AHBPeriph_GPIOB
|
||||
#define WS2811_GPIO_AF GPIO_AF_1
|
||||
#define WS2811_PIN GPIO_Pin_8 // TIM16_CH1
|
||||
#define WS2811_PIN_SOURCE GPIO_PinSource8
|
||||
#ifdef LED_STRIP
|
||||
|
||||
#ifndef WS2811_PIN
|
||||
#define WS2811_PIN PB8 // TIM16_CH1
|
||||
#define WS2811_TIMER TIM16
|
||||
#define WS2811_TIMER_APB2_PERIPHERAL RCC_APB2Periph_TIM16
|
||||
#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
|
||||
|
||||
#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)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
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 */
|
||||
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);
|
||||
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
||||
|
||||
/* Compute the prescaler value */
|
||||
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
|
||||
|
@ -89,9 +89,6 @@ void ws2811LedStripHardwareInit(void)
|
|||
TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE);
|
||||
|
||||
/* configure DMA */
|
||||
/* DMA clock enable */
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
|
||||
/* DMA1 Channel Config */
|
||||
DMA_DeInit(WS2811_DMA_CHANNEL);
|
||||
|
||||
|
@ -114,24 +111,20 @@ void ws2811LedStripHardwareInit(void)
|
|||
|
||||
DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE);
|
||||
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
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);
|
||||
|
||||
ws2811Initialised = true;
|
||||
setStripColor(&hsv_white);
|
||||
ws2811UpdateStrip();
|
||||
}
|
||||
|
||||
void ws2811LedStripDMAEnable(void)
|
||||
{
|
||||
if (!ws2811Initialised)
|
||||
return;
|
||||
|
||||
DMA_SetCurrDataCounter(WS2811_DMA_CHANNEL, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
||||
TIM_SetCounter(WS2811_TIMER, 0);
|
||||
TIM_Cmd(WS2811_TIMER, ENABLE);
|
||||
DMA_Cmd(WS2811_DMA_CHANNEL, ENABLE);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,63 +23,116 @@
|
|||
#include "common/color.h"
|
||||
#include "light_ws2811strip.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
#include "io.h"
|
||||
#include "system.h"
|
||||
#include "rcc.h"
|
||||
#include "timer.h"
|
||||
|
||||
#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)
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
uint16_t prescalerValue;
|
||||
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
|
||||
|
||||
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
||||
|
||||
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
||||
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
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);
|
||||
|
||||
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));
|
||||
|
||||
// Stop timer
|
||||
TIM_Cmd(TIM5, DISABLE);
|
||||
TIM_Cmd(WS2811_TIMER, DISABLE);
|
||||
|
||||
/* Compute the prescaler value */
|
||||
prescalerValue = (uint16_t) (SystemCoreClock / 2 / 84000000) - 1;
|
||||
prescalerValue = (uint16_t)(SystemCoreClock / 2 / 84000000) - 1;
|
||||
|
||||
/* Time base configuration */
|
||||
TIM_TimeBaseStructure.TIM_Period = 104; // 800kHz
|
||||
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_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
|
||||
TIM_TimeBaseInit(WS2811_TIMER, &TIM_TimeBaseStructure);
|
||||
|
||||
/* PWM1 Mode configuration: Channel1 */
|
||||
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_OutputNState = TIM_OutputNState_Disable;
|
||||
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 */
|
||||
/* DMA1 Channel Config */
|
||||
DMA_Cmd(DMA1_Stream2, DISABLE); // disable DMA channel 6
|
||||
DMA_DeInit(DMA1_Stream2);
|
||||
DMA_Cmd(WS2811_DMA_STREAM, DISABLE);
|
||||
DMA_DeInit(WS2811_DMA_STREAM);
|
||||
DMA_StructInit(&DMA_InitStructure);
|
||||
DMA_InitStructure.DMA_Channel = DMA_Channel_6;
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM5->CCR1);
|
||||
DMA_InitStructure.DMA_Channel = WS2811_DMA_CHANNEL;
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = channelAddress;
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||
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_MemoryBurst = DMA_MemoryBurst_Single;
|
||||
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||
DMA_Init(DMA1_Stream2, &DMA_InitStructure);
|
||||
|
||||
DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE);
|
||||
DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2); // clear DMA1 Channel 6 transfer complete flag
|
||||
DMA_Init(WS2811_DMA_STREAM, &DMA_InitStructure);
|
||||
|
||||
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;
|
||||
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);
|
||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
||||
|
||||
ws2811Initialised = true;
|
||||
setStripColor(&hsv_white);
|
||||
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)
|
||||
{
|
||||
DMA_SetCurrDataCounter(DMA1_Stream2, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
||||
TIM_SetCounter(TIM5, 0);
|
||||
DMA_Cmd(DMA1_Stream2, ENABLE);
|
||||
TIM_DMACmd(TIM5, TIM_DMA_CC1, ENABLE);
|
||||
if (!ws2811Initialised)
|
||||
return;
|
||||
|
||||
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
|
||||
|
|
|
@ -15,20 +15,20 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common/printf.h"
|
||||
#include "platform.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef USE_MAX7456
|
||||
|
||||
#include "common/printf.h"
|
||||
#include "drivers/bus_spi.h"
|
||||
#include "drivers/light_led.h"
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/nvic.h"
|
||||
#include "drivers/dma.h"
|
||||
|
||||
#include "max7456.h"
|
||||
#include "max7456_symbols.h"
|
||||
|
@ -36,24 +36,116 @@
|
|||
#define DISABLE_MAX7456 IOHi(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;
|
||||
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 max7456_lock = 0;
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
@ -64,7 +156,7 @@ void max7456_init(uint8_t video_system)
|
|||
#ifdef MAX7456_SPI_CS_PIN
|
||||
max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN));
|
||||
#endif
|
||||
IOInit(max7456CsPin, OWNER_SYSTEM, RESOURCE_SPI);
|
||||
IOInit(max7456CsPin, OWNER_OSD, RESOURCE_SPI_CS, 0);
|
||||
IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG);
|
||||
|
||||
//Minimum spi clock period for max7456 is 100ns (10Mhz)
|
||||
|
@ -112,94 +204,66 @@ void max7456_init(uint8_t video_system)
|
|||
|
||||
DISABLE_MAX7456;
|
||||
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
|
||||
void max7456_write_string(const char *string, int16_t address) {
|
||||
char *dest;
|
||||
MAX7456_CHAR_TYPE *dest;
|
||||
|
||||
if (address >= 0)
|
||||
dest = max7456_screen + address;
|
||||
dest = SCREEN_BUFFER + address;
|
||||
else
|
||||
dest = max7456_screen + (max_screen_size + address);
|
||||
dest = SCREEN_BUFFER + (max_screen_size + address);
|
||||
|
||||
while(*string && dest < (max7456_screen + max_screen_size))
|
||||
*dest++ = *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;
|
||||
while(*string && dest < (SCREEN_BUFFER + max_screen_size)) {
|
||||
*dest++ = MAX7456_CHAR(*string++);
|
||||
}
|
||||
}
|
||||
|
||||
void max7456_draw_screen(void) {
|
||||
uint16_t xx;
|
||||
if (!max7456_lock) {
|
||||
ENABLE_MAX7456;
|
||||
for (xx = 0; xx < max_screen_size; ++xx) {
|
||||
max7456_send(MAX7456ADD_DMAH, xx>>8);
|
||||
max7456_send(MAX7456ADD_DMAL, xx);
|
||||
max7456_send(MAX7456ADD_DMDI, max7456_screen[xx]);
|
||||
max7456_screen[xx] = ' ';
|
||||
}
|
||||
DISABLE_MAX7456;
|
||||
}
|
||||
}
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
max7456_send_dma(max7456_screen, NULL, max_screen_size * 2 + 10);
|
||||
#else
|
||||
uint16_t xx;
|
||||
max7456_lock = 1;
|
||||
|
||||
void max7456_draw_screen_fast(void) {
|
||||
uint16_t xx;
|
||||
if (!max7456_lock) {
|
||||
ENABLE_MAX7456;
|
||||
max7456_send(MAX7456ADD_DMAH, 0);
|
||||
max7456_send(MAX7456ADD_DMAL, 0);
|
||||
max7456_send(MAX7456ADD_DMM, 1);
|
||||
for (xx = 0; xx < max_screen_size; ++xx) {
|
||||
max7456_send(MAX7456ADD_DMDI, max7456_screen[xx]);
|
||||
max7456_screen[xx] = ' ';
|
||||
max7456_send(MAX7456ADD_DMDI, SCREEN_BUFFER[xx]);
|
||||
SCREEN_BUFFER[xx] = MAX7456_CHAR(0);
|
||||
}
|
||||
max7456_send(MAX7456ADD_DMDI, 0xFF);
|
||||
max7456_send(MAX7456ADD_DMM, 0);
|
||||
DISABLE_MAX7456;
|
||||
max7456_lock = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) {
|
||||
uint8_t x;
|
||||
|
||||
#ifdef MAX7456_DMA_CHANNEL_TX
|
||||
while (dma_transaction_in_progress);
|
||||
#endif
|
||||
while (max7456_lock);
|
||||
max7456_lock = 1;
|
||||
ENABLE_MAX7456;
|
||||
|
||||
|
|
|
@ -143,12 +143,18 @@
|
|||
enum VIDEO_TYPES { AUTO = 0, PAL, NTSC };
|
||||
|
||||
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_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_nvm(uint8_t char_address, uint8_t *font_data);
|
||||
MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#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_CALLBACK NVIC_BUILD_PRIORITY(0x0f, 0x0f)
|
||||
#define NVIC_PRIO_MAX7456_DMA NVIC_BUILD_PRIORITY(3, 0)
|
||||
|
||||
// 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)
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -93,16 +92,6 @@ pwmOutputConfiguration_t *pwmGetOutputConfiguration(void)
|
|||
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)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -111,7 +100,7 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
int channelIndex = 0;
|
||||
|
||||
memset(&pwmOutputConfiguration, 0, sizeof(pwmOutputConfiguration));
|
||||
|
||||
|
||||
// this is pretty hacky shit, but it will do for now. array of 4 config maps, [ multiPWM multiPPM airPWM airPPM ]
|
||||
if (init->airplane)
|
||||
i = 2; // switch to air hardware config
|
||||
|
@ -142,9 +131,9 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
continue;
|
||||
#endif
|
||||
|
||||
#if defined(STM32F303xC) && defined(USE_USART3)
|
||||
#if defined(STM32F303xC) && defined(USE_UART3)
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
|
@ -157,33 +146,33 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
continue;
|
||||
#endif
|
||||
|
||||
#ifdef LED_STRIP_TIMER
|
||||
#ifdef WS2811_TIMER
|
||||
// skip LED Strip output
|
||||
if (init->useLEDStrip) {
|
||||
if (timerHardwarePtr->tim == LED_STRIP_TIMER)
|
||||
if (timerHardwarePtr->tim == WS2811_TIMER)
|
||||
continue;
|
||||
#if defined(STM32F303xC) && defined(WS2811_GPIO) && defined(WS2811_PIN_SOURCE)
|
||||
if (CheckGPIOPinSource(timerHardwarePtr->tag, WS2811_GPIO, WS2811_PIN_SOURCE))
|
||||
#if defined(STM32F303xC) && defined(WS2811_PIN)
|
||||
if (timerHardwarePtr->tag == IO_TAG(WS2811_PIN))
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef VBAT_ADC_GPIO
|
||||
if (init->useVbat && CheckGPIOPin(timerHardwarePtr->tag, VBAT_ADC_GPIO, VBAT_ADC_GPIO_PIN)) {
|
||||
#ifdef VBAT_ADC_PIN
|
||||
if (init->useVbat && timerHardwarePtr->tag == IO_TAG(VBAT_ADC_PIN)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
@ -274,7 +263,7 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
}
|
||||
|
||||
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 (init->useLEDStrip) {
|
||||
if (timerIndex >= PWM13 && timerIndex <= PWM14) {
|
||||
|
@ -306,7 +295,7 @@ pwmOutputConfiguration_t *pwmInit(drv_pwm_config_t *init)
|
|||
|
||||
if (type == MAP_TO_PPM_INPUT) {
|
||||
#if defined(SPARKY) || defined(ALIENFLIGHTF3)
|
||||
if (init->useFastPwm || init->pwmProtocolType == PWM_TYPE_BRUSHED) {
|
||||
if (init->useFastPwm || init->pwmProtocolType == PWM_TYPE_BRUSHED) {
|
||||
ppmAvoidPWMTimerClash(timerHardwarePtr, TIM2);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,10 +34,20 @@
|
|||
#define MAX_INPUTS 8
|
||||
#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 MULTISHOT_TIMER_MHZ 72
|
||||
#define ONESHOT42_TIMER_MHZ 24
|
||||
#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 {
|
||||
ioTag_t triggerTag;
|
||||
|
@ -78,23 +88,21 @@ typedef struct drv_pwm_config_s {
|
|||
} drv_pwm_config_t;
|
||||
|
||||
enum {
|
||||
MAP_TO_PPM_INPUT = 1,
|
||||
MAP_TO_PPM_INPUT = 1,
|
||||
MAP_TO_PWM_INPUT,
|
||||
MAP_TO_MOTOR_OUTPUT,
|
||||
MAP_TO_SERVO_OUTPUT,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PWM_PF_NONE = 0,
|
||||
PWM_PF_MOTOR = (1 << 0),
|
||||
PWM_PF_SERVO = (1 << 1),
|
||||
PWM_PF_MOTOR_MODE_BRUSHED = (1 << 2),
|
||||
PWM_PF_OUTPUT_PROTOCOL_PWM = (1 << 3),
|
||||
PWM_PF_OUTPUT_PROTOCOL_ONESHOT = (1 << 4)
|
||||
PWM_PF_NONE = 0,
|
||||
PWM_PF_MOTOR = (1 << 0),
|
||||
PWM_PF_SERVO = (1 << 1),
|
||||
PWM_PF_MOTOR_MODE_BRUSHED = (1 << 2),
|
||||
PWM_PF_OUTPUT_PROTOCOL_PWM = (1 << 3),
|
||||
PWM_PF_OUTPUT_PROTOCOL_ONESHOT = (1 << 4)
|
||||
} pwmPortFlags_e;
|
||||
|
||||
enum {PWM_INVERTED = 1};
|
||||
|
||||
typedef struct pwmPortConfiguration_s {
|
||||
uint8_t index;
|
||||
pwmPortFlags_e flags;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
pwmOutputPort_t *p = &pwmOutputPorts[allocatedOutputPortCount++];
|
||||
|
||||
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_Cmd(timerHardware->tim, ENABLE);
|
||||
|
@ -121,6 +118,8 @@ static pwmOutputPort_t *pwmOutConfig(const timerHardware_t *timerHardware, uint8
|
|||
p->period = period;
|
||||
p->tim = timerHardware->tim;
|
||||
|
||||
*p->ccr = 0;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -134,9 +133,19 @@ static void pwmWriteStandard(uint8_t index, uint16_t 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)
|
||||
{
|
||||
*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)
|
||||
|
@ -221,7 +230,9 @@ void pwmFastPwmMotorConfig(const timerHardware_t *timerHardware, uint8_t motorIn
|
|||
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
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include "build_config.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)
|
||||
{
|
||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||
|
@ -372,7 +365,10 @@ void pwmInConfig(const timerHardware_t *timerHardwarePtr, uint8_t channel)
|
|||
self->mode = INPUT_MODE_PWM;
|
||||
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);
|
||||
|
||||
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->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);
|
||||
|
||||
timerConfigure(timerHardwarePtr, (uint16_t)PPM_TIMER_PERIOD, PWM_TIMER_MHZ);
|
||||
|
|
|
@ -7,7 +7,7 @@ void RCC_ClockCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
|
|||
int tag = periphTag >> 5;
|
||||
uint32_t mask = 1 << (periphTag & 0x1f);
|
||||
switch (tag) {
|
||||
#if defined(STM32F303xC)
|
||||
#if defined(STM32F3) || defined(STM32F1)
|
||||
case RCC_AHB:
|
||||
RCC_AHBPeriphClockCmd(mask, NewState);
|
||||
break;
|
||||
|
@ -18,7 +18,7 @@ void RCC_ClockCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
|
|||
case RCC_APB1:
|
||||
RCC_APB1PeriphClockCmd(mask, NewState);
|
||||
break;
|
||||
#if defined(STM32F40_41xxx) || defined(STM32F411xE)
|
||||
#if defined(STM32F4)
|
||||
case RCC_AHB1:
|
||||
RCC_AHB1PeriphClockCmd(mask, NewState);
|
||||
break;
|
||||
|
@ -31,7 +31,7 @@ void RCC_ResetCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
|
|||
int tag = periphTag >> 5;
|
||||
uint32_t mask = 1 << (periphTag & 0x1f);
|
||||
switch (tag) {
|
||||
#if defined(STM32F303xC)
|
||||
#if defined(STM32F3) || defined(STM32F10X_CL)
|
||||
case RCC_AHB:
|
||||
RCC_AHBPeriphResetCmd(mask, NewState);
|
||||
break;
|
||||
|
@ -42,7 +42,7 @@ void RCC_ResetCmd(rccPeriphTag_t periphTag, FunctionalState NewState)
|
|||
case RCC_APB1:
|
||||
RCC_APB1PeriphResetCmd(mask, NewState);
|
||||
break;
|
||||
#if defined(STM32F40_41xxx) || defined(STM32F411xE)
|
||||
#if defined(STM32F4)
|
||||
case RCC_AHB1:
|
||||
RCC_AHB1PeriphResetCmd(mask, NewState);
|
||||
break;
|
||||
|
|
|
@ -1,46 +1,52 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define RESOURCE_INDEX(x) x + 1
|
||||
|
||||
typedef enum {
|
||||
OWNER_FREE = 0,
|
||||
OWNER_PWMINPUT,
|
||||
OWNER_PPMINPUT,
|
||||
OWNER_PWMOUTPUT_MOTOR,
|
||||
OWNER_PWMOUTPUT_SERVO,
|
||||
OWNER_SOFTSERIAL_RX,
|
||||
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_MOTOR,
|
||||
OWNER_SERVO,
|
||||
OWNER_SOFTSERIAL,
|
||||
OWNER_ADC,
|
||||
OWNER_SERIAL_RX,
|
||||
OWNER_SERIAL_TX,
|
||||
OWNER_SERIAL_RXTX,
|
||||
OWNER_SERIAL,
|
||||
OWNER_PINDEBUG,
|
||||
OWNER_TIMER,
|
||||
OWNER_SONAR,
|
||||
OWNER_SYSTEM,
|
||||
OWNER_SPI,
|
||||
OWNER_I2C,
|
||||
OWNER_SDCARD,
|
||||
OWNER_FLASH,
|
||||
OWNER_USB,
|
||||
OWNER_BEEPER,
|
||||
OWNER_OSD,
|
||||
OWNER_BARO,
|
||||
OWNER_MPU,
|
||||
OWNER_INVERTER,
|
||||
OWNER_LED_STRIP,
|
||||
OWNER_LED,
|
||||
OWNER_RX,
|
||||
OWNER_TX,
|
||||
OWNER_TOTAL_COUNT
|
||||
} 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)
|
||||
// with mode switching (shared serial ports, ...) this will need some improvement
|
||||
typedef enum {
|
||||
RESOURCE_NONE = 0,
|
||||
RESOURCE_INPUT = 1 << 0,
|
||||
RESOURCE_OUTPUT = 1 << 1,
|
||||
RESOURCE_IO = RESOURCE_INPUT | RESOURCE_OUTPUT,
|
||||
RESOURCE_TIMER = 1 << 2,
|
||||
RESOURCE_TIMER_DUAL = 1 << 3, // channel used in dual-capture, other channel will be allocated too
|
||||
RESOURCE_USART = 1 << 4,
|
||||
RESOURCE_ADC = 1 << 5,
|
||||
RESOURCE_EXTI = 1 << 6,
|
||||
RESOURCE_I2C = 1 << 7,
|
||||
RESOURCE_SPI = 1 << 8,
|
||||
RESOURCE_INPUT, RESOURCE_OUTPUT, RESOURCE_IO,
|
||||
RESOURCE_TIMER,
|
||||
RESOURCE_UART_TX, RESOURCE_UART_RX, RESOURCE_UART_TXRX,
|
||||
RESOURCE_EXTI,
|
||||
RESOURCE_I2C_SCL, RESOURCE_I2C_SDA,
|
||||
RESOURCE_SPI_SCK, RESOURCE_SPI_MOSI, RESOURCE_SPI_MISO, RESOURCE_SPI_CS,
|
||||
RESOURCE_ADC_BATTERY, RESOURCE_ADC_RSSI, RESOURCE_ADC_EXTERNAL1, RESOURCE_ADC_CURRENT,
|
||||
RESOURCE_TOTAL_COUNT
|
||||
} resourceType_t;
|
||||
|
||||
extern const char * const resourceNames[RESOURCE_TOTAL_COUNT];
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef USE_SDCARD
|
||||
|
||||
#include "nvic.h"
|
||||
#include "io.h"
|
||||
|
||||
|
@ -30,8 +31,6 @@
|
|||
#include "sdcard.h"
|
||||
#include "sdcard_standard.h"
|
||||
|
||||
#ifdef USE_SDCARD
|
||||
|
||||
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
|
||||
#define SDCARD_PROFILING
|
||||
#endif
|
||||
|
@ -44,7 +43,7 @@
|
|||
// Chosen so that CMD8 will have the same CRC as CMD0:
|
||||
#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
|
||||
|
||||
/* 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
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
@ -135,7 +134,7 @@ void sdcardInsertionDetectInit(void)
|
|||
{
|
||||
#ifdef 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);
|
||||
#endif
|
||||
}
|
||||
|
@ -547,10 +546,10 @@ void sdcard_init(bool useDMA)
|
|||
|
||||
#ifdef 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);
|
||||
#endif // SDCARD_SPI_CS_PIN
|
||||
|
||||
|
||||
// Max frequency is initially 400kHz
|
||||
spiSetDivisor(SDCARD_SPI_INSTANCE, SDCARD_SPI_INITIALIZATION_CLOCK_DIVIDER);
|
||||
|
||||
|
@ -559,7 +558,7 @@ void sdcard_init(bool useDMA)
|
|||
|
||||
// Transmit at least 74 dummy clock cycles with CS high so the SD card can start up
|
||||
SET_CS_HIGH;
|
||||
|
||||
|
||||
spiTransfer(SDCARD_SPI_INSTANCE, NULL, NULL, SDCARD_INIT_NUM_DUMMY_BYTES);
|
||||
|
||||
// Wait for that transmission to finish before we enable the SDCard, so it receives the required number of cycles:
|
||||
|
@ -1059,7 +1058,7 @@ bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationComp
|
|||
sdcard.pendingOperation.blockIndex = blockIndex;
|
||||
sdcard.pendingOperation.callback = callback;
|
||||
sdcard.pendingOperation.callbackData = callbackData;
|
||||
|
||||
|
||||
sdcard.state = SDCARD_STATE_READING;
|
||||
|
||||
sdcard.operationStartTime = millis();
|
||||
|
|
|
@ -22,4 +22,4 @@ typedef void (*sensorInitFuncPtr)(void); // sensor init proto
|
|||
typedef bool (*sensorReadFuncPtr)(int16_t *data); // sensor read and align prototype
|
||||
typedef void (*sensorAccInitFuncPtr)(struct acc_s *acc); // 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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ struct serialPortVTable {
|
|||
};
|
||||
|
||||
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);
|
||||
void serialWriteBuf(serialPort_t *instance, uint8_t *data, int count);
|
||||
uint8_t serialRead(serialPort_t *instance);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -96,23 +95,24 @@ void setTxSignal(softSerial_t *softSerial, uint8_t state)
|
|||
if (state) {
|
||||
IOHi(softSerial->txIO);
|
||||
} else {
|
||||
IOLo(softSerial->txIO);
|
||||
IOLo(softSerial->txIO);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
IOConfigGPIO(IOGetByTag(pin), mode);
|
||||
IOInit(IOGetByTag(pin), OWNER_SOFTSERIAL, RESOURCE_UART_RX, RESOURCE_INDEX(portIndex));
|
||||
#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
|
||||
softSerialGPIOConfig(pin, IOCFG_IPU);
|
||||
#else
|
||||
softSerialGPIOConfig(pin, IOCFG_AF_PP_UP);
|
||||
#endif
|
||||
IOInit(IOGetByTag(pin), OWNER_SOFTSERIAL, RESOURCE_UART_TX, RESOURCE_INDEX(portIndex));
|
||||
IOConfigGPIO(IOGetByTag(pin), IOCFG_OUT_PP);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void serialOutputPortConfig(ioTag_t pin)
|
||||
{
|
||||
softSerialGPIOConfig(pin, IOCFG_OUT_PP);
|
||||
}
|
||||
|
||||
static void resetBuffers(softSerial_t *softSerial)
|
||||
{
|
||||
softSerial->port.rxBufferSize = SOFTSERIAL_BUFFER_SIZE;
|
||||
|
@ -219,10 +214,10 @@ serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallb
|
|||
softSerial->softSerialPortIndex = portIndex;
|
||||
|
||||
softSerial->txIO = IOGetByTag(softSerial->txTimerHardware->tag);
|
||||
serialOutputPortConfig(softSerial->txTimerHardware->tag);
|
||||
|
||||
serialOutputPortConfig(softSerial->txTimerHardware->tag, portIndex);
|
||||
|
||||
softSerial->rxIO = IOGetByTag(softSerial->rxTimerHardware->tag);
|
||||
serialInputPortConfig(softSerial->rxTimerHardware->tag);
|
||||
serialInputPortConfig(softSerial->rxTimerHardware->tag, portIndex);
|
||||
|
||||
setTxSignal(softSerial, ENABLE);
|
||||
delay(50);
|
||||
|
@ -271,8 +266,6 @@ void processTxState(softSerial_t *softSerial)
|
|||
softSerial->isTransmittingData = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
TRAILING,
|
||||
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) {
|
||||
return 0;
|
||||
|
|
|
@ -28,7 +28,7 @@ serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallb
|
|||
|
||||
// serialPort API
|
||||
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 softSerialReadByte(serialPort_t *instance);
|
||||
void softSerialSetBaudRate(serialPort_t *s, uint32_t baudRate);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -99,26 +98,26 @@ serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback,
|
|||
uartPort_t *s = NULL;
|
||||
|
||||
if (USARTx == USART1) {
|
||||
s = serialUSART1(baudRate, mode, options);
|
||||
#ifdef USE_USART2
|
||||
s = serialUART1(baudRate, mode, options);
|
||||
#ifdef USE_UART2
|
||||
} else if (USARTx == USART2) {
|
||||
s = serialUSART2(baudRate, mode, options);
|
||||
s = serialUART2(baudRate, mode, options);
|
||||
#endif
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
} else if (USARTx == USART3) {
|
||||
s = serialUSART3(baudRate, mode, options);
|
||||
s = serialUART3(baudRate, mode, options);
|
||||
#endif
|
||||
#ifdef USE_USART4
|
||||
#ifdef USE_UART4
|
||||
} else if (USARTx == UART4) {
|
||||
s = serialUSART4(baudRate, mode, options);
|
||||
s = serialUART4(baudRate, mode, options);
|
||||
#endif
|
||||
#ifdef USE_USART5
|
||||
#ifdef USE_UART5
|
||||
} else if (USARTx == UART5) {
|
||||
s = serialUSART5(baudRate, mode, options);
|
||||
s = serialUART5(baudRate, mode, options);
|
||||
#endif
|
||||
#ifdef USE_USART6
|
||||
#ifdef USE_UART6
|
||||
} else if (USARTx == USART6) {
|
||||
s = serialUSART6(baudRate, mode, options);
|
||||
s = serialUART6(baudRate, mode, options);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
|
|
@ -40,13 +40,13 @@ typedef struct {
|
|||
serialPort_t port;
|
||||
|
||||
#ifdef STM32F4
|
||||
DMA_Stream_TypeDef *rxDMAStream;
|
||||
DMA_Stream_TypeDef *txDMAStream;
|
||||
uint32_t rxDMAChannel;
|
||||
uint32_t txDMAChannel;
|
||||
DMA_Stream_TypeDef *rxDMAStream;
|
||||
DMA_Stream_TypeDef *txDMAStream;
|
||||
uint32_t rxDMAChannel;
|
||||
uint32_t txDMAChannel;
|
||||
#else
|
||||
DMA_Channel_TypeDef *rxDMAChannel;
|
||||
DMA_Channel_TypeDef *txDMAChannel;
|
||||
DMA_Channel_TypeDef *rxDMAChannel;
|
||||
DMA_Channel_TypeDef *txDMAChannel;
|
||||
#endif
|
||||
|
||||
uint32_t rxDMAIrq;
|
||||
|
|
|
@ -23,10 +23,10 @@ extern const struct serialPortVTable uartVTable[];
|
|||
|
||||
void uartStartTxDMA(uartPort_t *s);
|
||||
|
||||
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUSART6(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
uartPort_t *serialUART6(uint32_t baudRate, portMode_t mode, portOptions_t options);
|
||||
|
||||
|
|
|
@ -24,38 +24,32 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
#include "rcc.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "serial_uart.h"
|
||||
#include "serial_uart_impl.h"
|
||||
|
||||
#ifdef USE_USART1
|
||||
#ifdef USE_UART1
|
||||
static uartPort_t uartPort1;
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
static uartPort_t uartPort2;
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
static uartPort_t uartPort3;
|
||||
#endif
|
||||
|
||||
// Using RX DMA disables the use of receive callbacks
|
||||
#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)
|
||||
void uartIrqCallback(uartPort_t *s)
|
||||
{
|
||||
uint16_t SR = s->USARTx->SR;
|
||||
|
||||
|
@ -82,69 +76,74 @@ 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)
|
||||
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;
|
||||
static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE];
|
||||
gpio_config_t gpio;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
s = &uartPort1;
|
||||
s->port.vTable = uartVTable;
|
||||
|
||||
|
||||
s->port.baudRate = baudRate;
|
||||
|
||||
|
||||
s->port.rxBuffer = rx1Buffer;
|
||||
s->port.txBuffer = tx1Buffer;
|
||||
s->port.rxBufferSize = UART1_RX_BUFFER_SIZE;
|
||||
s->port.txBufferSize = UART1_TX_BUFFER_SIZE;
|
||||
|
||||
|
||||
s->USARTx = USART1;
|
||||
|
||||
|
||||
#ifdef USE_USART1_RX_DMA
|
||||
#ifdef USE_UART1_RX_DMA
|
||||
s->rxDMAChannel = DMA1_Channel5;
|
||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
#endif
|
||||
s->txDMAChannel = DMA1_Channel4;
|
||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB2(USART1), ENABLE);
|
||||
RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
|
||||
|
||||
// USART1_TX PA9
|
||||
// USART1_RX PA10
|
||||
gpio.speed = Speed_2MHz;
|
||||
|
||||
gpio.pin = Pin_9;
|
||||
// UART1_TX PA9
|
||||
// UART1_RX PA10
|
||||
if (options & SERIAL_BIDIR) {
|
||||
gpio.mode = Mode_AF_OD;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(PA9)), OWNER_SERIAL, RESOURCE_UART_TXRX, 1);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(PA9)), IOCFG_AF_OD);
|
||||
} else {
|
||||
if (mode & MODE_TX) {
|
||||
gpio.mode = Mode_AF_PP;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(PA9)), OWNER_SERIAL, RESOURCE_UART_TX, 1);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(PA9)), IOCFG_AF_PP);
|
||||
}
|
||||
|
||||
if (mode & MODE_RX) {
|
||||
gpio.pin = Pin_10;
|
||||
gpio.mode = Mode_IPU;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(PA10)), OWNER_SERIAL, RESOURCE_UART_RX, 1);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(PA10)), IOCFG_IPU);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
dmaSetHandler(DMA1_CH4_HANDLER, uart_tx_dma_IRQHandler, NVIC_PRIO_SERIALUART1_TXDMA, (uint32_t)&uartPort1);
|
||||
|
||||
#ifndef USE_USART1_RX_DMA
|
||||
#ifndef USE_UART1_RX_DMA
|
||||
// RX/TX Interrupt
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1);
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1);
|
||||
|
@ -155,75 +154,57 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
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
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort1;
|
||||
usartIrqCallback(s);
|
||||
uartIrqCallback(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
// 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;
|
||||
static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE];
|
||||
gpio_config_t gpio;
|
||||
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
s = &uartPort2;
|
||||
s->port.vTable = uartVTable;
|
||||
|
||||
|
||||
s->port.baudRate = baudRate;
|
||||
|
||||
|
||||
s->port.rxBufferSize = UART2_RX_BUFFER_SIZE;
|
||||
s->port.txBufferSize = UART2_TX_BUFFER_SIZE;
|
||||
s->port.rxBuffer = rx2Buffer;
|
||||
s->port.txBuffer = tx2Buffer;
|
||||
|
||||
|
||||
s->USARTx = USART2;
|
||||
|
||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB1(USART2), ENABLE);
|
||||
RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
|
||||
|
||||
// USART2_TX PA2
|
||||
// USART2_RX PA3
|
||||
gpio.speed = Speed_2MHz;
|
||||
|
||||
gpio.pin = Pin_2;
|
||||
// UART2_TX PA2
|
||||
// UART2_RX PA3
|
||||
if (options & SERIAL_BIDIR) {
|
||||
gpio.mode = Mode_AF_OD;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(PA2)), OWNER_SERIAL, RESOURCE_UART_TXRX, 2);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(PA2)), IOCFG_AF_OD);
|
||||
} else {
|
||||
if (mode & MODE_TX) {
|
||||
gpio.mode = Mode_AF_PP;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(PA2)), OWNER_SERIAL, RESOURCE_UART_TX, 2);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(PA2)), IOCFG_AF_PP);
|
||||
}
|
||||
|
||||
if (mode & MODE_RX) {
|
||||
gpio.pin = Pin_3;
|
||||
gpio.mode = Mode_IPU;
|
||||
gpioInit(GPIOA, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(PA3)), OWNER_SERIAL, RESOURCE_UART_RX, 2);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(PA3)), IOCFG_IPU);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,19 +223,19 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
void USART2_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort2;
|
||||
usartIrqCallback(s);
|
||||
uartIrqCallback(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
// 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;
|
||||
static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE];
|
||||
gpio_config_t gpio;
|
||||
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
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->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
|
||||
#ifdef USART3_APB1_PERIPHERALS
|
||||
RCC_APB1PeriphClockCmd(USART3_APB1_PERIPHERALS, ENABLE);
|
||||
#endif
|
||||
#ifdef USART3_APB2_PERIPHERALS
|
||||
RCC_APB2PeriphClockCmd(USART3_APB2_PERIPHERALS, ENABLE);
|
||||
#endif
|
||||
RCC_ClockCmd(RCC_APB1(USART3), ENABLE);
|
||||
|
||||
gpio.speed = Speed_2MHz;
|
||||
|
||||
gpio.pin = USART3_TX_PIN;
|
||||
if (options & SERIAL_BIDIR) {
|
||||
gpio.mode = Mode_AF_OD;
|
||||
gpioInit(USART3_GPIO, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), OWNER_SERIAL, RESOURCE_UART_TXRX, 3);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOCFG_AF_OD);
|
||||
} else {
|
||||
if (mode & MODE_TX) {
|
||||
gpio.mode = Mode_AF_PP;
|
||||
gpioInit(USART3_GPIO, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), OWNER_SERIAL, RESOURCE_UART_TX, 3);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOCFG_AF_PP);
|
||||
}
|
||||
|
||||
if (mode & MODE_RX) {
|
||||
gpio.pin = USART3_RX_PIN;
|
||||
gpio.mode = Mode_IPU;
|
||||
gpioInit(USART3_GPIO, &gpio);
|
||||
IOInit(IOGetByTag(IO_TAG(UART3_RX_PIN)), OWNER_SERIAL, RESOURCE_UART_RX, 3);
|
||||
IOConfigGPIO(IOGetByTag(IO_TAG(UART3_RX_PIN)), IOCFG_IPU);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,6 +284,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
void USART3_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort3;
|
||||
usartIrqCallback(s);
|
||||
uartIrqCallback(s);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,106 +25,137 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "gpio.h"
|
||||
#include "io.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
#include "rcc.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "serial_uart.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_USART2_TX_DMA
|
||||
//#define USE_USART3_RX_DMA
|
||||
//#define USE_USART3_TX_DMA
|
||||
|
||||
#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
|
||||
#ifdef USE_UART1
|
||||
#ifndef UART1_TX_PIN
|
||||
#define UART1_TX_PIN PA9 // PA9
|
||||
#endif
|
||||
#ifndef UART1_RX_PIN
|
||||
#define UART1_RX_PIN PA10 // PA10
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UART2_GPIO
|
||||
#define UART2_TX_PIN GPIO_Pin_5 // PD5
|
||||
#define UART2_RX_PIN GPIO_Pin_6 // PD6
|
||||
#define UART2_GPIO GPIOD
|
||||
#define UART2_GPIO_AF GPIO_AF_7
|
||||
#define UART2_TX_PINSOURCE GPIO_PinSource5
|
||||
#define UART2_RX_PINSOURCE GPIO_PinSource6
|
||||
#ifdef USE_UART2
|
||||
#ifndef UART2_TX_PIN
|
||||
#define UART2_TX_PIN PD5 // PD5
|
||||
#endif
|
||||
#ifndef UART2_RX_PIN
|
||||
#define UART2_RX_PIN PD6 // PD6
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UART3_GPIO
|
||||
#define UART3_TX_PIN GPIO_Pin_10 // PB10 (AF7)
|
||||
#define UART3_RX_PIN GPIO_Pin_11 // PB11 (AF7)
|
||||
#define UART3_GPIO_AF GPIO_AF_7
|
||||
#define UART3_GPIO GPIOB
|
||||
#define UART3_TX_PINSOURCE GPIO_PinSource10
|
||||
#define UART3_RX_PINSOURCE GPIO_PinSource11
|
||||
#ifdef USE_UART3
|
||||
#ifndef UART3_TX_PIN
|
||||
#define UART3_TX_PIN PB10 // PB10 (AF7)
|
||||
#endif
|
||||
#ifndef UART3_RX_PIN
|
||||
#define UART3_RX_PIN PB11 // PB11 (AF7)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UART4_GPIO
|
||||
#define UART4_TX_PIN GPIO_Pin_10 // PC10 (AF5)
|
||||
#define UART4_RX_PIN GPIO_Pin_11 // PC11 (AF5)
|
||||
#define UART4_GPIO_AF GPIO_AF_5
|
||||
#define UART4_GPIO GPIOC
|
||||
#define UART4_TX_PINSOURCE GPIO_PinSource10
|
||||
#define UART4_RX_PINSOURCE GPIO_PinSource11
|
||||
#ifdef USE_UART4
|
||||
#ifndef UART4_TX_PIN
|
||||
#define UART4_TX_PIN PC10 // PC10 (AF5)
|
||||
#endif
|
||||
#ifndef UART4_RX_PIN
|
||||
#define UART4_RX_PIN PC11 // PC11 (AF5)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef UART5_GPIO // The real UART5_RX is on PD2, no board is using.
|
||||
#define UART5_TX_PIN GPIO_Pin_12 // PC12 (AF5)
|
||||
#define UART5_RX_PIN GPIO_Pin_12 // PC12 (AF5)
|
||||
#define UART5_GPIO_AF GPIO_AF_5
|
||||
#define UART5_GPIO GPIOC
|
||||
#define UART5_TX_PINSOURCE GPIO_PinSource12
|
||||
#define UART5_RX_PINSOURCE GPIO_PinSource12
|
||||
#ifdef USE_UART5
|
||||
#ifndef UART5_TX_PIN // The real UART5_RX is on PD2, no board is using.
|
||||
#define UART5_TX_PIN PC12 // PC12 (AF5)
|
||||
#endif
|
||||
#ifndef UART5_RX_PIN
|
||||
#define UART5_RX_PIN PC12 // PC12 (AF5)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART1
|
||||
#ifdef USE_UART1
|
||||
static uartPort_t uartPort1;
|
||||
#endif
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
static uartPort_t uartPort2;
|
||||
#endif
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
static uartPort_t uartPort3;
|
||||
#endif
|
||||
#ifdef USE_USART4
|
||||
#ifdef USE_UART4
|
||||
static uartPort_t uartPort4;
|
||||
#endif
|
||||
#ifdef USE_USART5
|
||||
#ifdef USE_UART5
|
||||
static uartPort_t uartPort5;
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART1
|
||||
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
static void handleUsartTxDma(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;
|
||||
}
|
||||
|
||||
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;
|
||||
static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE];
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
s = &uartPort1;
|
||||
s->port.vTable = uartVTable;
|
||||
|
||||
|
||||
s->port.baudRate = baudRate;
|
||||
|
||||
|
||||
s->port.rxBuffer = rx1Buffer;
|
||||
s->port.txBuffer = tx1Buffer;
|
||||
s->port.rxBufferSize = UART1_RX_BUFFER_SIZE;
|
||||
s->port.txBufferSize = UART1_TX_BUFFER_SIZE;
|
||||
|
||||
#ifdef USE_USART1_RX_DMA
|
||||
|
||||
#ifdef USE_UART1_RX_DMA
|
||||
s->rxDMAChannel = DMA1_Channel5;
|
||||
#endif
|
||||
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->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB2(USART1), ENABLE);
|
||||
RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
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;
|
||||
serialUARTInit(IOGetByTag(IO_TAG(UART1_TX_PIN)), IOGetByTag(IO_TAG(UART1_RX_PIN)), mode, options, GPIO_AF_7, 1);
|
||||
|
||||
if (options & SERIAL_BIDIR) {
|
||||
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);
|
||||
}
|
||||
dmaSetHandler(DMA1_CH4_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART1_TXDMA, (uint32_t)&uartPort1);
|
||||
|
||||
if (mode & MODE_RX) {
|
||||
GPIO_InitStructure.GPIO_Pin = UART1_RX_PIN;
|
||||
GPIO_PinAFConfig(UART1_GPIO, UART1_RX_PINSOURCE, UART1_GPIO_AF);
|
||||
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
|
||||
}
|
||||
}
|
||||
#ifndef USE_UART1_RX_DMA
|
||||
NVIC_InitTypeDef NVIC_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_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_RXDMA);
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_RXDMA);
|
||||
|
@ -182,78 +186,50 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART2
|
||||
uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
#ifdef USE_UART2
|
||||
uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
{
|
||||
uartPort_t *s;
|
||||
static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE];
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
s = &uartPort2;
|
||||
s->port.vTable = uartVTable;
|
||||
|
||||
|
||||
s->port.baudRate = baudRate;
|
||||
|
||||
|
||||
s->port.rxBufferSize = UART2_RX_BUFFER_SIZE;
|
||||
s->port.txBufferSize = UART2_TX_BUFFER_SIZE;
|
||||
s->port.rxBuffer = rx2Buffer;
|
||||
s->port.txBuffer = tx2Buffer;
|
||||
|
||||
s->USARTx = USART2;
|
||||
|
||||
#ifdef USE_USART2_RX_DMA
|
||||
|
||||
#ifdef USE_UART2_RX_DMA
|
||||
s->rxDMAChannel = DMA1_Channel6;
|
||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
|
||||
#endif
|
||||
#ifdef USE_USART2_TX_DMA
|
||||
#ifdef USE_UART2_TX_DMA
|
||||
s->txDMAChannel = DMA1_Channel7;
|
||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
|
||||
#endif
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB1(USART2), ENABLE);
|
||||
|
||||
#if defined(USE_USART2_TX_DMA) || defined(USE_USART2_RX_DMA)
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
#if defined(USE_UART2_TX_DMA) || defined(USE_UART2_RX_DMA)
|
||||
RCC_ClockCmd(RCC_AHB(DMA1), ENABLE);
|
||||
#endif
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
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;
|
||||
serialUARTInit(IOGetByTag(IO_TAG(UART2_TX_PIN)), IOGetByTag(IO_TAG(UART2_RX_PIN)), mode, options, GPIO_AF_7, 2);
|
||||
|
||||
if (options & SERIAL_BIDIR) {
|
||||
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
|
||||
#ifdef USE_UART2_TX_DMA
|
||||
// DMA TX Interrupt
|
||||
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
|
||||
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);
|
||||
dmaSetHandler(DMA1_CH7_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART2_TXDMA, (uint32_t)&uartPort2);
|
||||
#endif
|
||||
|
||||
#ifndef USE_USART2_RX_DMA
|
||||
#ifndef USE_UART2_RX_DMA
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(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
|
||||
|
||||
#ifdef USE_USART3
|
||||
uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
#ifdef USE_UART3
|
||||
uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
{
|
||||
uartPort_t *s;
|
||||
static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE];
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
s = &uartPort3;
|
||||
s->port.vTable = uartVTable;
|
||||
|
@ -286,57 +260,31 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
|
||||
s->USARTx = USART3;
|
||||
|
||||
#ifdef USE_USART3_RX_DMA
|
||||
#ifdef USE_UART3_RX_DMA
|
||||
s->rxDMAChannel = DMA1_Channel3;
|
||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR;
|
||||
#endif
|
||||
#ifdef USE_USART3_TX_DMA
|
||||
#ifdef USE_UART3_TX_DMA
|
||||
s->txDMAChannel = DMA1_Channel2;
|
||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR;
|
||||
#endif
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB1(USART3), ENABLE);
|
||||
|
||||
#if defined(USE_USART3_TX_DMA) || defined(USE_USART3_RX_DMA)
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
#if defined(USE_UART3_TX_DMA) || defined(USE_UART3_RX_DMA)
|
||||
RCC_AHBClockCmd(RCC_AHB(DMA1), ENABLE);
|
||||
#endif
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
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;
|
||||
serialUARTInit(IOGetByTag(IO_TAG(UART3_TX_PIN)), IOGetByTag(IO_TAG(UART3_RX_PIN)), mode, options, GPIO_AF_7, 3);
|
||||
|
||||
if (options & SERIAL_BIDIR) {
|
||||
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
|
||||
#ifdef USE_UART3_TX_DMA
|
||||
// DMA TX Interrupt
|
||||
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
|
||||
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);
|
||||
dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, (uint32_t)&uartPort3);
|
||||
#endif
|
||||
|
||||
#ifndef USE_USART3_RX_DMA
|
||||
#ifndef USE_UART3_RX_DMA
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(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
|
||||
|
||||
#ifdef USE_USART4
|
||||
uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
#ifdef USE_UART4
|
||||
uartPort_t *serialUART4(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
{
|
||||
uartPort_t *s;
|
||||
static volatile uint8_t rx4Buffer[UART4_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx4Buffer[UART4_TX_BUFFER_SIZE];
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
s = &uartPort4;
|
||||
s->port.vTable = uartVTable;
|
||||
|
@ -369,33 +316,9 @@ uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
|
||||
s->USARTx = UART4;
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB1(UART4), ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
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);
|
||||
}
|
||||
}
|
||||
serialUARTInit(IOGetByTag(IO_TAG(UART4_TX_PIN)), IOGetByTag(IO_TAG(UART4_RX_PIN)), mode, options, GPIO_AF_5, 4);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
|
||||
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
|
||||
|
||||
#ifdef USE_USART5
|
||||
uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
#ifdef USE_UART5
|
||||
uartPort_t *serialUART5(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
{
|
||||
uartPort_t *s;
|
||||
static volatile uint8_t rx5Buffer[UART5_RX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx5Buffer[UART5_TX_BUFFER_SIZE];
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
s = &uartPort5;
|
||||
s->port.vTable = uartVTable;
|
||||
|
@ -428,33 +350,9 @@ uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t optio
|
|||
|
||||
s->USARTx = UART5;
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
|
||||
RCC_ClockCmd(RCC_APB1(UART5), ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
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);
|
||||
}
|
||||
}
|
||||
serialUARTInit(IOGetByTag(IO_TAG(UART5_TX_PIN)), IOGetByTag(IO_TAG(UART5_RX_PIN)), mode, options, GPIO_AF_5, 5);
|
||||
|
||||
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
uartPort_t *s = &uartPort1;
|
||||
|
@ -549,7 +405,7 @@ void USART1_IRQHandler(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort2;
|
||||
|
@ -558,7 +414,7 @@ void USART2_IRQHandler(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort3;
|
||||
|
@ -567,7 +423,7 @@ void USART3_IRQHandler(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART4
|
||||
#ifdef USE_UART4
|
||||
void UART4_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort4;
|
||||
|
@ -576,7 +432,7 @@ void UART4_IRQHandler(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART5
|
||||
#ifdef USE_UART5
|
||||
void UART5_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &uartPort5;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -25,19 +24,12 @@
|
|||
#include "io.h"
|
||||
#include "rcc.h"
|
||||
#include "nvic.h"
|
||||
#include "dma.h"
|
||||
|
||||
#include "serial.h"
|
||||
#include "serial_uart.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_TX_BUFFER_SIZE UART1_TX_BUFFER_SIZE
|
||||
|
||||
|
@ -71,138 +63,138 @@ typedef struct uartDevice_s {
|
|||
} uartDevice_t;
|
||||
|
||||
//static uartPort_t uartPort[MAX_UARTS];
|
||||
#ifdef USE_USART1
|
||||
#ifdef USE_UART1
|
||||
static uartDevice_t uart1 =
|
||||
{
|
||||
.DMAChannel = DMA_Channel_4,
|
||||
.txDMAStream = DMA2_Stream7,
|
||||
#ifdef USE_USART1_RX_DMA
|
||||
#ifdef USE_UART1_RX_DMA
|
||||
.rxDMAStream = DMA2_Stream5,
|
||||
#endif
|
||||
.dev = USART1,
|
||||
.rx = IO_TAG(USART1_RX_PIN),
|
||||
.tx = IO_TAG(USART1_TX_PIN),
|
||||
.rx = IO_TAG(UART1_RX_PIN),
|
||||
.tx = IO_TAG(UART1_TX_PIN),
|
||||
.af = GPIO_AF_USART1,
|
||||
#ifdef USART1_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = USART1_AHB1_PERIPHERALS,
|
||||
#ifdef UART1_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = UART1_AHB1_PERIPHERALS,
|
||||
#endif
|
||||
.rcc_apb2 = RCC_APB2(USART1),
|
||||
.txIrq = DMA2_Stream7_IRQn,
|
||||
.txIrq = DMA2_ST7_HANDLER,
|
||||
.rxIrq = USART1_IRQn,
|
||||
.txPriority = NVIC_PRIO_SERIALUART1_TXDMA,
|
||||
.rxPriority = NVIC_PRIO_SERIALUART1
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
static uartDevice_t uart2 =
|
||||
{
|
||||
.DMAChannel = DMA_Channel_4,
|
||||
#ifdef USE_USART2_RX_DMA
|
||||
#ifdef USE_UART2_RX_DMA
|
||||
.rxDMAStream = DMA1_Stream5,
|
||||
#endif
|
||||
.txDMAStream = DMA1_Stream6,
|
||||
.dev = USART2,
|
||||
.rx = IO_TAG(USART2_RX_PIN),
|
||||
.tx = IO_TAG(USART2_TX_PIN),
|
||||
.rx = IO_TAG(UART2_RX_PIN),
|
||||
.tx = IO_TAG(UART2_TX_PIN),
|
||||
.af = GPIO_AF_USART2,
|
||||
#ifdef USART2_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = USART2_AHB1_PERIPHERALS,
|
||||
#ifdef UART2_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = UART2_AHB1_PERIPHERALS,
|
||||
#endif
|
||||
.rcc_apb1 = RCC_APB1(USART2),
|
||||
.txIrq = DMA1_Stream6_IRQn,
|
||||
.txIrq = DMA1_ST6_HANDLER,
|
||||
.rxIrq = USART2_IRQn,
|
||||
.txPriority = NVIC_PRIO_SERIALUART2_TXDMA,
|
||||
.rxPriority = NVIC_PRIO_SERIALUART2
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
static uartDevice_t uart3 =
|
||||
{
|
||||
.DMAChannel = DMA_Channel_4,
|
||||
#ifdef USE_USART3_RX_DMA
|
||||
#ifdef USE_UART3_RX_DMA
|
||||
.rxDMAStream = DMA1_Stream1,
|
||||
#endif
|
||||
.txDMAStream = DMA1_Stream3,
|
||||
.dev = USART3,
|
||||
.rx = IO_TAG(USART3_RX_PIN),
|
||||
.tx = IO_TAG(USART3_TX_PIN),
|
||||
.rx = IO_TAG(UART3_RX_PIN),
|
||||
.tx = IO_TAG(UART3_TX_PIN),
|
||||
.af = GPIO_AF_USART3,
|
||||
#ifdef USART3_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = USART3_AHB1_PERIPHERALS,
|
||||
#ifdef UART3_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = UART3_AHB1_PERIPHERALS,
|
||||
#endif
|
||||
.rcc_apb1 = RCC_APB1(USART3),
|
||||
.txIrq = DMA1_Stream3_IRQn,
|
||||
.txIrq = DMA1_ST3_HANDLER,
|
||||
.rxIrq = USART3_IRQn,
|
||||
.txPriority = NVIC_PRIO_SERIALUART3_TXDMA,
|
||||
.rxPriority = NVIC_PRIO_SERIALUART3
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART4
|
||||
#ifdef USE_UART4
|
||||
static uartDevice_t uart4 =
|
||||
{
|
||||
.DMAChannel = DMA_Channel_4,
|
||||
#ifdef USE_USART1_RX_DMA
|
||||
#ifdef USE_UART1_RX_DMA
|
||||
.rxDMAStream = DMA1_Stream2,
|
||||
#endif
|
||||
.txDMAStream = DMA1_Stream4,
|
||||
.dev = UART4,
|
||||
.rx = IO_TAG(USART4_RX_PIN),
|
||||
.tx = IO_TAG(USART4_TX_PIN),
|
||||
.rx = IO_TAG(UART4_RX_PIN),
|
||||
.tx = IO_TAG(UART4_TX_PIN),
|
||||
.af = GPIO_AF_UART4,
|
||||
#ifdef USART4_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = USART4_AHB1_PERIPHERALS,
|
||||
#ifdef UART4_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = UART4_AHB1_PERIPHERALS,
|
||||
#endif
|
||||
.rcc_apb1 = RCC_APB1(UART4),
|
||||
.txIrq = DMA1_Stream4_IRQn,
|
||||
.txIrq = DMA1_ST4_HANDLER,
|
||||
.rxIrq = UART4_IRQn,
|
||||
.txPriority = NVIC_PRIO_SERIALUART4_TXDMA,
|
||||
.rxPriority = NVIC_PRIO_SERIALUART4
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART5
|
||||
#ifdef USE_UART5
|
||||
static uartDevice_t uart5 =
|
||||
{
|
||||
.DMAChannel = DMA_Channel_4,
|
||||
#ifdef USE_USART1_RX_DMA
|
||||
#ifdef USE_UART1_RX_DMA
|
||||
.rxDMAStream = DMA1_Stream0,
|
||||
#endif
|
||||
.txDMAStream = DMA2_Stream7,
|
||||
.dev = UART5,
|
||||
.rx = IO_TAG(USART5_RX_PIN),
|
||||
.tx = IO_TAG(USART5_TX_PIN),
|
||||
.rx = IO_TAG(UART5_RX_PIN),
|
||||
.tx = IO_TAG(UART5_TX_PIN),
|
||||
.af = GPIO_AF_UART5,
|
||||
#ifdef USART5_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = USART5_AHB1_PERIPHERALS,
|
||||
#ifdef UART5_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = UART5_AHB1_PERIPHERALS,
|
||||
#endif
|
||||
.rcc_apb1 = RCC_APB1(UART5),
|
||||
.txIrq = DMA2_Stream7_IRQn,
|
||||
.txIrq = DMA2_ST7_HANDLER,
|
||||
.rxIrq = UART5_IRQn,
|
||||
.txPriority = NVIC_PRIO_SERIALUART5_TXDMA,
|
||||
.rxPriority = NVIC_PRIO_SERIALUART5
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART6
|
||||
#ifdef USE_UART6
|
||||
static uartDevice_t uart6 =
|
||||
{
|
||||
.DMAChannel = DMA_Channel_5,
|
||||
#ifdef USE_USART6_RX_DMA
|
||||
#ifdef USE_UART6_RX_DMA
|
||||
.rxDMAStream = DMA2_Stream1,
|
||||
#endif
|
||||
.txDMAStream = DMA2_Stream6,
|
||||
.dev = USART6,
|
||||
.rx = IO_TAG(USART6_RX_PIN),
|
||||
.tx = IO_TAG(USART6_TX_PIN),
|
||||
.rx = IO_TAG(UART6_RX_PIN),
|
||||
.tx = IO_TAG(UART6_TX_PIN),
|
||||
.af = GPIO_AF_USART6,
|
||||
#ifdef USART6_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = USART6_AHB1_PERIPHERALS,
|
||||
#ifdef UART6_AHB1_PERIPHERALS
|
||||
.rcc_ahb1 = UART6_AHB1_PERIPHERALS,
|
||||
#endif
|
||||
.rcc_apb2 = RCC_APB2(USART6),
|
||||
.txIrq = DMA2_Stream6_IRQn,
|
||||
.txIrq = DMA2_ST6_HANDLER,
|
||||
.rxIrq = USART6_IRQn,
|
||||
.txPriority = NVIC_PRIO_SERIALUART6_TXDMA,
|
||||
.rxPriority = NVIC_PRIO_SERIALUART6
|
||||
|
@ -210,39 +202,39 @@ static uartDevice_t uart6 =
|
|||
#endif
|
||||
|
||||
static uartDevice_t* uartHardwareMap[] = {
|
||||
#ifdef USE_USART1
|
||||
#ifdef USE_UART1
|
||||
&uart1,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
&uart2,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
&uart3,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef USE_USART4
|
||||
#ifdef USE_UART4
|
||||
&uart4,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef USE_USART5
|
||||
#ifdef USE_UART5
|
||||
&uart5,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef USE_USART6
|
||||
#ifdef USE_UART6
|
||||
&uart6,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
void usartIrqHandler(uartPort_t *s)
|
||||
void uartIrqHandler(uartPort_t *s)
|
||||
{
|
||||
if (!s->rxDMAStream && (USART_GetITStatus(s->USARTx, USART_IT_RXNE) == SET)) {
|
||||
if (s->port.callback) {
|
||||
|
@ -278,24 +270,47 @@ static void handleUsartTxDma(uartPort_t *s)
|
|||
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;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
uartDevice_t *uart = uartHardwareMap[device];
|
||||
if (!uart) return NULL;
|
||||
|
||||
|
||||
s = &(uart->port);
|
||||
s->port.vTable = uartVTable;
|
||||
|
||||
|
||||
s->port.baudRate = baudRate;
|
||||
|
||||
|
||||
s->port.rxBuffer = uart->rxBuffer;
|
||||
s->port.txBuffer = uart->txBuffer;
|
||||
s->port.rxBufferSize = sizeof(uart->rxBuffer);
|
||||
s->port.txBufferSize = sizeof(uart->txBuffer);
|
||||
|
||||
|
||||
s->USARTx = uart->dev;
|
||||
if (uart->rxDMAStream) {
|
||||
s->rxDMAChannel = uart->DMAChannel;
|
||||
|
@ -303,44 +318,40 @@ uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, p
|
|||
}
|
||||
s->txDMAChannel = uart->DMAChannel;
|
||||
s->txDMAStream = uart->txDMAStream;
|
||||
|
||||
|
||||
s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR;
|
||||
|
||||
|
||||
IO_t tx = IOGetByTag(uart->tx);
|
||||
IO_t rx = IOGetByTag(uart->rx);
|
||||
|
||||
|
||||
if (uart->rcc_apb2)
|
||||
RCC_ClockCmd(uart->rcc_apb2, ENABLE);
|
||||
|
||||
|
||||
if (uart->rcc_apb1)
|
||||
RCC_ClockCmd(uart->rcc_apb1, ENABLE);
|
||||
|
||||
|
||||
if (uart->rcc_ahb1)
|
||||
RCC_AHB1PeriphClockCmd(uart->rcc_ahb1, ENABLE);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// DMA TX Interrupt
|
||||
NVIC_InitStructure.NVIC_IRQChannel = uart->txIrq;
|
||||
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);
|
||||
dmaSetHandler(uart->txIrq, dmaIRQHandler, uart->txPriority, (uint32_t)uart);
|
||||
|
||||
if (!(s->rxDMAChannel)) {
|
||||
NVIC_InitStructure.NVIC_IRQChannel = uart->rxIrq;
|
||||
|
@ -353,230 +364,86 @@ uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, p
|
|||
return s;
|
||||
}
|
||||
|
||||
#ifdef USE_USART1
|
||||
uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
#ifdef USE_UART1
|
||||
uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t options)
|
||||
{
|
||||
return serialUSART(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);
|
||||
}
|
||||
return serialUART(UARTDEV_1, baudRate, mode, options);
|
||||
}
|
||||
|
||||
// USART1 Rx/Tx IRQ Handler
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port);
|
||||
usartIrqHandler(s);
|
||||
uartIrqHandler(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART2
|
||||
#ifdef USE_UART2
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
return serialUART(UARTDEV_2, baudRate, mode, options);
|
||||
}
|
||||
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port);
|
||||
usartIrqHandler(s);
|
||||
uartIrqHandler(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART3
|
||||
#ifdef USE_UART3
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
return serialUART(UARTDEV_3, baudRate, mode, options);
|
||||
}
|
||||
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port);
|
||||
usartIrqHandler(s);
|
||||
uartIrqHandler(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART4
|
||||
#ifdef USE_UART4
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
return serialUART(UARTDEV_4, baudRate, mode, options);
|
||||
}
|
||||
|
||||
void UART4_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port);
|
||||
usartIrqHandler(s);
|
||||
uartIrqHandler(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART5
|
||||
#ifdef USE_UART5
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
return serialUART(UARTDEV_5, baudRate, mode, options);
|
||||
}
|
||||
|
||||
void UART5_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port);
|
||||
usartIrqHandler(s);
|
||||
uartIrqHandler(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_USART6
|
||||
#ifdef USE_UART6
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
return serialUART(UARTDEV_6, baudRate, mode, options);
|
||||
}
|
||||
|
||||
void USART6_IRQHandler(void)
|
||||
{
|
||||
uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port);
|
||||
usartIrqHandler(s);
|
||||
uartIrqHandler(s);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -117,7 +115,7 @@ static bool usbVcpFlush(vcpPort_t *port)
|
|||
if (count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (!usbIsConnected() || !usbIsConfigured()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -181,14 +179,14 @@ serialPort_t *usbVcpOpen(void)
|
|||
vcpPort_t *s;
|
||||
|
||||
#ifdef STM32F4
|
||||
IOInit(IOGetByTag(IO_TAG(PA11)), OWNER_USB, RESOURCE_IO);
|
||||
IOInit(IOGetByTag(IO_TAG(PA12)), OWNER_USB, RESOURCE_IO);
|
||||
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);
|
||||
IOInit(IOGetByTag(IO_TAG(PA11)), OWNER_USB, RESOURCE_INPUT, 0);
|
||||
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);
|
||||
#else
|
||||
Set_System();
|
||||
Set_USBClock();
|
||||
USB_Interrupts_Config();
|
||||
USB_Init();
|
||||
Set_System();
|
||||
Set_USBClock();
|
||||
USB_Interrupts_Config();
|
||||
USB_Init();
|
||||
#endif
|
||||
|
||||
s = &vcpPort;
|
||||
|
|
|
@ -83,18 +83,18 @@ void hcsr04_init(sonarRange_t *sonarRange)
|
|||
|
||||
// trigger pin
|
||||
triggerIO = IOGetByTag(sonarHardwareHCSR04.triggerTag);
|
||||
IOInit(triggerIO, OWNER_SONAR, RESOURCE_INPUT);
|
||||
IOInit(triggerIO, OWNER_SONAR, RESOURCE_OUTPUT, 0);
|
||||
IOConfigGPIO(triggerIO, IOCFG_OUT_PP);
|
||||
|
||||
|
||||
// echo pin
|
||||
echoIO = IOGetByTag(sonarHardwareHCSR04.echoTag);
|
||||
IOInit(echoIO, OWNER_SONAR, RESOURCE_INPUT);
|
||||
IOInit(echoIO, OWNER_SONAR, RESOURCE_INPUT, 0);
|
||||
IOConfigGPIO(echoIO, IOCFG_IN_FLOATING);
|
||||
|
||||
#ifdef USE_EXTI
|
||||
EXTIHandlerInit(&hcsr04_extiCallbackRec, hcsr04_extiHandler);
|
||||
EXTIConfig(echoIO, &hcsr04_extiCallbackRec, NVIC_PRIO_SONAR_EXTI, EXTI_Trigger_Rising_Falling); // TODO - priority!
|
||||
EXTIEnable(echoIO, true);
|
||||
EXTIHandlerInit(&hcsr04_extiCallbackRec, hcsr04_extiHandler);
|
||||
EXTIConfig(echoIO, &hcsr04_extiCallbackRec, NVIC_PRIO_SONAR_EXTI, EXTI_Trigger_Rising_Falling); // TODO - priority!
|
||||
EXTIEnable(echoIO, true);
|
||||
#endif
|
||||
|
||||
lastMeasurementAt = millis() - 60; // force 1st measurement in hcsr04_get_distance()
|
||||
|
|
|
@ -17,12 +17,9 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "common/utils.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "io.h"
|
||||
|
||||
|
@ -39,31 +36,31 @@ static bool beeperInverted = false;
|
|||
void systemBeep(bool onoff)
|
||||
{
|
||||
#ifndef BEEPER
|
||||
UNUSED(onoff);
|
||||
UNUSED(onoff);
|
||||
#else
|
||||
IOWrite(beeperIO, beeperInverted ? onoff : !onoff);
|
||||
IOWrite(beeperIO, beeperInverted ? onoff : !onoff);
|
||||
#endif
|
||||
}
|
||||
|
||||
void systemBeepToggle(void)
|
||||
{
|
||||
#ifdef BEEPER
|
||||
IOToggle(beeperIO);
|
||||
IOToggle(beeperIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void beeperInit(const beeperConfig_t *config)
|
||||
{
|
||||
#ifndef BEEPER
|
||||
UNUSED(config);
|
||||
UNUSED(config);
|
||||
#else
|
||||
beeperIO = IOGetByTag(config->ioTag);
|
||||
beeperInverted = config->isInverted;
|
||||
beeperIO = IOGetByTag(config->ioTag);
|
||||
beeperInverted = config->isInverted;
|
||||
|
||||
if (beeperIO) {
|
||||
IOInit(beeperIO, OWNER_BEEPER, RESOURCE_OUTPUT);
|
||||
IOConfigGPIO(beeperIO, config->isOD ? IOCFG_OUT_OD : IOCFG_OUT_PP);
|
||||
}
|
||||
systemBeep(false);
|
||||
if (beeperIO) {
|
||||
IOInit(beeperIO, OWNER_BEEPER, RESOURCE_OUTPUT, 0);
|
||||
IOConfigGPIO(beeperIO, config->isOD ? IOCFG_OUT_OD : IOCFG_OUT_PP);
|
||||
}
|
||||
systemBeep(false);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
#endif
|
||||
|
||||
typedef struct beeperConfig_s {
|
||||
ioTag_t ioTag;
|
||||
unsigned isInverted : 1;
|
||||
unsigned isOD : 1;
|
||||
ioTag_t ioTag;
|
||||
unsigned isInverted : 1;
|
||||
unsigned isOD : 1;
|
||||
} beeperConfig_t;
|
||||
|
||||
void systemBeep(bool on);
|
||||
|
|
|
@ -15,15 +15,11 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "build_config.h"
|
||||
|
||||
#include "gpio.h"
|
||||
#include "light_led.h"
|
||||
#include "sound_beeper.h"
|
||||
|
|
|
@ -25,13 +25,13 @@ uint32_t micros(void);
|
|||
uint32_t millis(void);
|
||||
|
||||
typedef enum {
|
||||
FAILURE_DEVELOPER = 0,
|
||||
FAILURE_MISSING_ACC,
|
||||
FAILURE_ACC_INIT,
|
||||
FAILURE_ACC_INCOMPATIBLE,
|
||||
FAILURE_INVALID_EEPROM_CONTENTS,
|
||||
FAILURE_FLASH_WRITE_FAILED,
|
||||
FAILURE_GYRO_INIT_FAILED
|
||||
FAILURE_DEVELOPER = 0,
|
||||
FAILURE_MISSING_ACC,
|
||||
FAILURE_ACC_INIT,
|
||||
FAILURE_ACC_INCOMPATIBLE,
|
||||
FAILURE_INVALID_EEPROM_CONTENTS,
|
||||
FAILURE_FLASH_WRITE_FAILED,
|
||||
FAILURE_GYRO_INIT_FAILED
|
||||
} failureMode_e;
|
||||
|
||||
// failure
|
||||
|
@ -42,6 +42,7 @@ void systemReset(void);
|
|||
void systemResetToBootloader(void);
|
||||
bool isMPUSoftReset(void);
|
||||
void cycleCounterInit(void);
|
||||
void checkForBootLoaderRequest(void);
|
||||
|
||||
void enableGPIOPowerUsageAndNoiseReductions(void);
|
||||
// current crystal frequency - 8 or 12MHz
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -37,7 +36,8 @@ void systemReset(void)
|
|||
SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04;
|
||||
}
|
||||
|
||||
void systemResetToBootloader(void) {
|
||||
void systemResetToBootloader(void)
|
||||
{
|
||||
// 1FFFF000 -> 20000200 -> SP
|
||||
// 1FFFF004 -> 1FFFF021 -> PC
|
||||
|
||||
|
@ -68,8 +68,10 @@ bool isMPUSoftReset(void)
|
|||
|
||||
void systemInit(void)
|
||||
{
|
||||
checkForBootLoaderRequest();
|
||||
|
||||
SetSysClock(false);
|
||||
|
||||
|
||||
#ifdef CC3D
|
||||
/* Accounts for OP Bootloader, set the Vector Table base address as specified in .ld file */
|
||||
extern void *isr_vector_table_base;
|
||||
|
@ -110,3 +112,6 @@ void systemInit(void)
|
|||
SysTick_Config(SystemCoreClock / 1000);
|
||||
}
|
||||
|
||||
void checkForBootLoaderRequest(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -35,7 +34,8 @@ void systemReset(void)
|
|||
SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)0x04;
|
||||
}
|
||||
|
||||
void systemResetToBootloader(void) {
|
||||
void systemResetToBootloader(void)
|
||||
{
|
||||
// 1FFFF000 -> 20000200 -> SP
|
||||
// 1FFFF004 -> 1FFFF021 -> PC
|
||||
|
||||
|
@ -82,6 +82,8 @@ bool isMPUSoftReset(void)
|
|||
|
||||
void systemInit(void)
|
||||
{
|
||||
checkForBootLoaderRequest();
|
||||
|
||||
// Enable FPU
|
||||
SCB->CPACR = (0x3 << (10 * 2)) | (0x3 << (11 * 2));
|
||||
SetSysClock();
|
||||
|
@ -102,3 +104,7 @@ void systemInit(void)
|
|||
// SysTick
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
}
|
||||
|
||||
void checkForBootLoaderRequest(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -15,26 +15,18 @@
|
|||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "accgyro_mpu.h"
|
||||
#include "gpio.h"
|
||||
#include "nvic.h"
|
||||
#include "system.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)
|
||||
|
@ -45,8 +37,8 @@ void systemReset(void)
|
|||
if (mpuConfiguration.reset)
|
||||
mpuConfiguration.reset();
|
||||
|
||||
__disable_irq();
|
||||
NVIC_SystemReset();
|
||||
__disable_irq();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void systemResetToBootloader(void)
|
||||
|
@ -54,10 +46,10 @@ void systemResetToBootloader(void)
|
|||
if (mpuConfiguration.reset)
|
||||
mpuConfiguration.reset();
|
||||
|
||||
*((uint32_t *)0x2001FFFC) = 0xDEADBEEF; // 128KB SRAM STM32F4XX
|
||||
*((uint32_t *)0x2001FFFC) = 0xDEADBEEF; // 128KB SRAM STM32F4XX
|
||||
|
||||
__disable_irq();
|
||||
NVIC_SystemReset();
|
||||
__disable_irq();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void enableGPIOPowerUsageAndNoiseReductions(void)
|
||||
|
@ -82,7 +74,7 @@ void enableGPIOPowerUsageAndNoiseReductions(void)
|
|||
RCC_AHB1Periph_BKPSRAM |
|
||||
RCC_AHB1Periph_DMA1 |
|
||||
RCC_AHB1Periph_DMA2 |
|
||||
0, ENABLE
|
||||
0, ENABLE
|
||||
);
|
||||
|
||||
RCC_AHB2PeriphClockCmd(0, ENABLE);
|
||||
|
@ -169,28 +161,45 @@ bool isMPUSoftReset(void)
|
|||
|
||||
void systemInit(void)
|
||||
{
|
||||
checkForBootLoaderRequest();
|
||||
|
||||
SetSysClock();
|
||||
|
||||
// Configure NVIC preempt/priority groups
|
||||
NVIC_PriorityGroupConfig(NVIC_PRIORITY_GROUPING);
|
||||
NVIC_PriorityGroupConfig(NVIC_PRIORITY_GROUPING);
|
||||
|
||||
// cache RCC->CSR value to use it in isMPUSoftreset() and others
|
||||
cachedRccCsrValue = RCC->CSR;
|
||||
cachedRccCsrValue = RCC->CSR;
|
||||
|
||||
/* Accounts for OP Bootloader, set the Vector Table base address as specified in .ld file */
|
||||
extern void *isr_vector_table_base;
|
||||
NVIC_SetVectorTable((uint32_t)&isr_vector_table_base, 0x0);
|
||||
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, DISABLE);
|
||||
|
||||
RCC_ClearFlag();
|
||||
extern void *isr_vector_table_base;
|
||||
NVIC_SetVectorTable((uint32_t)&isr_vector_table_base, 0x0);
|
||||
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, DISABLE);
|
||||
|
||||
enableGPIOPowerUsageAndNoiseReductions();
|
||||
RCC_ClearFlag();
|
||||
|
||||
enableGPIOPowerUsageAndNoiseReductions();
|
||||
|
||||
// Init cycle counter
|
||||
cycleCounterInit();
|
||||
cycleCounterInit();
|
||||
|
||||
memset(extiHandlerConfigs, 0x00, sizeof(extiHandlerConfigs));
|
||||
// SysTick
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
memset(extiHandlerConfigs, 0x00, sizeof(extiHandlerConfigs));
|
||||
// SysTick
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue