Skip to content

Commit bdfc559

Browse files
Clean up stm32l0_dma.c to have shorter critical sections
1 parent 207858b commit bdfc559

File tree

9 files changed

+219
-244
lines changed

9 files changed

+219
-244
lines changed

system/STM32L0xx/Include/stm32l0_dma.h

Lines changed: 175 additions & 174 deletions
Large diffs are not rendered by default.

system/STM32L0xx/Include/stm32l0_i2c.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ typedef struct _stm32l0_i2c_pins_t {
101101
typedef struct _stm32l0_i2c_params_t {
102102
uint8_t instance;
103103
uint8_t priority;
104-
uint8_t rx_dma;
105-
uint8_t tx_dma;
104+
uint16_t rx_dma;
105+
uint16_t tx_dma;
106106
stm32l0_i2c_pins_t pins;
107107
} stm32l0_i2c_params_t;
108108

@@ -125,8 +125,8 @@ typedef struct _stm32l0_i2c_t {
125125
uint8_t instance;
126126
uint8_t interrupt;
127127
uint8_t priority;
128-
uint8_t rx_dma;
129-
uint8_t tx_dma;
128+
uint16_t rx_dma;
129+
uint16_t tx_dma;
130130
stm32l0_i2c_pins_t pins;
131131
uint32_t option;
132132
uint32_t timeout;

system/STM32L0xx/Include/stm32l0_spi.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ typedef struct _stm32l0_spi_pins_t {
6969
typedef struct _stm32l0_spi_params_t {
7070
uint8_t instance;
7171
uint8_t priority;
72-
uint8_t rx_dma;
73-
uint8_t tx_dma;
72+
uint16_t rx_dma;
73+
uint16_t tx_dma;
7474
stm32l0_spi_pins_t pins;
7575
} stm32l0_spi_params_t;
7676

@@ -81,9 +81,9 @@ typedef struct _stm32l0_spi_t {
8181
volatile uint8_t state;
8282
uint8_t instance;
8383
uint8_t priority;
84-
uint8_t rx_dma;
85-
uint8_t tx_dma;
8684
uint8_t lock;
85+
uint16_t rx_dma;
86+
uint16_t tx_dma;
8787
stm32l0_spi_pins_t pins;
8888
stm32l0_spi_notify_callback_t callback;
8989
void *context;

system/STM32L0xx/Include/stm32l0_uart.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ typedef struct _stm32l0_uart_pins_t {
101101
typedef struct _stm32l0_uart_params_t {
102102
uint8_t instance;
103103
uint8_t priority;
104-
uint8_t rx_dma;
105-
uint8_t tx_dma;
104+
uint16_t rx_dma;
105+
uint16_t tx_dma;
106106
uint8_t *rx_fifo;
107107
uint16_t rx_entries;
108108
stm32l0_uart_pins_t pins;
@@ -114,8 +114,8 @@ typedef struct _stm32l0_uart_t {
114114
uint8_t instance;
115115
uint8_t interrupt;
116116
uint8_t priority;
117-
uint8_t rx_dma;
118-
uint8_t tx_dma;
117+
uint16_t rx_dma;
118+
uint16_t tx_dma;
119119
stm32l0_uart_pins_t pins;
120120
uint32_t baudrate;
121121
uint32_t option;

system/STM32L0xx/Lib/libstm32l052xx.a

144 Bytes
Binary file not shown.

system/STM32L0xx/Lib/libstm32l072xx.a

148 Bytes
Binary file not shown.

system/STM32L0xx/Lib/libstm32l082xx.a

144 Bytes
Binary file not shown.

system/STM32L0xx/Source/stm32l0_dma.c

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2019 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -30,6 +30,8 @@
3030
#include "stm32l0_dma.h"
3131
#include "stm32l0_system.h"
3232

33+
#define STM32L0_DMA_CHANNEL_LOCKED 0x8000
34+
3335
extern void DMA1_Channel1_IRQHandler(void);
3436
extern void DMA1_Channel2_3_IRQHandler(void);
3537
extern void DMA1_Channel4_5_6_7_IRQHandler(void);
@@ -45,7 +47,7 @@ static DMA_Channel_TypeDef * const stm32l0_dma_xlate_DMA[7] = {
4547
};
4648

4749
typedef struct _stm32l0_dma_t {
48-
uint8_t channel;
50+
volatile uint16_t channel;
4951
uint16_t size;
5052
stm32l0_dma_callback_t callback;
5153
void* context;
@@ -56,8 +58,7 @@ typedef struct _stm32l0_dma_device_t {
5658
uint8_t priority_1;
5759
uint8_t priority_2_3;
5860
uint8_t priority_4_5_6_7;
59-
volatile uint16_t dma;
60-
volatile uint16_t lock;
61+
volatile uint8_t dma;
6162
} stm32l0_dma_device_t;
6263

6364
static stm32l0_dma_device_t stm32l0_dma_device;
@@ -109,81 +110,48 @@ unsigned int stm32l0_dma_priority(unsigned int channel)
109110

110111
unsigned int stm32l0_dma_channel(unsigned int channel)
111112
{
112-
return ((stm32l0_dma_device.dma & (1ul << (channel & 7))) ? stm32l0_dma_device.channels[channel & 7].channel : STM32L0_DMA_CHANNEL_UNDEFINED);
113+
uint32_t index, mask;
114+
115+
index = channel & 7;
116+
mask = 1ul << index;
117+
118+
return ((stm32l0_dma_device.dma & mask) ? (stm32l0_dma_device.channels[index].channel & STM32L0_DMA_CHANNEL_MASK): STM32L0_DMA_CHANNEL_UNDEFINED);
113119
}
114120

115121
bool stm32l0_dma_lock(unsigned int channel)
116122
{
117123
stm32l0_dma_t *dma = &stm32l0_dma_device.channels[channel & 7];
118-
uint32_t primask, mask;
119-
120-
mask = 1ul << (channel & 7);
121-
122-
primask = __get_PRIMASK();
123-
124-
__disable_irq();
125-
126-
if (stm32l0_dma_device.lock & mask)
127-
{
128-
__set_PRIMASK(primask);
129124

130-
return false;
131-
}
132-
133-
dma->channel = channel;
134-
135-
stm32l0_dma_device.lock |= mask;
136-
137-
__set_PRIMASK(primask);
138-
139-
return true;
125+
return (armv6m_atomic_cash(&dma->channel, STM32L0_DMA_CHANNEL_NONE, channel) == STM32L0_DMA_CHANNEL_NONE);
140126
}
141127

142128
void stm32l0_dma_unlock(unsigned int channel)
143129
{
144-
uint32_t primask, mask;
145-
146-
mask = 1ul << (channel & 7);
147-
148-
primask = __get_PRIMASK();
149-
150-
__disable_irq();
151-
152-
stm32l0_dma_device.lock &= ~mask;
130+
stm32l0_dma_t *dma = &stm32l0_dma_device.channels[channel & 7];
153131

154-
__set_PRIMASK(primask);
132+
dma->channel = STM32L0_DMA_CHANNEL_NONE;
155133
}
156134

157135
bool stm32l0_dma_enable(unsigned int channel, stm32l0_dma_callback_t callback, void *context)
158136
{
159137
stm32l0_dma_t *dma = &stm32l0_dma_device.channels[channel & 7];
160138
unsigned int shift;
161-
uint32_t primask, mask;
139+
uint32_t primask, mask, o_channel;
140+
141+
o_channel = armv6m_atomic_cash(&dma->channel, STM32L0_DMA_CHANNEL_NONE, channel);
162142

143+
if ((o_channel != STM32L0_DMA_CHANNEL_NONE) && (o_channel != (STM32L0_DMA_CHANNEL_LOCKED | channel)))
144+
{
145+
return false;
146+
}
147+
163148
shift = (channel & 7) << 2;
164149
mask = 1ul << (channel & 7);
165150

166151
primask = __get_PRIMASK();
167152

168153
__disable_irq();
169154

170-
if (stm32l0_dma_device.dma & mask)
171-
{
172-
__set_PRIMASK(primask);
173-
174-
return false;
175-
}
176-
177-
if (stm32l0_dma_device.lock & mask)
178-
{
179-
if (dma->channel != channel)
180-
{
181-
__set_PRIMASK(primask);
182-
183-
return false;
184-
}
185-
}
186-
187155
if (!stm32l0_dma_device.dma)
188156
{
189157
RCC->AHBENR |= RCC_AHBENR_DMAEN;
@@ -192,10 +160,10 @@ bool stm32l0_dma_enable(unsigned int channel, stm32l0_dma_callback_t callback, v
192160

193161
stm32l0_dma_device.dma |= mask;
194162

195-
DMA1_CSELR->CSELR = (DMA1_CSELR->CSELR & ~(15 << shift)) | ((channel >> 4) << shift);
196-
197163
__set_PRIMASK(primask);
198164

165+
armv6m_atomic_modify(&DMA1_CSELR->CSELR, (15 << shift), ((channel >> 4) << shift));
166+
199167
dma->channel = channel;
200168
dma->callback = callback;
201169
dma->context = context;
@@ -205,6 +173,7 @@ bool stm32l0_dma_enable(unsigned int channel, stm32l0_dma_callback_t callback, v
205173

206174
void stm32l0_dma_disable(unsigned int channel)
207175
{
176+
stm32l0_dma_t *dma = &stm32l0_dma_device.channels[channel & 7];
208177
uint32_t primask, mask;
209178

210179
mask = 1ul << (channel & 7);
@@ -222,6 +191,11 @@ void stm32l0_dma_disable(unsigned int channel)
222191
}
223192

224193
__set_PRIMASK(primask);
194+
195+
if (!(dma->channel & STM32L0_DMA_CHANNEL_LOCKED))
196+
{
197+
dma->channel = STM32L0_DMA_CHANNEL_NONE;
198+
}
225199
}
226200

227201
void stm32l0_dma_start(unsigned int channel, uint32_t tx_data, uint32_t rx_data, uint16_t xf_count, uint32_t option)

system/STM32L0xx/Source/stm32l0_i2c.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static void stm32l0_i2c_master_transmit(stm32l0_i2c_t *i2c)
339339
{
340340
I2C_TypeDef *I2C = i2c->I2C;
341341
uint32_t i2c_cr2, count;
342-
uint8_t tx_dma;
342+
uint16_t tx_dma;
343343

344344
i2c->state = STM32L0_I2C_STATE_MASTER_TRANSMIT;
345345

@@ -408,7 +408,7 @@ static void stm32l0_i2c_master_receive(stm32l0_i2c_t *i2c)
408408
{
409409
I2C_TypeDef *I2C = i2c->I2C;
410410
uint32_t i2c_cr2, count;
411-
uint8_t rx_dma;
411+
uint16_t rx_dma;
412412

413413
i2c->state = STM32L0_I2C_STATE_MASTER_RECEIVE;
414414

0 commit comments

Comments
 (0)