12
12
#include <stdint.h>
13
13
#include <string.h>
14
14
15
- #include <contiki.h>
16
15
#include STM32_HAL_H
17
16
18
17
#include <pbdrv/pwm.h>
19
18
#include <pbio/error.h>
19
+ #include <pbio/os.h>
20
20
#include <pbio/util.h>
21
21
22
22
#include "../core.h"
@@ -84,8 +84,8 @@ typedef struct {
84
84
DMA_HandleTypeDef hdma_rx ;
85
85
/** HAL Tx DMA data */
86
86
DMA_HandleTypeDef hdma_tx ;
87
- /** Protothread */
88
- struct pt pt ;
87
+ /** Process for this device */
88
+ pbio_os_process_t process ;
89
89
/** Pointer to generic PWM device instance */
90
90
pbdrv_pwm_dev_t * pwm ;
91
91
/** PWM values */
@@ -94,7 +94,6 @@ typedef struct {
94
94
bool changed ;
95
95
} pbdrv_pwm_lp50xx_stm32_priv_t ;
96
96
97
- PROCESS (pwm_lp50xx_stm32 , "pwm_lp50xx_stm32" );
98
97
static pbdrv_pwm_lp50xx_stm32_priv_t dev_priv [PBDRV_CONFIG_PWM_LP50XX_STM32_NUM_DEV ];
99
98
100
99
static pbio_error_t pbdrv_pwm_lp50xx_stm32_set_duty (pbdrv_pwm_dev_t * dev , uint32_t ch , uint32_t value ) {
@@ -107,7 +106,7 @@ static pbio_error_t pbdrv_pwm_lp50xx_stm32_set_duty(pbdrv_pwm_dev_t *dev, uint32
107
106
// (the data sheet says 12-bit PWM but the I2C registers are only 8-bit).
108
107
priv -> values [ch ] = value >> 8 ;
109
108
priv -> changed = true;
110
- process_poll ( & pwm_lp50xx_stm32 );
109
+ pbio_os_request_poll ( );
111
110
112
111
return PBIO_SUCCESS ;
113
112
}
@@ -116,6 +115,66 @@ static const pbdrv_pwm_driver_funcs_t pbdrv_pwm_lp50xx_stm32_funcs = {
116
115
.set_duty = pbdrv_pwm_lp50xx_stm32_set_duty ,
117
116
};
118
117
118
+ static pbio_error_t pbdrv_pwm_lp50xx_stm32_process_thread (pbio_os_state_t * state , void * context ) {
119
+
120
+ pbdrv_pwm_lp50xx_stm32_priv_t * priv = context ;
121
+
122
+ ASYNC_BEGIN (state );
123
+
124
+ // Need to allow all drivers to init first.
125
+ AWAIT_ONCE (state );
126
+
127
+ static const struct {
128
+ uint8_t reg ;
129
+ uint8_t values [11 ];
130
+ } __attribute__((packed )) init_data = {
131
+ .reg = DEVICE_CONFIG0 ,
132
+ .values = {
133
+ [DEVICE_CONFIG0 ] = DEVICE_CONFIG0_CHIP_EN ,
134
+ [DEVICE_CONFIG1 ] = DEVICE_CONFIG1_POWER_SAVE_EN | DEVICE_CONFIG1_PWM_DITHERING_EN | DEVICE_CONFIG1_AUTO_INCR_EN ,
135
+ [LED_CONFIG0 ] = 0 ,
136
+ [BANK_BRIGHTNESS ] = 0 ,
137
+ [BANK_A_COLOR ] = 0 ,
138
+ [BANK_B_COLOR ] = 0 ,
139
+ [BANK_C_COLOR ] = 0 ,
140
+ // Official LEGO firmware has LED0_BRIGHTNESS set to 255 and LED1_BRIGHTNESS
141
+ // set to 190 but then divides the incoming PWM duty cycle by 5. By doing
142
+ // the divide by 5 here, we end up with the same max brightness while
143
+ // allowing full dynamic range of the PWM duty cycle.
144
+ [LED0_BRIGHTNESS ] = 51 ,
145
+ [LED1_BRIGHTNESS ] = 38 ,
146
+ [LED2_BRIGHTNESS ] = 0 ,
147
+ [LED3_BRIGHTNESS ] = 0 ,
148
+ }
149
+ };
150
+
151
+ HAL_FMPI2C_Master_Transmit_DMA (& priv -> hfmpi2c , I2C_ADDR , (void * )& init_data , sizeof (init_data ));
152
+ AWAIT_UNTIL (state , HAL_FMPI2C_GetState (& priv -> hfmpi2c ) == HAL_FMPI2C_STATE_READY );
153
+
154
+ // initialization is finished so consumers can use this PWM device now.
155
+ priv -> pwm -> funcs = & pbdrv_pwm_lp50xx_stm32_funcs ;
156
+ pbdrv_init_busy_down ();
157
+
158
+ for (;;) {
159
+ AWAIT_UNTIL (state , priv -> changed );
160
+
161
+ static struct {
162
+ uint8_t reg ;
163
+ uint8_t values [LP50XX_NUM_CH ];
164
+ } __attribute__((packed )) color_data = {
165
+ .reg = OUT0_COLOR ,
166
+ };
167
+
168
+ memcpy (color_data .values , priv -> values , LP50XX_NUM_CH );
169
+ HAL_FMPI2C_Master_Transmit_DMA (& priv -> hfmpi2c , I2C_ADDR , (void * )& color_data , sizeof (color_data ));
170
+ priv -> changed = false;
171
+ AWAIT_UNTIL (state , HAL_FMPI2C_GetState (& priv -> hfmpi2c ) == HAL_FMPI2C_STATE_READY );
172
+ }
173
+
174
+ // Unreachable.
175
+ ASYNC_END (PBIO_ERROR_FAILED );
176
+ }
177
+
119
178
void pbdrv_pwm_lp50xx_stm32_init (pbdrv_pwm_dev_t * devs ) {
120
179
for (int i = 0 ; i < PBDRV_CONFIG_PWM_LP50XX_STM32_NUM_DEV ; i ++ ) {
121
180
const pbdrv_pwm_lp50xx_stm32_platform_data_t * pdata = & pbdrv_pwm_lp50xx_stm32_platform_data [i ];
@@ -186,68 +245,14 @@ void pbdrv_pwm_lp50xx_stm32_init(pbdrv_pwm_dev_t *devs) {
186
245
HAL_NVIC_SetPriority (pdata -> i2c_er_irq , 7 , 3 );
187
246
HAL_NVIC_EnableIRQ (pdata -> i2c_er_irq );
188
247
189
- PT_INIT (& priv -> pt );
190
248
priv -> pwm = pwm ;
191
249
pwm -> pdata = pdata ;
192
250
pwm -> priv = priv ;
251
+ pbio_os_process_start (& priv -> process , pbdrv_pwm_lp50xx_stm32_process_thread , priv );
252
+
193
253
// don't set funcs yet since we are not fully initialized
194
254
pbdrv_init_busy_up ();
195
255
}
196
-
197
- process_start (& pwm_lp50xx_stm32 );
198
- }
199
-
200
- static PT_THREAD (pbdrv_pwm_lp50xx_stm32_handle_event (pbdrv_pwm_lp50xx_stm32_priv_t * priv , process_event_t ev )) {
201
- PT_BEGIN (& priv -> pt );
202
-
203
- static const struct {
204
- uint8_t reg ;
205
- uint8_t values [11 ];
206
- } __attribute__((packed )) init_data = {
207
- .reg = DEVICE_CONFIG0 ,
208
- .values = {
209
- [DEVICE_CONFIG0 ] = DEVICE_CONFIG0_CHIP_EN ,
210
- [DEVICE_CONFIG1 ] = DEVICE_CONFIG1_POWER_SAVE_EN | DEVICE_CONFIG1_PWM_DITHERING_EN | DEVICE_CONFIG1_AUTO_INCR_EN ,
211
- [LED_CONFIG0 ] = 0 ,
212
- [BANK_BRIGHTNESS ] = 0 ,
213
- [BANK_A_COLOR ] = 0 ,
214
- [BANK_B_COLOR ] = 0 ,
215
- [BANK_C_COLOR ] = 0 ,
216
- // Official LEGO firmware has LED0_BRIGHTNESS set to 255 and LED1_BRIGHTNESS
217
- // set to 190 but then divides the incoming PWM duty cycle by 5. By doing
218
- // the divide by 5 here, we end up with the same max brightness while
219
- // allowing full dynamic range of the PWM duty cycle.
220
- [LED0_BRIGHTNESS ] = 51 ,
221
- [LED1_BRIGHTNESS ] = 38 ,
222
- [LED2_BRIGHTNESS ] = 0 ,
223
- [LED3_BRIGHTNESS ] = 0 ,
224
- }
225
- };
226
-
227
- HAL_FMPI2C_Master_Transmit_DMA (& priv -> hfmpi2c , I2C_ADDR , (void * )& init_data , sizeof (init_data ));
228
- PT_WAIT_UNTIL (& priv -> pt , HAL_FMPI2C_GetState (& priv -> hfmpi2c ) == HAL_FMPI2C_STATE_READY );
229
-
230
- // initialization is finished so consumers can use this PWM device now.
231
- priv -> pwm -> funcs = & pbdrv_pwm_lp50xx_stm32_funcs ;
232
- pbdrv_init_busy_down ();
233
-
234
- for (;;) {
235
- PT_WAIT_UNTIL (& priv -> pt , priv -> changed );
236
-
237
- static struct {
238
- uint8_t reg ;
239
- uint8_t values [LP50XX_NUM_CH ];
240
- } __attribute__((packed )) color_data = {
241
- .reg = OUT0_COLOR ,
242
- };
243
-
244
- memcpy (color_data .values , priv -> values , LP50XX_NUM_CH );
245
- HAL_FMPI2C_Master_Transmit_DMA (& priv -> hfmpi2c , I2C_ADDR , (void * )& color_data , sizeof (color_data ));
246
- priv -> changed = false;
247
- PT_WAIT_UNTIL (& priv -> pt , HAL_FMPI2C_GetState (& priv -> hfmpi2c ) == HAL_FMPI2C_STATE_READY );
248
- }
249
-
250
- PT_END (& priv -> pt );
251
256
}
252
257
253
258
/**
@@ -287,24 +292,7 @@ void pbdrv_pwm_lp50xx_stm32_i2c_er_irq(uint8_t index) {
287
292
}
288
293
289
294
void HAL_FMPI2C_MasterTxCpltCallback (FMPI2C_HandleTypeDef * hfmpi2c ) {
290
- process_poll (& pwm_lp50xx_stm32 );
291
- }
292
-
293
- PROCESS_THREAD (pwm_lp50xx_stm32 , ev , data ) {
294
- PROCESS_BEGIN ();
295
-
296
- // need to allow all drivers to init first
297
- PROCESS_PAUSE ();
298
-
299
- for (;;) {
300
- for (int i = 0 ; i < PBDRV_CONFIG_PWM_LP50XX_STM32_NUM_DEV ; i ++ ) {
301
- pbdrv_pwm_lp50xx_stm32_priv_t * priv = & dev_priv [i ];
302
- pbdrv_pwm_lp50xx_stm32_handle_event (priv , ev );
303
- }
304
- PROCESS_WAIT_EVENT ();
305
- }
306
-
307
- PROCESS_END ();
295
+ pbio_os_request_poll ();
308
296
}
309
297
310
298
#endif // PBDRV_CONFIG_PWM_LP50XX_STM32
0 commit comments