Skip to content

Commit 5fd0941

Browse files
committed
2 parents 73e2644 + f575fda commit 5fd0941

File tree

8 files changed

+346
-18
lines changed

8 files changed

+346
-18
lines changed

STM32F1/cores/maple/libmaple/i2c.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,24 @@ int32 i2c_master_xfer(i2c_dev *dev,
409409
// with state changes in the IRQ handlers:
410410
dev->state = I2C_STATE_ERROR;
411411
if (rc == I2C_ERROR_TIMEOUT) dev->error_flags |= I2C_SR1_TIMEOUT;
412+
if (!(dev->config_flags & I2C_SLAVE_MODE) &&
413+
(dev->error_flags & (I2C_SR1_AF | I2C_SR1_BERR | I2C_SR1_TIMEOUT))
414+
) { // In Master Mode, we need to abort the transmission with a STOP
415+
// for NACK, Bus Error, or Timeout
416+
uint32 cr1;
417+
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
418+
I2C_CR1_STOP |
419+
I2C_CR1_PEC)) {
420+
; // Must wait for pending start/stop/pec before setting stop to avoid
421+
// accidental restart condition. See ST RM0008 Note in 26.6.1 (I2C_CR1)
422+
}
423+
dev->regs->CR1 |= I2C_CR1_STOP;
424+
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
425+
I2C_CR1_STOP |
426+
I2C_CR1_PEC)) {
427+
;
428+
}
429+
}
412430
} else {
413431
dev->state = I2C_STATE_IDLE;
414432
}
@@ -782,14 +800,10 @@ void _i2c_irq_error_handler(i2c_dev *dev) {
782800
dev->state = I2C_STATE_IDLE;
783801
return;
784802
}
785-
} else {
786-
// Master should send a STOP on NACK:
787-
if (sr1 & I2C_SR1_AF) {
788-
dev->regs->CR1 |= I2C_CR1_STOP;
789-
}
790803
}
791804

792-
/* Catch any other strange errors while in slave mode.
805+
/* Catch any other strange errors while in slave mode and
806+
* all errors in master mode (which are handled by outer loop).
793807
* I have seen BERR caused by an over fast master device
794808
* as well as several overflows and arbitration failures.
795809
* We are going to reset SR flags and carry on at this point which

STM32F1/libraries/STM32ADC/examples/SingleChannelContinuousConversion/SingleChannelContinuousConversion.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
#include <STM32ADC.h>
77

8-
ADC myAdc(ADC1);
8+
STM32ADC myAdc(ADC1);
99

1010
void setup() {
1111
Serial.begin(19200);

STM32F1/libraries/Wire/Wire.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ uint8 TwoWire::process(uint8 stop) {
4444
if (sel_hard->error_flags & I2C_SR1_AF) { /* NACK */
4545
res = (sel_hard->error_flags & I2C_SR1_ADDR ? ENACKADDR :
4646
ENACKTRNS);
47-
} else if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */
48-
res = EDATA;
49-
} else { /* Bus or Arbitration error */
50-
res = EOTHER;
47+
} else {
48+
if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */
49+
res = EDATA;
50+
} else { /* Bus or Arbitration error */
51+
res = EOTHER;
52+
}
53+
i2c_disable(sel_hard);
54+
i2c_master_enable(sel_hard, dev_flags, frequency);
5155
}
52-
i2c_disable(sel_hard);
53-
i2c_master_enable(sel_hard, dev_flags, frequency);
5456
}
5557
return res;
5658
}

STM32F4/cores/maple/libmaple/adc.c

+32-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const adc_dev adc3 = {
7474
.handler_p = &adc3Handlers
7575
};
7676

77+
7778
adc_common_reg_map* const ADC_COMMON = ADC_COMMON_BASE;
7879

7980
/**
@@ -148,6 +149,12 @@ void adc_awd_enable_irq(const adc_dev * dev)
148149
nvic_irq_enable(NVIC_ADC_1_2_3);
149150
}
150151

152+
void adc_ovr_enable_irq(const adc_dev* dev)
153+
{
154+
dev->regs->CR1 |= ADC_CR1_OVRIE;
155+
nvic_irq_enable(NVIC_ADC_1_2_3);
156+
}
157+
151158
/*
152159
attach interrupt functionality for ADC
153160
use ADC_EOC, ADC_JEOC, ADC_AWD
@@ -160,7 +167,12 @@ void adc_attach_interrupt(const adc_dev *dev,
160167
if (irq_id<ADC_LAST_IRQ_ID)
161168
{
162169
(*(dev->handler_p))[irq_id] = handler;
163-
adc_enable_irq(dev);
170+
if(irq_id == ADC_EOC)
171+
adc_enable_irq(dev);
172+
else if (irq_id == ADC_AWD)
173+
adc_awd_enable_irq(dev);
174+
else if (irq_id == ADC_OVR)
175+
adc_ovr_enable_irq(dev);
164176
}
165177
}
166178

@@ -183,6 +195,16 @@ void adc_foreach(void (*fn)(const adc_dev*))
183195
fn(ADC3);
184196
}
185197

198+
/*
199+
* @param pre, setup the ADC prescaler to one of PCLK /2, /4, /6, /8
200+
* the templates per adc_prescaler enum
201+
*/
202+
void adc_set_prescaler(adc_prescaler pre) {
203+
204+
ADC_COMMON->CCR &= ~ ADC_CCR_ADCPRE;
205+
ADC_COMMON->CCR |= ((pre & 3U) << ADC_CCR_ADCPRE_SHIFT);
206+
}
207+
186208
/**
187209
* @brief Set the given sampling times for all channels.
188210
* Don't call this during conversion!
@@ -303,6 +325,15 @@ void adc_irq_handler(const adc_dev * dev)
303325
handler();
304326
}
305327
}
328+
//ADC overrun interrupt
329+
if (dev->regs->SR & ADC_SR_OVR) {
330+
dev->regs->SR = ~ADC_SR_OVR;
331+
voidFuncPtr handler = (*(dev->handler_p))[ADC_OVR];
332+
if (handler) {
333+
handler();
334+
}
335+
}
336+
306337
}
307338

308339
void __irq_adc()

STM32F4/cores/maple/libmaple/adc.h

+28-3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ typedef enum {
7272
ADC_EOC, // End Of Conversion interrupt.
7373
ADC_AWD , // Analog WatchDog interrupt
7474
ADC_JEOC, // Injected End Of Conversion interrupt.
75+
ADC_OVR, // overrun interrupt
7576
ADC_LAST_IRQ_ID
7677
} adc_irq_id;
7778

@@ -92,9 +93,10 @@ typedef struct adc_dev
9293
extern const adc_dev adc1;
9394
extern const adc_dev adc2;
9495
extern const adc_dev adc3;
95-
#define ADC1 (&adc1)
96-
#define ADC2 (&adc2)
97-
#define ADC3 (&adc3)
96+
97+
#define ADC1 ((adc_dev*) &adc1)
98+
#define ADC2 ((adc_dev*) &adc2)
99+
#define ADC3 ((adc_dev*) &adc3)
98100

99101
typedef struct adc_common_reg_map {
100102
__IO uint32 CSR; ///< Common status register
@@ -303,6 +305,7 @@ extern adc_common_reg_map* const ADC_COMMON;
303305
#define ADC_CCR_DELAY_SHIFT 8
304306
#define ADC_CCR_MULTI_SHIFT 0
305307

308+
306309
#define ADC_CCR_TSVREFE (0x1 << ADC_CCR_TSVREFE_BIT)
307310
#define ADC_CCR_VBATE (0x1 << ADC_CCR_VBATE_BIT)
308311
#define ADC_CCR_ADCPRE (0x3 << ADC_CCR_ADCPRE_SHIFT)
@@ -311,6 +314,20 @@ extern adc_common_reg_map* const ADC_COMMON;
311314
#define ADC_CCR_DELAY (0xF << ADC_CCR_DELAY_SHIFT)
312315
#define ADC_CCR_MULTI (0x1F << ADC_CCR_MULTI_SHIFT)
313316

317+
/**
318+
* @brief STM32F1/F4 ADC prescalers, as divisors of PCLK2.
319+
*/
320+
typedef enum adc_prescaler {
321+
/** PCLK2 divided by 2 */
322+
ADC_PRE_PCLK2_DIV_2 = 0,
323+
/** PCLK2 divided by 4 */
324+
ADC_PRE_PCLK2_DIV_4 = 1,
325+
/** PCLK2 divided by 6 */
326+
ADC_PRE_PCLK2_DIV_6 = 2,
327+
/** PCLK2 divided by 8 */
328+
ADC_PRE_PCLK2_DIV_8 = 3,
329+
} adc_prescaler;
330+
314331
/* Common regular data register */
315332

316333
#define ADC_CDR_DATA2 (0xFFFF << 16)
@@ -384,6 +401,7 @@ typedef enum {
384401
ADC_SMPR_480, /**< 480 ADC cycles */
385402
} adc_smp_rate;
386403

404+
void adc_set_prescaler(adc_prescaler pre);
387405
void adc_set_sampling_time(const adc_dev *dev, adc_smp_rate smp_rate);
388406
void adc_set_exttrig(const adc_dev *dev, adc_ext_trigger trigger);
389407
void adc_set_jextrig(const adc_dev *dev, adc_ext_trigger trigger);
@@ -392,6 +410,7 @@ void adc_set_jextsel(const adc_dev *dev, adc_jextsel_event event);
392410
void adc_foreach(void (*fn)(const adc_dev*));
393411
void adc_enable_irq(const adc_dev* dev);
394412
void adc_disable_irq(const adc_dev* dev);
413+
void adc_ovr_enable_irq(const adc_dev* dev);
395414
void adc_attach_interrupt(const adc_dev *dev, adc_irq_id irq_id, voidFuncPtr handler);
396415
void adc_set_reg_sequence(const adc_dev * dev, uint8 * channels, uint8 len);
397416
void adc_enable_tsvref(void);
@@ -478,6 +497,11 @@ static inline void adc_awd_enable(const adc_dev * dev)
478497
dev->regs->CR1 |= ADC_CR1_AWDEN;
479498
}
480499

500+
static inline void adc_awd_disable(const adc_dev * dev)
501+
{
502+
dev->regs->CR1 &= ~ADC_CR1_AWDEN;
503+
}
504+
481505
static inline void adc_set_scan_mode(const adc_dev * dev)
482506
{
483507
dev->regs->CR1 |= ADC_CR1_SCAN;
@@ -534,6 +558,7 @@ static inline void adc_start_convert(const adc_dev * dev)
534558
}
535559

536560

561+
537562
#ifdef __cplusplus
538563
} // extern "C"
539564
#endif

0 commit comments

Comments
 (0)