@@ -46,6 +46,47 @@ enum {
4646 ADC_SAMPLE_PERIOD = 10 ,
4747};
4848
49+ // Construct both SPI peripheral settings (data format, chip select)
50+ // and ADC chip settings (manual mode, 2xVref) in one go,
51+ // so that DMA can be used efficiently.
52+ //
53+ // NOTE: CSHOLD is *not* set here, so that CS is deasserted between each 16-bit unit
54+ #define MANUAL_ADC_CHANNEL (x ) \
55+ (SPI_SPIDAT1_DFSEL_FORMAT1 << SPI_SPIDAT1_DFSEL_SHIFT) | \
56+ (0 << (SPI_SPIDAT1_CSNR_SHIFT + PBDRV_EV3_SPI0_ADC_CS)) | \
57+ (1 << (SPI_SPIDAT1_CSNR_SHIFT + PBDRV_EV3_SPI0_FLASH_CS)) | \
58+ (1 << 12) | \
59+ (1 << 11) | \
60+ (((x) & 0xf) << 7) | \
61+ (1 << 6)
62+
63+ static const uint32_t channel_cmd [PBDRV_CONFIG_ADC_EV3_ADC_NUM_CHANNELS + PBDRV_CONFIG_ADC_EV3_NUM_DELAY_SAMPLES ] = {
64+ MANUAL_ADC_CHANNEL (0 ),
65+ MANUAL_ADC_CHANNEL (1 ),
66+ MANUAL_ADC_CHANNEL (2 ),
67+ MANUAL_ADC_CHANNEL (3 ),
68+ MANUAL_ADC_CHANNEL (4 ),
69+ MANUAL_ADC_CHANNEL (5 ),
70+ MANUAL_ADC_CHANNEL (6 ),
71+ MANUAL_ADC_CHANNEL (7 ),
72+ MANUAL_ADC_CHANNEL (8 ),
73+ MANUAL_ADC_CHANNEL (9 ),
74+ MANUAL_ADC_CHANNEL (10 ),
75+ MANUAL_ADC_CHANNEL (11 ),
76+ MANUAL_ADC_CHANNEL (12 ),
77+ MANUAL_ADC_CHANNEL (13 ),
78+ MANUAL_ADC_CHANNEL (14 ),
79+ MANUAL_ADC_CHANNEL (15 ),
80+ // We need two additional commands here because of how the ADC works.
81+ // In every given command frame, a new analog channel is selected in the ADC frontend multiplexer.
82+ // In frame n+1, that value actually gets converted to a digital value.
83+ // In frame n+2, the converted digital value is finally output, and we are able to receive it.
84+ // These requests are _pipelined_, so there is a latency of 2 frames, but we get a new sample on each frame.
85+ //
86+ // For more information, see figures 1 and 51 in the ADS7957 datasheet.
87+ MANUAL_ADC_CHANNEL (15 ),
88+ MANUAL_ADC_CHANNEL (15 ),
89+ };
4990static volatile uint16_t channel_data [PBDRV_CONFIG_ADC_EV3_ADC_NUM_CHANNELS + PBDRV_CONFIG_ADC_EV3_NUM_DELAY_SAMPLES ];
5091
5192static int adc_soon ;
@@ -85,8 +126,6 @@ static pbio_os_process_t pbdrv_adc_ev3_process;
85126pbio_error_t pbdrv_adc_ev3_process_thread (pbio_os_state_t * state , void * context ) {
86127 static pbio_os_timer_t timer ;
87128
88- (void )timer ;
89-
90129 PBIO_OS_ASYNC_BEGIN (state );
91130
92131 // HACK: This waits until storage is completely done with SPI flash before we start
@@ -95,7 +134,35 @@ pbio_error_t pbdrv_adc_ev3_process_thread(pbio_os_state_t *state, void *context)
95134 // Once SPI flash init is finished, there is nothing further for us to do.
96135 // We are ready to start sampling.
97136
98- // TODO: Actually start sampling
137+ pbio_os_timer_set (& timer , ADC_SAMPLE_PERIOD );
138+
139+ for (;;) {
140+ PBIO_OS_AWAIT_UNTIL (state , shut_down_hack || adc_soon || pbio_os_timer_is_expired (& timer ));
141+
142+ if (shut_down_hack ) {
143+ shut_down_hack_done = 1 ;
144+ break ;
145+ }
146+
147+ if (adc_soon ) {
148+ adc_soon = 0 ;
149+ pbio_os_timer_set (& timer , ADC_SAMPLE_PERIOD );
150+ } else {
151+ // TODO: There should probably be a pbio OS function for this
152+ timer .start += timer .duration ;
153+ }
154+
155+ // Do a sample of all channels
156+ pbdrv_block_device_ev3_spi_begin_for_adc (
157+ channel_cmd ,
158+ channel_data ,
159+ PBDRV_CONFIG_ADC_EV3_ADC_NUM_CHANNELS + PBDRV_CONFIG_ADC_EV3_NUM_DELAY_SAMPLES );
160+ PBIO_OS_AWAIT_WHILE (state , pbdrv_block_device_ev3_is_busy ());
161+
162+ for (uint32_t i = 0 ; i < pbdrv_adc_callback_count ; i ++ ) {
163+ pbdrv_adc_callbacks [i ]();
164+ }
165+ }
99166
100167 PBIO_OS_ASYNC_END (PBIO_SUCCESS );
101168}
0 commit comments