|ADC READ | ADC WAIT |ADC READ | ADC WAIT |
|[0] |[0] | -> [r0]
| [1] | [1] | -> [r1]
| [2] | [2] | -> [r2]
|<-------- 1/f_s ------>|
Configure 3 DMA channels (one "ADC READ
" in the above diagram):
Trigger ADC READ
periodically.
Advantages:
Disadvantages:
Advantages:
Disadvantages:
In [4]:
from IPython.display import display
from datetime import datetime
import numpy as np
import pandas as pd
import arduino_helpers.hardware.teensy as teensy
from arduino_helpers.hardware.teensy.adc import ADC_DESCRIPTIONS
from arduino_helpers.hardware.teensy.dma import (TCD_DESCRIPTIONS,
REGISTERS_DESCRIPTIONS
as DMA_REG_DESCRIPTIONS,
DCHPRI_DESCRIPTIONS)
from arduino_helpers.hardware.teensy.pit import (TIMER_CONFIG_DESCRIPTIONS,
REGISTERS_DESCRIPTIONS
as PIT_REG_DESCRIPTIONS)
import arduino_helpers.hardware.arduino as arduino
from arduino_rpc.protobuf import resolve_field_values
from teensy_minimal_rpc import SerialProxy
import teensy_minimal_rpc.ADC as adc
import teensy_minimal_rpc.DMA as dma
import teensy_minimal_rpc.SIM as sim
import teensy_minimal_rpc.PIT as pit
def init_dma(proxy):
# SIM_SCGC7 |= SIM_SCGC7_DMA;
# SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
proxy.update_sim_SCGC6(sim.R_SCGC6(DMAMUX=True))
proxy.update_sim_SCGC7(sim.R_SCGC7(DMA=True))
for i in xrange(proxy.dma_channel_count()):
# TCD = (TCD_t *)(0x40009000 + ch * 32);
# uint32_t *p = (uint32_t *)TCD;
# *p++ = 0;
# *p++ = 0;
# *p++ = 0;
# *p++ = 0;
# *p++ = 0;
# *p++ = 0;
# *p++ = 0;
# *p++ = 0;
proxy.reset_dma_TCD(i)
In [67]:
try:
del proxy
except NameError:
pass
proxy = SerialProxy(baudrate=512000)
proxy.pin_mode(13, 1)
proxy.digital_write(13, 1)
init_dma(proxy)
# proxy.enableDMA(teensy.ADC_0)
# proxy.enableInterrupts(teensy.ADC_0)
# proxy.dma_start(256)
# Set ADC parameters
# proxy.setAveraging(4, teensy.ADC_0)
# proxy.setResolution(10, teensy.ADC_0)
# proxy.setConversionSpeed(teensy.ADC_VERY_HIGH_SPEED, teensy.ADC_0)
# proxy.setSamplingSpeed(teensy.ADC_VERY_HIGH_SPEED, teensy.ADC_0)
In [68]:
N = 512
proxy.free_all()
src_addr = proxy.mem_alloc(N)
dst_addr = proxy.mem_alloc(N)
proxy.mem_cpy_host_to_device(src_addr, np.arange(1, 17, dtype='uint8'))
proxy.mem_fill_uint32(dst_addr, 0, N / 4)
[hex(addr)[:-1] for addr in (src_addr, dst_addr)]
Out[68]:
In [77]:
XFER_REQUEST = dma.TCD(CSR=dma.R_TCD_CSR(START=1),
NBYTES_MLNO=8,
SADDR=int(src_addr + 15),
DADDR=int(dst_addr),
SOFF=-1,
DOFF=4,
ATTR=dma.R_TCD_ATTR(SSIZE=dma.R_TCD_ATTR._8_BIT,
DSIZE=dma.R_TCD_ATTR._32_BIT),
SLAST=16,
DLASTSGA=-16,
CITER_ELINKNO=dma.R_TCD_ITER_ELINKNO(ITER=2),
BITER_ELINKNO=dma.R_TCD_ITER_ELINKNO(ITER=2),
)
In [78]:
proxy.mem_fill_uint32(dst_addr, 0, N / 4)
request = dma.TCD()
request.CopyFrom(XFER_REQUEST)
request.CSR.START = 0
proxy.update_dma_TCD(1, request)
Out[78]:
In [94]:
proxy.mem_fill_uint32(dst_addr, 0, N / 4)
proxy.update_dma_registers(dma.Registers(SSRT=1))
proxy.mem_cpy_device_to_host(dst_addr, 20)
Out[94]:
In [18]:
proxy.update_dma_TCD(0, XFER_REQUEST)
tcd0 = dma.TCD.FromString(proxy.read_dma_TCD(0).tostring())
df_tcd0 = resolve_field_values(tcd0)
display(df_tcd0[['full_name', 'value']].dropna()
.join(TCD_DESCRIPTIONS, on='full_name')
[['full_name', 'value', 'short_description', 'page']]
.sort_values(['page','full_name']))
In [ ]:
In [89]:
dchpri0 = dma.DCHPRI.FromString(proxy.read_dma_priority(0).tostring())
df_dchpri0 = resolve_field_values(dchpri0)
display(df_dchpri0[['full_name', 'value']].dropna().join(DCHPRI_DESCRIPTIONS, on='full_name'))
In [94]:
proxy.update_dma_registers(CERQ=0) # (ES=dma.R_ES())
In [93]:
dma_registers = dma.Registers.FromString(proxy.read_dma_registers().tostring())
df_dma = resolve_field_values(dma_registers)
display(df_dma.dropna(subset=['value'])
.join(DMA_REG_DESCRIPTIONS, on='full_name')
[['full_name', 'value', 'short_description', 'page']])
In [52]:
init_dma(proxy)
proxy.update_dma_TCD(0, dma.TCD(CSR=dma.R_TCD_CSR(BWC=dma.R_TCD_CSR.NO_STALLS)))
tcd0 = dma.TCD.FromString(proxy.read_dma_TCD(0).tostring())
df_tcd0 = resolve_field_values(tcd0)
display(df_tcd0[['full_name', 'value']].dropna()
.join(TCD_DESCRIPTIONS, on='full_name')
[['full_name', 'value', 'short_description', 'page']]
.sort_values(['page','full_name']))
In [30]:
adc0 = adc.Registers.FromString(proxy.read_adc_registers(0).tostring())
df_adc0 = resolve_field_values(adc0)
display(df_adc0[['full_name', 'value']].dropna())
In [31]:
proxy.update_sim_SCGC6(sim.R_SCGC6(PIT=True))
Out[31]:
In [51]:
scgc6 = sim.R_SCGC6.FromString(proxy.read_sim_SCGC6().tostring())
df_scgc6_fields = resolve_field_values(scgc6)
display(df_scgc6_fields[['full_name', 'value']].dropna().T)
scgc7 = sim.R_SCGC7.FromString(proxy.read_sim_SCGC7().tostring())
df_scgc7_fields = resolve_field_values(scgc7)
display(df_scgc7_fields[['full_name', 'value']].dropna().T)
In [33]:
pit_registers = pit.Registers.FromString(proxy.read_pit_registers().tostring())
df_pit_registers = resolve_field_values(pit_registers)
display(df_pit_registers[['full_name', 'value']].dropna())
pit_tmr0 = pit.TimerConfig.FromString(proxy.read_pit_timer_config(0).tostring())
df_pit_tmr0 = resolve_field_values(pit_tmr0)
display(df_pit_tmr0[['full_name', 'value']].dropna()
.join(TIMER_CONFIG_DESCRIPTIONS, on='full_name'))
In [34]:
proxy.D__F_CPU(), proxy.D__F_BUS()
Out[34]:
In [35]:
proxy.dma_channel_count()
Out[35]:
In [36]:
frames = []
for i in xrange(proxy.dma_channel_count()):
tcd = dma.TCD.FromString(proxy.read_dma_TCD(i).tostring())
frame = resolve_field_values(tcd)
frame.insert(0, 'channel', i)
frames.append(frame)
df_tdc_fields = pd.concat(frames)
# df_tdc_fields[['channel', 'full_name', 'value']].dropna().loc['CSR']
In [49]:
# tcd.CSR.BWC = dma.R_TCD_CSR.E_BWC.Value('STALL_4_CYCLES')
tcd = dma.TCD(SADDR=1234)
# tcd.CSR.BWC = dma.R_TCD_CSR.E_BWC.Value('NO_STALLS')
proxy.update_dma_TCD(0, tcd.SerializeToString())
Out[49]:
In [13]:
tcd.SADDR = 1234
tcd.SLAST = -1
tcd.DADDR = 4321
tcd.DLASTSGA = -1
tcd.NBYTES_MLNO = 4
tcd.CSR.BWC = dma.R_TCD_CSR.E_BWC.Value('NO_STALLS')
proxy.update_dma_TCD(0, tcd.SerializeToString())
Out[13]:
In [45]:
# addr = proxy.mem_aligned_alloc_and_set(range(16), 16)
# addr = proxy.mem_aligned_alloc(16, 24)
# proxy.ram_free()
N = 512
src_addr = proxy.mem_alloc(N)
dst_addr = proxy.mem_alloc(N)
[hex(addr)[:-1] for addr in (src_addr, dst_addr)]
Out[45]:
In [39]:
%timeit proxy.mem_cpy_device_to_host(src_addr, N)
In [40]:
for addr in (src_addr, dst_addr):
proxy.mem_fill_uint32(addr, 0, N / 4)
In [42]:
import numpy as np
N_i = N / 2 / 2
for i in xrange(2):
proxy.mem_cpy_host_to_device(src_addr + i * N_i * 2, np.arange(i * N_i, (i + 1) * N_i, dtype='uint16').view('uint8'))
In [43]:
print proxy.mem_cpy_device_to_host(src_addr, N).view('uint16')
print proxy.mem_cpy_device_to_host(dst_addr, N).view('uint16')
In [44]:
for addr in (src_addr, dst_addr):
proxy.mem_free(addr)
In [16]:
proxy.mem_fill_uint16(src_addr + 4, 65000, 4)
In [46]:
proxy.mem_cpy_device_to_host(addr, 8)
Out[46]:
In [4]:
proxy.mem_cpy_device_to_host(0x40009000, 4 * 32)
Out[4]:
In [21]:
addrs = [proxy.do_aligned_alloc(4, 128) for i in xrange(8)]
addrs
Out[21]:
In [14]:
addrs = [proxy.do_aligned_alloc(4, 128) for i in xrange(8)]
addrs
Out[14]:
In [22]:
for addr in addrs:
proxy.do_aligned_free(addr)
In [6]:
tcd = dma.TCD.FromString(proxy.read_dma_TCD(0).tostring())
df_tdc_fields = resolve_field_values(tcd)
df_tdc_fields[['full_name', 'value']].dropna()
Out[6]:
In [14]:
scgc6 = sim.R_SCGC6.FromString(proxy.read_sim_SCGC6().tostring())
df_scgc6_fields = resolve_field_values(scgc6)
df_scgc6_fields[['full_name', 'value']].dropna().T
Out[14]:
In [29]:
scgc7 = sim.R_SCGC7.FromString(proxy.read_sim_SCGC7().tostring())
df_scgc7_fields = resolve_field_values(scgc7)
df_scgc7_fields[['full_name', 'value']].dropna().T
Out[29]:
In [43]:
proxy.startSingleRead(teensy.A1, teensy.ADC_0)
Out[43]:
In [58]:
proxy.adc_read()
Out[58]:
In [65]:
adc0_registers = adc.Registers.FromString(proxy.read_adc_registers(0).tostring())
df_fields = resolve_field_values(adc0_registers).join(ADC_DESCRIPTIONS, on='full_name')
df_fields.loc[(df_fields.index != '') |
df_fields.full_name.str.startswith('R'),
['full_name', 'value', 'short_description']]
Out[65]:
In [24]:
teensy.adc.SC1A_TO_CHANNEL_ADC0[df_fields.set_index('full_name').loc['SC1A.ADCH'].value]
teensy.adc.CHANNEL_TO_SC1A_ADC0[teensy.A0]
Out[24]:
In [16]:
proxy.analogRead(teensy.A0, teensy.ADC_0)
Out[16]:
In [36]:
[(k.full_name, v) for k, v in adc0_registers.ListFields()]
Out[36]:
In [11]:
adc0_registers.SC3.
Out[11]:
In [140]:
proxy.start_timer(20)
In [141]:
%matplotlib inline
In [219]:
frames = []
for i in xrange(100):
result = proxy.adc_read()
adc_count = result[:2].view('uint32')[0]
channel_start_i = [0, 1]
channel_readings = result[2:]
#frame = pd.DataFrame([[adc_count[0], adc_count, channel_readings[0]]],
#columns=['count', 'adc_count', 'reading'])
frame = pd.DataFrame(channel_readings, columns=['reading'])
frame.insert(0, 'adc_count', adc_count)
frame.insert(0, 'i', i)
frames.append(frame)
readings = pd.concat(frames)
In [227]:
import numpy as np
# print pd.Series(channel_readings[channel_start_i[0]::2]).describe()
# print pd.Series(channel_readings[channel_start_i[1]::2]).describe()
df_i = readings.reset_index(drop=True)
df_i['offset'] = df_i.groupby('i')['adc_count'].transform(lambda v: v & 0x01)
count_scan = np.zeros(df_i.i.unique().shape[0], dtype='uint')
count_scan[1:] = df_i.groupby('i')['adc_count'].count().cumsum()[:-1]
df_i.loc[:, 'count_exc_scan'] = count_scan[df_i['i']]
df_i['group_i'] = np.arange(df_i.shape[0]) - df_i['count_exc_scan']
df_i['channel_i'] = 0
df_i.loc[(df_i.group_i & 0x01 == 1) & (df_i.offset == 0), 'channel_i'] = 1
df_i.loc[(df_i.group_i & 0x01 == 0) & (df_i.offset == 1), 'channel_i'] = 1
df_i.drop('count_exc_scan', axis=1, inplace=True)
df_i.loc[(df_i.channel_i == 0) & (df_i.reading < 1000),
['group_i', 'channel_i', 'reading']].shape[0]
Out[227]:
In [123]:
proxy.dma_available()
Out[123]:
In [ ]:
import numpy as np
In [ ]:
def leading_zeros(value, bits=32):
for i in xrange(bits, 0, -1):
if (value >> (bits - i)) == 1:
return i - 1
return bits
(31 - leading_zeros(256)) << 3
In [ ]:
9 << 3
In [ ]:
import time
N = 32
# proxy.dma_start(1 << int(np.ceil(np.log2(N))))
proxy.dma_start(256)
for i in range(N): proxy.startSingleRead(teensy.A0, teensy.ADC_0)
# time.sleep(0.01)
result = proxy.adc_read()
print result.shape[0]
result
In [ ]:
result = proxy.adc_read()
result.shape[0], result.mean()
In [ ]:
proxy.start_timer(5)
In [ ]:
1 / 100e3 / 1e-6
In [ ]:
proxy.adc_period_us()
In [ ]:
import time
proxy.startContinuous(teensy.A0, teensy.ADC_0)
while proxy.dma_available() < N: time.sleep(0.001)
proxy.stopContinuous(teensy.ADC_0)
proxy.adc_read()
In [ ]:
proxy.enableInterrupts(teensy.ADC_0)
In [ ]:
proxy.adc_timestamp_us()
In [ ]:
# for i in range(128): proxy.startSingleRead(teensy.A0, teensy.ADC_0)
# proxy.startSingleRead(teensy.A0, teensy.ADC_0)
In [ ]:
from datetime import datetime, timedelta
start = datetime.now()
start_us = proxy.microseconds()
proxy.startContinuous(teensy.A0, teensy.ADC_0)
proxy.stopContinuous(teensy.ADC_0)
start + timedelta(microseconds=proxy.adc_timestamp_us() - start_us), proxy.adc_read()
In [ ]:
import time
import pandas as pd
ADC_SPEEDS = pd.Series(['ADC_VERY_LOW_SPEED',
'ADC_LOW_SPEED',
'ADC_MED_SPEED',
# 'ADC_HIGH_SPEED_16BITS',
'ADC_HIGH_SPEED',
'ADC_VERY_HIGH_SPEED'],
index=[teensy.ADC_VERY_LOW_SPEED,
teensy.ADC_LOW_SPEED,
teensy.ADC_MED_SPEED,
# teensy.ADC_HIGH_SPEED_16BITS,
teensy.ADC_HIGH_SPEED,
teensy.ADC_VERY_HIGH_SPEED])
def benchmark_adc(proxy):
rows = []
for conversion_i, conversion_speed in ADC_SPEEDS.iteritems():
for sampling_i, sampling_speed in ADC_SPEEDS.iteritems():
for averaging in (0, 4, 8, 16, 32):
for resolution in (8, 10, 12):
if [conversion_i, sampling_i, averaging] == [5, 5, 0]:
continue
print '.',
try:
proxy.setAveraging(averaging, teensy.ADC_0)
proxy.setResolution(resolution, teensy.ADC_0)
proxy.setConversionSpeed(conversion_i, teensy.ADC_0)
proxy.setSamplingSpeed(sampling_i, teensy.ADC_0)
proxy.startContinuous(teensy.A0, teensy.ADC_0)
time.sleep(0.001)
proxy.stopContinuous(teensy.ADC_0)
period_us = proxy.adc_period_us()
except IOError:
print 'Failed for %s' % [conversion_i, sampling_i, averaging,
resolution]
raise
row = [conversion_i, sampling_i, averaging,
resolution, period_us]
rows.append(row)
df_adc_benchmarks = pd.DataFrame(rows, columns=['conversion_i',
'sampling_i',
'averaging',
'resolution',
'period_us'])
df_adc_benchmarks.loc[df_adc_benchmarks.period_us < 0, 'period_us'] += 1000
# df_adc_benchmarks.set_index(['conversion_speed', 'sampling_speed',
# 'averaging', 'resolution'], inplace=True)
df_adc_benchmarks['sampling_rate_Hz'] = 1e6 / df_adc_benchmarks['period_us']
return df_adc_benchmarks
In [ ]:
df_adc_benchmarks = benchmark_adc(proxy)
In [ ]:
%matplotlib inline
In [365]:
teensy.ADC_VERY_HIGH_SPEED
Out[365]:
In [ ]:
from si_prefix import si_format
df_i = (df_adc_benchmarks.loc[(df_adc_benchmarks.resolution > 8) &
(df_adc_benchmarks.averaging > 0) &
(df_adc_benchmarks.sampling_rate_Hz >= 100e3)]
.sort_values(by=['sampling_rate_Hz', 'resolution', 'conversion_i', 'sampling_i'],
ascending=False))
df_i['conversion_speed'] = ADC_SPEEDS[df_i.conversion_i].values
df_i['sampling_speed'] = ADC_SPEEDS[df_i.sampling_i].values
df_i['sampling_rate'] = df_i.sampling_rate_Hz.map(si_format)
df_i[['sampling_rate', 'averaging', 'resolution', 'conversion_speed', 'sampling_speed']]
In [ ]:
df_i[['sampling_rate', 'averaging', 'resolution', 'conversion_speed', 'sampling_speed']]
axis = (df_i.set_index(['averaging', 'resolution', 'conversion_speed', 'sampling_speed'])
['sampling_rate_Hz']).plot(rot=90, style='o')
axis.set_yticklabels(['%sHz' % si_format(v) for v in axis.get_yticks()])
# axis.get_figure().savefig('test.pdf', bbox_inches='tight')
pass
In [ ]:
fig.savefig
In [ ]:
import time
import pandas as pd
In [ ]:
proxy.adc_period_us()
In [ ]:
proxy.digital_write(13, 0)
In [ ]:
proxy.startContinuous(teensy.A0, teensy.ADC_0)
In [ ]:
proxy.stopContinuous(teensy.ADC_0)
In [ ]:
proxy.isContinuous(teensy.ADC_0)
In [ ]:
if proxy.dma_available() > 0:
print proxy.dma_read()
proxy.adc_buffer(), proxy.dma_available()
In [ ]:
proxy.startSingleRead(teensy.A0, teensy.ADC_0)
In [ ]:
proxy.dma_available(), proxy.dma_empty(), proxy.dma_full()
In [ ]:
proxy.dma_read()
In [ ]:
proxy.start_timer(10)
In [ ]:
%matplotlib inline
import pandas as pd
In [ ]:
from datetime import datetime
In [ ]:
proxy.setAveraging(0, -1)
In [ ]:
data = pd.DataFrame([(proxy.analogRead(0, -1), datetime.now()) for i in xrange(200)],
columns=['reading', 'timestamp'])
data.set_index('timestamp').plot()
In [ ]:
proxy.adc_buffer
In [ ]:
40 * proxy.benchmark_flops(10e3) / 10e3
In [ ]:
40 * proxy.benchmark_iops(10e3) / 10e3
In [ ]:
import sys
sys.path.insert(0, r'C:\Users\Christian\Documents\GitHub\ring-buffer-testbench')
In [ ]:
from ring_buffer_testbench.cRingBuffer import cRingBuffer
In [ ]:
ring_buffer = cRingBuffer()
In [ ]:
ring_buffer.elems(), ring_buffer.b_start, ring_buffer.b_end