55
66#if PBDRV_CONFIG_ADC_EV3
77
8+ #if !PBDRV_CONFIG_BLOCK_DEVICE_EV3
9+ #error "EV3 block device driver must be enabled"
10+ #endif
11+
812#include <stdbool.h>
913#include <stdint.h>
1014#include <string.h>
@@ -91,9 +95,6 @@ static const uint32_t channel_cmd[PBDRV_CONFIG_ADC_EV3_ADC_NUM_CHANNELS + PBDRV_
9195static volatile uint16_t channel_data [PBDRV_CONFIG_ADC_EV3_ADC_NUM_CHANNELS + PBDRV_ADC_EV3_NUM_DELAY_SAMPLES ];
9296
9397static int adc_soon ;
94- // Used to block ADC from interfering with flash upon shutdown
95- static int shut_down_hack = 0 ;
96- static int shut_down_hack_done = 0 ;
9798
9899static pbdrv_adc_callback_t pbdrv_adc_callbacks [1 ];
99100static uint32_t pbdrv_adc_callback_count = 0 ;
@@ -124,24 +125,30 @@ pbio_error_t pbdrv_adc_get_ch(uint8_t ch, uint16_t *value) {
124125
125126static pbio_os_process_t pbdrv_adc_ev3_process ;
126127
128+ /**
129+ * Request ADC process to exit and await until it does.
130+ */
131+ pbio_error_t pbdrv_adc_ev3_exit (pbio_os_state_t * state ) {
132+ PBIO_OS_ASYNC_BEGIN (state );
133+
134+ pbio_os_process_make_request (& pbdrv_adc_ev3_process , PBIO_OS_PROCESS_REQUEST_TYPE_CANCEL );
135+ PBIO_OS_AWAIT_UNTIL (state , pbdrv_adc_ev3_process .err == PBIO_SUCCESS );
136+
137+ PBIO_OS_ASYNC_END (PBIO_SUCCESS );
138+ }
139+
127140pbio_error_t pbdrv_adc_ev3_process_thread (pbio_os_state_t * state , void * context ) {
128141 static pbio_os_timer_t timer ;
129142
130143 PBIO_OS_ASYNC_BEGIN (state );
131144
132- // HACK: This waits until storage is completely done with SPI flash before we start
133- PBIO_OS_AWAIT_UNTIL (state , pbsys_storage_settings_get_settings ());
134-
135- // Once SPI flash init is finished, there is nothing further for us to do.
136- // We are ready to start sampling.
137-
138145 pbio_os_timer_set (& timer , ADC_SAMPLE_PERIOD );
139146
140147 for (;;) {
141- PBIO_OS_AWAIT_UNTIL (state , shut_down_hack || adc_soon || pbio_os_timer_is_expired (& timer ));
148+ PBIO_OS_AWAIT_UNTIL (state , pbdrv_adc_ev3_process . request || adc_soon || pbio_os_timer_is_expired (& timer ));
142149
143- if ( shut_down_hack ) {
144- shut_down_hack_done = 1 ;
150+ // Here we can exit gracefully since no SPI operation is in progress.
151+ if ( pbdrv_adc_ev3_process . request & PBIO_OS_PROCESS_REQUEST_TYPE_CANCEL ) {
145152 break ;
146153 }
147154
@@ -165,22 +172,26 @@ pbio_error_t pbdrv_adc_ev3_process_thread(pbio_os_state_t *state, void *context)
165172 }
166173 }
167174
168- PBIO_OS_ASYNC_END (PBIO_SUCCESS );
169- }
170-
171- void pbdrv_adc_init (void ) {
172- // Immediately go into async mode so that we can wait for the SPI flash driver.
173- // We *don't* want to block the initial init phase, or else things will deadlock.
175+ // Processes may be waiting on us to complete, so kick when done.
176+ pbio_os_request_poll ();
174177
175- pbio_os_process_start ( & pbdrv_adc_ev3_process , pbdrv_adc_ev3_process_thread , NULL );
178+ PBIO_OS_ASYNC_END ( PBIO_SUCCESS );
176179}
177180
178181void pbdrv_adc_update_soon (void ) {
179182 adc_soon = 1 ;
180183 pbio_os_request_poll ();
181184}
182185
183- void pbdrv_adc_ev3_configure_data_format () {
186+ // Public init is not used.
187+ void pbdrv_adc_init (void ) {
188+ }
189+
190+ // Init starts here instead. Called by SPI flash driver when it is done initializing.
191+ void pbdrv_adc_ev3_init (void ) {
192+
193+ // Most of the SPI initialization is already done by the SPI flash driver.
194+
184195 SPIClkConfigure (SOC_SPI_0_REGS , SOC_SYSCLK_2_FREQ , SPI_CLK_SPEED_ADC , SPI_DATA_FORMAT1 );
185196 // NOTE: Cannot be CPOL=1 CPHA=1 like SPI flash
186197 // The ADC seems to use the last falling edge to trigger conversions (see Figure 1 in the datasheet).
@@ -193,14 +204,9 @@ void pbdrv_adc_ev3_configure_data_format() {
193204 // as well as the CS-assert-to-clock-start and clock-end-to-CS-deassert delays
194205 // (which are global and set in block_device_ev3.c).
195206 SPIWdelaySet (SOC_SPI_0_REGS , 0x3f << SPI_SPIFMT_WDELAY_SHIFT , SPI_DATA_FORMAT1 );
196- }
197207
198- void pbdrv_adc_ev3_shut_down_hack () {
199- shut_down_hack = 1 ;
200- pbio_os_request_poll ();
201- }
202- int pbdrv_adc_ev3_is_shut_down_hack () {
203- return shut_down_hack_done ;
208+ // Begin polling.
209+ pbio_os_process_start (& pbdrv_adc_ev3_process , pbdrv_adc_ev3_process_thread , NULL );
204210}
205211
206212#endif // PBDRV_CONFIG_ADC_EV3
0 commit comments