Skip to content

Commit a9f9fdd

Browse files
add masked enable/disable/wake/sleep code for RCC*ENR/RCC*SMENR to track masked enables; hook up GPIO sleep for EXTI; track enable/disable for DMA1/DMA2; add masked enable/disable to ADC1/ADC2/ADC3; update i2c/spi/qspi to properly enable/disable on start/stop
1 parent 15c85df commit a9f9fdd

File tree

13 files changed

+385
-219
lines changed

13 files changed

+385
-219
lines changed

system/libstm32l4_dragonfly/dosfs_sflash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static uint32_t dosfs_sflash_nor_identify(dosfs_sflash_t *sflash)
7373
qspi_pins.io3 = GPIO_PIN_PA6_QUADSPI_BK1_IO3;
7474

7575
stm32l4_qspi_create(&sflash->qspi, QSPI_INSTANCE_QUADSPI, &qspi_pins, 2, QSPI_MODE_DMA);
76-
stm32l4_qspi_enable(&sflash->qspi, 40000000, QSPI_OPTION_MODE_3 | QSPI_OPTION_RX_DMA | QSPI_OPTION_TX_DMA, NULL, NULL, 0);
76+
stm32l4_qspi_enable(&sflash->qspi, 40000000, QSPI_OPTION_MODE_3, NULL, NULL, 0);
7777

7878
stm32l4_qspi_select(&sflash->qspi);
7979
stm32l4_qspi_mode(&sflash->qspi, 0);

system/libstm32l4_dragonfly/stm32l4_adc.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747

4848

4949
typedef struct _stm32l4_adc_driver_t {
50-
stm32l4_adc_t *instances[ADC_INSTANCE_COUNT];
50+
stm32l4_adc_t *instances[ADC_INSTANCE_COUNT];
51+
volatile uint32_t adc;
5152
} stm32l4_adc_driver_t;
5253

5354
static stm32l4_adc_driver_t stm32l4_adc_driver;
@@ -141,14 +142,11 @@ bool stm32l4_adc_disable(stm32l4_adc_t *adc)
141142

142143
if (adc->instance == ADC_INSTANCE_ADC1)
143144
{
144-
armv7m_atomic_and(&ADC123_COMMON->CCR, ~(ADC_CCR_VBATEN | ADC_CCR_VREFEN));
145-
146-
if (!stm32l4_adc_driver.instances[ADC_INSTANCE_ADC2] && !stm32l4_adc_driver.instances[ADC_INSTANCE_ADC3])
147-
{
148-
stm32l4_system_periph_disable(SYSTEM_PERIPH_ADC);
149-
}
145+
armv7m_atomic_and(&ADC123_COMMON->CCR, ~(ADC_CCR_VBATEN | ADC_CCR_VREFEN));
150146
}
151147

148+
stm32l4_system_periph_cond_disable(SYSTEM_PERIPH_ADC, &stm32l4_adc_driver.adc, (1ul << adc->instance));
149+
152150
adc->events = 0;
153151
adc->callback = NULL;
154152
adc->context = NULL;
@@ -169,7 +167,7 @@ bool stm32l4_adc_configure(stm32l4_adc_t *adc, uint32_t option)
169167

170168
if (adc->state == ADC_STATE_BUSY)
171169
{
172-
stm32l4_system_periph_enable(SYSTEM_PERIPH_ADC);
170+
stm32l4_system_periph_cond_enable(SYSTEM_PERIPH_ADC, &stm32l4_adc_driver.adc, (1ul << adc->instance));
173171

174172
if ((stm32l4_system_hclk() <= 48000000) && (stm32l4_system_hclk() == stm32l4_system_sysclk()))
175173
{

system/libstm32l4_dragonfly/stm32l4_dma.c

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "stm32l4xx.h"
3232

3333
#include "stm32l4_dma.h"
34+
#include "stm32l4_system.h"
3435

3536
#include "armv7m.h"
3637

@@ -73,45 +74,28 @@ static const IRQn_Type stm32l4_dma_interrupt_table[16] = {
7374
};
7475

7576
typedef struct _stm32l4_dma_driver_t {
77+
stm32l4_dma_t *instances[16];
7678
volatile uint32_t mask;
7779
volatile uint32_t flash;
78-
stm32l4_dma_t *instances[16];
80+
volatile uint32_t dma1;
81+
volatile uint32_t dma2;
7982
} stm32l4_dma_driver_t;
8083

8184
static stm32l4_dma_driver_t stm32l4_dma_driver;
8285

83-
static void stm32l4_dma_track(uint32_t address)
86+
static inline void stm32l4_dma_track(uint32_t channel, uint32_t address)
8487
{
8588
if (address < 0x10000000)
8689
{
87-
armv7m_atomic_add(&stm32l4_dma_driver.flash, 1);
88-
89-
armv7m_atomic_or(&RCC->AHB1SMENR, RCC_AHB1SMENR_FLASHSMEN);
90+
stm32l4_system_periph_cond_wake(SYSTEM_PERIPH_FLASH, &stm32l4_dma_driver.flash, (1ul << channel));
9091
}
9192
}
9293

93-
static void stm32l4_dma_untrack(uint32_t address)
94+
static inline void stm32l4_dma_untrack(uint32_t channel, uint32_t address)
9495
{
95-
uint32_t o_flash, n_flash;
96-
9796
if (address < 0x10000000)
9897
{
99-
o_flash = stm32l4_dma_driver.flash;
100-
101-
do
102-
{
103-
n_flash = o_flash - 1;
104-
105-
if (n_flash == 0)
106-
{
107-
armv7m_atomic_and(&RCC->AHB1SMENR, ~RCC_AHB1SMENR_FLASHSMEN);
108-
}
109-
else
110-
{
111-
armv7m_atomic_or(&RCC->AHB1SMENR, RCC_AHB1SMENR_FLASHSMEN);
112-
}
113-
}
114-
while (!armv7m_atomic_compare_exchange(&stm32l4_dma_driver.flash, &o_flash, n_flash));
98+
stm32l4_system_periph_cond_sleep(SYSTEM_PERIPH_FLASH, &stm32l4_dma_driver.flash, (1ul << channel));
11599
}
116100
}
117101

@@ -192,12 +176,14 @@ void stm32l4_dma_enable(stm32l4_dma_t *dma, stm32l4_dma_callback_t callback, voi
192176

193177
if (!(dma->channel & 8))
194178
{
195-
armv7m_atomic_or(&RCC->AHB1ENR, RCC_AHB1ENR_DMA1EN);
179+
stm32l4_system_periph_cond_enable(SYSTEM_PERIPH_DMA1, &stm32l4_dma_driver.dma1, (1ul << (dma->channel & 7)));
180+
196181
armv7m_atomic_modify(&DMA1_CSELR->CSELR, (15 << shift), (dma->channel >> 4) << shift);
197182
}
198183
else
199184
{
200-
armv7m_atomic_or(&RCC->AHB1ENR, RCC_AHB1ENR_DMA2EN);
185+
stm32l4_system_periph_cond_enable(SYSTEM_PERIPH_DMA2, &stm32l4_dma_driver.dma2, (1ul << (dma->channel & 7)));
186+
201187
armv7m_atomic_modify(&DMA2_CSELR->CSELR, (15 << shift), (dma->channel >> 4) << shift);
202188
}
203189

@@ -215,7 +201,16 @@ void stm32l4_dma_disable(stm32l4_dma_t *dma)
215201

216202
NVIC_DisableIRQ(dma->interrupt);
217203

218-
stm32l4_dma_untrack(DMA->CMAR);
204+
stm32l4_dma_untrack(dma->channel, DMA->CMAR);
205+
206+
if (!(dma->channel & 8))
207+
{
208+
stm32l4_system_periph_cond_disable(SYSTEM_PERIPH_DMA1, &stm32l4_dma_driver.dma1, (1ul << (dma->channel & 7)));
209+
}
210+
else
211+
{
212+
stm32l4_system_periph_cond_disable(SYSTEM_PERIPH_DMA2, &stm32l4_dma_driver.dma2, (1ul << (dma->channel & 7)));
213+
}
219214
}
220215

221216
void stm32l4_dma_start(stm32l4_dma_t *dma, uint32_t tx_data, uint32_t rx_data, uint16_t xf_count, uint32_t option)
@@ -236,18 +231,18 @@ void stm32l4_dma_start(stm32l4_dma_t *dma, uint32_t tx_data, uint32_t rx_data, u
236231
DMA2->IFCR = (15 << shift);
237232
}
238233

239-
stm32l4_dma_untrack(DMA->CMAR);
234+
stm32l4_dma_untrack(dma->channel, DMA->CMAR);
240235

241236
if (option & DMA_OPTION_MEMORY_TO_PERIPHERAL)
242237
{
243-
stm32l4_dma_track(rx_data);
238+
stm32l4_dma_track(dma->channel, rx_data);
244239

245240
DMA->CMAR = rx_data;
246241
DMA->CPAR = tx_data;
247242
}
248243
else
249244
{
250-
stm32l4_dma_track(tx_data);
245+
stm32l4_dma_track(dma->channel, tx_data);
251246

252247
DMA->CMAR = tx_data;
253248
DMA->CPAR = rx_data;
@@ -265,7 +260,7 @@ uint16_t stm32l4_dma_stop(stm32l4_dma_t *dma)
265260

266261
DMA->CCR &= ~(DMA_CCR_EN | DMA_CCR_TCIE | DMA_CCR_HTIE | DMA_CCR_TEIE);
267262

268-
stm32l4_dma_untrack(DMA->CMAR);
263+
stm32l4_dma_untrack(dma->channel, DMA->CMAR);
269264

270265
DMA->CMAR = 0xffffffff;
271266

system/libstm32l4_dragonfly/stm32l4_exti.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "stm32l4_exti.h"
3434
#include "stm32l4_gpio.h"
35+
#include "stm32l4_system.h"
3536

3637
#include "armv7m.h"
3738

@@ -104,13 +105,20 @@ bool stm32l4_exti_enable(stm32l4_exti_t *exti)
104105

105106
bool stm32l4_exti_disable(stm32l4_exti_t *exti)
106107
{
108+
unsigned int group;
109+
107110
if (exti->state != EXTI_STATE_READY)
108111
{
109112
return false;
110113
}
111114

112115
armv7m_atomic_and(&EXTI->IMR1, ~0x0000ffff);
113116

117+
for (group = 0; group < 8; group++)
118+
{
119+
stm32l4_system_periph_cond_sleep((SYSTEM_PERIPH_GPIOA + group), &exti->gpio[group], ~0ul);
120+
}
121+
114122
NVIC_DisableIRQ(EXTI15_10_IRQn);
115123
NVIC_DisableIRQ(EXTI9_5_IRQn);
116124
NVIC_DisableIRQ(EXTI4_IRQn);
@@ -154,8 +162,7 @@ bool stm32l4_exti_resume(stm32l4_exti_t *exti, uint32_t mask)
154162

155163
bool stm32l4_exti_notify(stm32l4_exti_t *exti, uint16_t pin, uint32_t control, stm32l4_exti_callback_t callback, void *context)
156164
{
157-
unsigned int mask, index, group;
158-
uint32_t apb2enr;
165+
unsigned int mask, index, group, o_group;
159166

160167
if (exti->state != EXTI_STATE_READY)
161168
{
@@ -166,8 +173,16 @@ bool stm32l4_exti_notify(stm32l4_exti_t *exti, uint16_t pin, uint32_t control, s
166173
group = (pin & GPIO_PIN_GROUP_MASK) >> GPIO_PIN_GROUP_SHIFT;
167174

168175
mask = 1ul << index;
169-
176+
170177
armv7m_atomic_and(&EXTI->IMR1, ~mask);
178+
179+
if (exti->enables & mask)
180+
{
181+
o_group = (SYSCFG->EXTICR[index >> 2] >> ((index & 3) << 2)) & 15;
182+
183+
stm32l4_system_periph_cond_sleep((SYSTEM_PERIPH_GPIOA + o_group), &exti->gpio[o_group], (1ul << index));
184+
}
185+
171186
armv7m_atomic_and(&exti->enables, ~mask);
172187

173188
exti->channels[index].callback = callback;
@@ -193,26 +208,16 @@ bool stm32l4_exti_notify(stm32l4_exti_t *exti, uint16_t pin, uint32_t control, s
193208
armv7m_atomic_and(&EXTI->FTSR1, ~mask);
194209
}
195210

196-
apb2enr = RCC->APB2ENR;
197-
198-
if (!(apb2enr & RCC_APB2ENR_SYSCFGEN))
199-
{
200-
armv7m_atomic_or(&RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);
201-
}
202-
203211
armv7m_atomic_modify(&SYSCFG->EXTICR[index >> 2], (0x0000000f << ((index & 3) << 2)), (group << ((index & 3) << 2)));
204212

205-
if (!(apb2enr & RCC_APB2ENR_SYSCFGEN))
206-
{
207-
armv7m_atomic_and(&RCC->APB2ENR, ~RCC_APB2ENR_SYSCFGEN);
208-
}
209-
210213
armv7m_atomic_or(&exti->enables, mask);
211214

212215
if ((exti->enables & exti->mask) & mask)
213216
{
214217
armv7m_atomic_or(&EXTI->IMR1, mask);
215218
}
219+
220+
stm32l4_system_periph_cond_wake((SYSTEM_PERIPH_GPIOA + group), &exti->gpio[group], (1ul << index));
216221
}
217222

218223
return true;

system/libstm32l4_dragonfly/stm32l4_exti.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ typedef struct _stm32l4_exti_t {
5757
uint8_t priority;
5858
uint32_t enables;
5959
uint32_t mask;
60+
volatile uint32_t gpio[8];
6061
struct {
6162
stm32l4_exti_callback_t callback;
6263
void* context;

0 commit comments

Comments
 (0)