Skip to content

Commit

Permalink
enabled really bad voltage clamp at ADC value of 300... seems to be w…
Browse files Browse the repository at this point in the history
…orking but ideally I would test it with GDB or something

pressing ENTER in num_pulses now pulses, if checkbox is enabled. Saving screenshots immediately after pulsing has updated the waveform, but it is a bit slow for the screenshot tool to actually run (watch for the visual pop up quickly coming and going, alerting you the screenshot has been saved)
  • Loading branch information
nmz787 committed Aug 30, 2018
1 parent 424a931 commit 54f25f6
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 43 deletions.
37 changes: 31 additions & 6 deletions FOR_ADC_DMA__1_9_3__CUSTOM__adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in) {

uint nelems = bufinfo.len / typesize;
//HAL_ADC_Start_DMA(&self->handle, (uint32_t *)bufinfo.buf + (typesize*self->adc_i), 1);
// nelems ends up programmed into DMA_SxNDTR
HAL_ADC_Start_DMA(&self->handle, bufinfo.buf, nelems);

// for (uint index = 0; index < nelems; index++) {
Expand Down Expand Up @@ -527,13 +528,29 @@ STATIC uint32_t ensure_input_is_int(mp_obj_t input){
}
}

STATIC mp_obj_t adc_read_timed_stop(mp_obj_t self_in, mp_obj_t first, mp_obj_t second) {
STATIC mp_obj_t adc_read_timed_stop(mp_uint_t n_args, const mp_obj_t *args) {
//(mp_obj_t self_in, mp_obj_t first, mp_obj_t second, mp_obj_t third, mp_obj_t buf_in) {
mp_obj_t self_in = args[0];
mp_obj_t first = args[1];
mp_obj_t second = args[2];
mp_obj_t third = args[3];
mp_obj_t buf_in = args[4];
(void)n_args; // unused, we know it's 4
uint32_t npulse_will_overflow = ensure_input_is_int(first);
uint32_t or_in_end = ensure_input_is_int(second);
uint16_t buf_len = ensure_input_is_int(third);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
pyb_obj_adc_t *self = self_in;
uint value = 0;
uint16_t num_left;
uint16_t index;

uint16_t tim2_pwm_defaults = TIM2->CCMR2;
tim2_pwm_defaults &= 36751; // 0b1000111110001111 # OC2M "000"....OC1M "000" AND
uint16_t tim5_pwm_defaults = TIM5->CCMR1;
tim2_pwm_defaults &= 36751; // 0b1000111110001111 # OC4M "000"....OC3M "000" AND
tim5_pwm_defaults &= 36751; // 0b1000111110001111 # OC2M "000"....OC1M "000" AND


if (npulse_will_overflow) {
TIM1->RCR = or_in_end;
Expand All @@ -548,13 +565,21 @@ STATIC mp_obj_t adc_read_timed_stop(mp_obj_t self_in, mp_obj_t first, mp_obj_t s
while(((TIM2->SR & TIM_FLAG_UPDATE)==TIM_FLAG_UPDATE)==RESET){
}
//__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
num_left = DMA2_Stream0->NDTR;
TIM2->SR = ~TIM_FLAG_UPDATE;
value = ADCx->DR;
index = buf_len-num_left;
if (index%2==1)
index-=1;
//ADCx->DR didn't work
value = ((uint16_t *)bufinfo.buf)[index];

if (value>300){
TIM2->CCMR1 = tim2_pwm_defaults | 16448; // 0b0100000001000000 # OC2M "100"....OC1M "100" OR
TIM2->CCMR2 = tim2_pwm_defaults | 16448; // 0b0100000001000000 # OC4M "100"....OC3M "100" OR
TIM5->CCMR1 = tim5_pwm_defaults | 16448; // 0b0100000001000000 # OC2M "100"....OC1M "100" OR
}
else if (value<285){
TIM2->CCMR1 = tim2_pwm_defaults | 28784; // 0b0111000001110000 # OC3M "111" OR
TIM2->CCMR2 = tim2_pwm_defaults | 28784; // 0b0111000001110000 # OC3M "111" OR
TIM5->CCMR1 = tim5_pwm_defaults | 28784; // 0b0111000001110000 # OC2M "111" OR
}

}
Expand All @@ -568,7 +593,7 @@ STATIC mp_obj_t adc_read_timed_stop(mp_obj_t self_in, mp_obj_t first, mp_obj_t s
HAL_ADC_Stop_DMA(&self->handle);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_stop_obj, adc_read_timed_stop);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(adc_read_timed_stop_obj, 5, adc_read_timed_stop);

STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&adc_read_obj) },
Expand Down
85 changes: 55 additions & 30 deletions FOR_ADC_DMA__adc.c.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index 9a0dc56..bd75109 100644
index 9a0dc56..704b13c 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -31,6 +31,7 @@
Expand Down Expand Up @@ -206,7 +206,7 @@ index 9a0dc56..bd75109 100644
adc_init_single(o);

return o;
@@ -363,84 +430,150 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
@@ -363,84 +430,175 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
/// print(val) # print the value out
///
/// This function does not allocate any memory.
Expand Down Expand Up @@ -268,6 +268,7 @@ index 9a0dc56..bd75109 100644
- }
- __HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
+ //HAL_ADC_Start_DMA(&self->handle, (uint32_t *)bufinfo.buf + (typesize*self->adc_i), 1);
+ // nelems ends up programmed into DMA_SxNDTR
+ HAL_ADC_Start_DMA(&self->handle, bufinfo.buf, nelems);
+
+// for (uint index = 0; index < nelems; index++) {
Expand Down Expand Up @@ -344,62 +345,86 @@ index 9a0dc56..bd75109 100644

- // read value
- uint value = ADCx->DR;
+STATIC mp_obj_t adc_read_timed_stop(mp_obj_t self_in, mp_obj_t first, mp_obj_t second) {
+STATIC mp_obj_t adc_read_timed_stop(mp_uint_t n_args, const mp_obj_t *args) {
+//(mp_obj_t self_in, mp_obj_t first, mp_obj_t second, mp_obj_t third, mp_obj_t buf_in) {
+ mp_obj_t self_in = args[0];
+ mp_obj_t first = args[1];
+ mp_obj_t second = args[2];
+ mp_obj_t third = args[3];
+ mp_obj_t buf_in = args[4];
+ (void)n_args; // unused, we know it's 4
+ uint32_t npulse_will_overflow = ensure_input_is_int(first);
+ uint32_t or_in_end = ensure_input_is_int(second);
+ uint16_t buf_len = ensure_input_is_int(third);
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE);
+ pyb_obj_adc_t *self = self_in;
+ uint value = 0;
+ uint16_t num_left;
+ uint16_t index;
+
+ uint16_t tim2_pwm_defaults = TIM2->CCMR2;
+ tim2_pwm_defaults &= 36751; // 0b1000111110001111 # OC2M "000"....OC1M "000" AND

- // store value in buffer
- if (typesize == 1) {
- value >>= 4;
- }
- mp_binary_set_val_array_from_int(bufinfo.typecode, bufinfo.buf, index, value);
+ uint16_t tim5_pwm_defaults = TIM5->CCMR1;
+ tim2_pwm_defaults &= 36751; // 0b1000111110001111 # OC4M "000"....OC3M "000" AND
+ tim5_pwm_defaults &= 36751; // 0b1000111110001111 # OC2M "000"....OC1M "000" AND
+
+
+ if (npulse_will_overflow) {
+ TIM1->RCR = or_in_end;
}
+ }
+ TIM3->CR1 |= 1;
+ // wait for DMA to complete: could use ISR/callback
+ // could do some control looping here!

- // turn the ADC off
- HAL_ADC_Stop(&self->handle);
- // store value in buffer
- if (typesize == 1) {
- value >>= 4;
+ while(TIM2->CR1 & TIM_CR1_CEN){
+ // Wait for the timer to trigger so we sample at the correct frequency
+ //while (__HAL_TIM_GET_FLAG(tim, TIM_FLAG_UPDATE) == RESET) {
+ while(((TIM2->SR & TIM_FLAG_UPDATE)==TIM_FLAG_UPDATE)==RESET){
+ }
}
- mp_binary_set_val_array_from_int(bufinfo.typecode, bufinfo.buf, index, value);
+ //__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
+ num_left = DMA2_Stream0->NDTR;
+ TIM2->SR = ~TIM_FLAG_UPDATE;
+ value = ADCx->DR;
+ index = buf_len-num_left;
+ if (index%2==1)
+ index-=1;
+ //ADCx->DR didn't work
+ value = ((uint16_t *)bufinfo.buf)[index];
+
+ if (value>300){
+ TIM2->CCMR1 = tim2_pwm_defaults | 16448; // 0b0100000001000000 # OC2M "100"....OC1M "100" OR
+ TIM2->CCMR2 = tim2_pwm_defaults | 16448; // 0b0100000001000000 # OC4M "100"....OC3M "100" OR
+ TIM5->CCMR1 = tim5_pwm_defaults | 16448; // 0b0100000001000000 # OC2M "100"....OC1M "100" OR
+ }
+ else if (value<285){
+ TIM2->CCMR1 = tim2_pwm_defaults | 28784; // 0b0111000001110000 # OC3M "111" OR
+ TIM2->CCMR2 = tim2_pwm_defaults | 28784; // 0b0111000001110000 # OC3M "111" OR
+ TIM5->CCMR1 = tim5_pwm_defaults | 28784; // 0b0111000001110000 # OC2M "111" OR
+ }
+
}

- // turn the ADC off
- HAL_ADC_Stop(&self->handle);
+ while (self->DMA_Handle.Instance->CR & DMA_SxCR_EN) // spin stream 0
+ {
+ //force_inactive_tim5() # disables 'push' (first pulse in pair)
+ //force_inactive_tim2() #disables 'pull' (second pulse in pair)

- #if defined(TIM6)
- if (mp_obj_is_integer(freq_in)) {
- // stop timer if we initialised TIM6 in this function (legacy behaviour)
- HAL_TIM_Base_Stop(tim);
}
- #endif
-
- return mp_obj_new_int(bufinfo.len);
+ while (self->DMA_Handle.Instance->CR & DMA_SxCR_EN) // spin stream 0
+ {
+ //force_inactive_tim5() # disables 'push' (first pulse in pair)
+ //force_inactive_tim2() #disables 'pull' (second pulse in pair)
+
+ }
+ HAL_ADC_Stop_DMA(&self->handle);
+ return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_obj, adc_read_timed);
+STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_stop_obj, adc_read_timed_stop);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(adc_read_timed_stop_obj, 5, adc_read_timed_stop);

STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&adc_read_obj) },
Expand All @@ -408,15 +433,15 @@ index 9a0dc56..bd75109 100644
};

STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
@@ -459,6 +592,7 @@ const mp_obj_type_t pyb_adc_type = {
@@ -459,6 +617,7 @@ const mp_obj_type_t pyb_adc_type = {
typedef struct _pyb_adc_all_obj_t {
mp_obj_base_t base;
ADC_HandleTypeDef handle;
+ DMA_HandleTypeDef DMA_Handle;
} pyb_adc_all_obj_t;

void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_mask) {
@@ -495,21 +629,21 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
@@ -495,21 +654,21 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
ADC_HandleTypeDef *adcHandle = &adc_all->handle;
adcHandle->Instance = ADCx;
adcHandle->Init.Resolution = resolution;
Expand All @@ -443,7 +468,7 @@ index 9a0dc56..bd75109 100644
adcHandle->Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;
adcHandle->Init.LowPowerAutoWait = DISABLE;
adcHandle->Init.Overrun = ADC_OVR_DATA_PRESERVED;
@@ -519,6 +653,31 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
@@ -519,6 +678,31 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
#endif

HAL_ADC_Init(adcHandle);
Expand Down Expand Up @@ -475,7 +500,7 @@ index 9a0dc56..bd75109 100644
}

uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32_t channel) {
@@ -537,62 +696,6 @@ int adc_get_resolution(ADC_HandleTypeDef *adcHandle) {
@@ -537,62 +721,6 @@ int adc_get_resolution(ADC_HandleTypeDef *adcHandle) {
return 12;
}

Expand Down Expand Up @@ -538,7 +563,7 @@ index 9a0dc56..bd75109 100644

/******************************************************************************/
/* MicroPython bindings : adc_all object */
@@ -622,49 +725,9 @@ STATIC mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) {
@@ -622,49 +750,9 @@ STATIC mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(adc_all_read_channel_obj, adc_all_read_channel);

Expand Down
14 changes: 7 additions & 7 deletions code_PYFLEX_F401/pulser_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
# PYFLEX_F401 pin LED_YELLOW,PB9 ==> pyflex_f401.sch LED_YELLOW,PB9
YEL_LED = Pin('LED_YELLOW', Pin.OUT)
# EN_18V_ONBOARD is active HI, (drives base of Q32), U3_!SHDN is inverted EN_18V_ONBOARD.
EN_18V_ONBOARD = Pin('PB14', Pin.OUT)
EN_18V_ONBOARD = Pin('PB14', Pin.OUT)
EN_18V_ONBOARD.value(1)
EN_18V_U4 = Pin('PB13', Pin.OUT)


Expand All @@ -70,8 +71,8 @@
adc = pyb.ADC(pyb.Pin.board.JA2, pyb.Pin.board.JA17) #current is PA5 aka JA17
adc_vals = array.array('H',[0 for i in range(2048)])
stm.mem32[stm.ADC1 + stm.ADC_CR2] |= 1 #enable ADC
adc.read_timed(adc_vals)
adc.read_timed_stop(0,0)
# adc.read_timed(adc_vals)
# adc.read_timed_stop(0,0, len(adc_vals), adc_vals)


def reset_vals():
Expand Down Expand Up @@ -220,7 +221,6 @@ def end_of_n_pulse_train__longer(self, t):
tim2_3_out = pyb.Pin(pyb.Pin.cpu.A2, pyb.Pin.AF_PP, pyb.Pin.PULL_NONE, 1) # PA2 set to AF1 --> TIM2_CH3
tim5_2_out = pyb.Pin(pyb.Pin.cpu.A1, pyb.Pin.AF_PP, pyb.Pin.PULL_NONE, 2) # PA1 set to AF2 --> TIM5_CH2

# enable_pb13_af_and_connect_to_tim1() 2018-7-16-jg

# as long as both TIM's tick at AHB freq, the TIM's will tick at the same rate;
# should there be any APB divider impacting TIM input clock freq,
Expand Down Expand Up @@ -378,7 +378,7 @@ def pulse():
# stm.mem16[tim_kickoff + stm.TIM_CR1] |= 1
npulse_will_overflow = int(rep_counter_overflow_detector==1)
# assumes tim_kickoff is TIM3 for now
adc.read_timed_stop(npulse_will_overflow, rep_counter_overflow_detector.or_in_end)
adc.read_timed_stop(npulse_will_overflow, rep_counter_overflow_detector.or_in_end, len(adc_vals), adc_vals)
print('done')

def timers_init():
Expand All @@ -405,7 +405,7 @@ def timers_init():

# make sure PA0 PA1, PA2 are output LO state
#timers_init()
pyb.delay(500)
#pyb.delay(500)

#YEL_LED.value(1)
#EN_18V_ONBOARD.value(1)
Expand All @@ -415,7 +415,7 @@ def timers_init():
force_inactive_tim2()
force_inactive_tim5()
#YEL_LED.value(0)
EN_18V_ONBOARD.value(1)
EN_18V_ONBOARD.value(0)
#EN_18V_U4.value(1)
#pyb.delay(2000)

Expand Down
29 changes: 29 additions & 0 deletions tk_adc_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,23 @@
# adapted from https://arduino.stackexchange.com/a/17529


# TODO
# checkout grabbing oscilloscope data after each pulse, and performing some basic checks like the number of requested pulse-pairs versus the actual emitted:
#
#>>> import ds1054z.discovery
#>>> from ds1054z import DS1054Z
#>>> scope = DS1054Z(ds1054z.discovery.discover_devices()[0]['ip'])
#>>> scope.get_waveform_samples(1) # grabs channel 1's on-screen buffer... use second arg "RAW"




from __future__ import print_function, division, absolute_import
import random
import pexpect
import time
import sys
import os
import re
if sys.hexversion > 0x02ffffff:
import tkinter as tk
Expand All @@ -18,6 +30,7 @@
class App(tk.Frame):
np_default = 'Num Pulses: {}'
integral_default = 'Integral: {}'
take_screenshots = False
def __init__(self, parent, title, serial_port):
tk.Frame.__init__(self, parent)
self.serial_port = serial_port
Expand Down Expand Up @@ -67,9 +80,17 @@ def __init__(self, parent, title, serial_port):

tk.Label(self, text="Num Pulse Pairs").grid(row=3, column=4)
self.n_pulses = tk.Entry(self)
self.n_pulses.bind('<Return>', self.num_pulses_pressed)
self.n_pulses.grid(row=3, column=5)
self.n_pulses.insert(0,'2')

self.pressing_num_pulses_starts_pulse = tk.IntVar()
self.num_pulses_checkbox = tk.Checkbutton(self, text="", variable=self.pressing_num_pulses_starts_pulse)
self.num_pulses_checkbox.grid(row=3, column=6)

def num_pulses_pressed(self, event):
if self.pressing_num_pulses_starts_pulse.get():
self.read_serial()

def fake(self):
#d = [0, 0, 0, 0, 0, 0, 0, 54.0, 77.0, 135.0, 167.0, 184.0, 235.0, 248.0, 361.0, 246.0, 312.0, 288.0, 292.0, 269.0, 265.0, 295.0, 304.0, 284.0, 277.0, 269.0, 307.0, 306.0, 236.0, 277.0, 269.0, 307.0, 292.0, 280.0, 270.0, 310.0, 307.0, 285.0, 276.0, 270.0, 309.0, 252.0, 280.0, 272.0, 314.0, 306.0, 310.0, 254.0, 176.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0]
Expand Down Expand Up @@ -142,10 +163,12 @@ def read_serial(self):
else:
self.append_value2(s)
flip=1
self.take_screenshots = True
self.after_idle(self.replot)
non_zeroes = [i for i in new_list if i>0]
self.integral.set(self.integral_default.format(sum(non_zeroes)))


def append_value(self, x):
"""
Update the cached data lists with new sensor values.
Expand Down Expand Up @@ -190,6 +213,12 @@ def replot(self):
coordsXX.append(h - ((h * (self.Line2[n]+100)) / max_all))
self.canvas2.coords('X', *coordsXX)

self.after(100, self.screenshot)

def screenshot(self):
if self.take_screenshots:
#os.system('xfce4-screenshooter -s ./pics -f')
os.system('shutter -a -e -n -o {}/Screenshot_%y-%m-%d_%T.png'.format(os.path.abspath('./pics')))

def main(args = None):
if args is None:
Expand Down

0 comments on commit 54f25f6

Please sign in to comment.