DSO firmware version 3.3

Attached is the most recent BenF V3.3x firmware.

The DSO Nano is using what’s commonly referred to as DC-coupling for its input signal and so all measurements are relative to ground. Vrms (root-mean-square) however is typically used with AC-coupling and so the current Vrms measurement may not be what users expect. To compensate for this, I’ve changed the Vrms calculation to use a synthesized AC-coupled reference. Further details on how measurements are calculated have been added to the readme file.

Display of waveforms for narrow T/Div’s (high frequency input) showed clearly visible steps due to the limited DSO Nano bandwidth. In this update, I’m using an interpolation drawing algorithm for a much smoother waveform display.

Some users wanted to see more of the waveform data after the trigger. This version adds an option to shift sampling buffer usage priority between pre and post trigger data. Fine tuning of output frequency as well as an option to specify duty cycle (pulse width modulation) have been added and basic calibration has been replaced with a full calibration capability (offset and gain for all ranges set individually).

New features in this version includes (see revisions.txt for all changes):

  • Use interpolated waveform drawing for narrow T/div’s (less equal 20us)
  • Tuned FIT mode for faster response and more accurate scale selections
  • Made AC measurement (Vrms and Duty) calculations relative to Vavg
  • Support screen capture with measurements (select ME and press B or long M)
  • Support fine tuning of output frequency (3-digits, range 10Hz-1MHz)
  • Option to specify duty-cycle (PWM) for output frequency in 1% increments from fully-on to fully-off
  • Added support for full calibration (separate offset and gain for all ranges)
  • Added option to set sampling buffer usage priority (pre/post equal split or post priority)

Update APP V3.31 - 2010.12.01

  • Fix issue with unable to select 1MHz output frequency
  • Fix issue with AUTO trigger in post priority mode

Update APP V3.32 - 2010.12.01

  • Fix issue with gain not settable for some ranges
  • Fix issue with time cursor offset error
  • Swap left/right keys for T/Div and V/Div (change to waveform centric)
  • Adjust duty cycle subject to HW V1/V2 differences (experimental)
  • Display detected HW version (V1 or V2) on startup screen

Update APP V3.33 - 2010.12.11

Hello BenF,
you spoil us :slight_smile: Been playing with this for a just few minutes and I love it: as usual, your work really rocks.

Thanks a lot!

Antonio

PS: hope you don’t mind me asking, but… is there any chance of seeing your code updates regularly on SVN? The part you published already has been a big boon for learning, and I’m eager for more :wink:

That is fantastic, BenF. And it is not even Christmas yet :slight_smile: Apropos, is there a means thankful people can send you something?

EDIT: removed two bad apples.

Hello BenF,
found a small bug on duty cycle: 0% results in an always on PWM, while 100% is always off. You should reverse the percent value (ie use 100-duty) when updating TIM4_CCR1.

Antonio

Another small typo - incrementing frequency 999kHZ I get 1.41MHz.

Antonio

Great job BenF! You have just made a very useful O’scope even better!

Many thanks,
Steve

Thnaks for your feedback guys!

This is a bug and I’ll post a fix for that.

This one I can not reproduce. Duty cycle is defined as the ratio of on-time to cycle time and that’s what I get. Any steps to reproduce or are you suggesting it should be defined differently?

BenF, thanks for this fine firmware,

Some small things… :

at x1 attn the 5V/div and 0.5 V/div and at x10 attn the 5 V/div and 50 V/div ranges cant be calibrated in gain %.

The T1 and T2 cursors have an offset compared with the trigger point for example 4 ms at 100 ms/div.

Also i prefer the X left and right and Y left and right keys swapped… i work al lot with oscillopscopes and when i push left button on these the level of the measured signal drops…when i do the same on the DSO nano the level increases…(verry confusing) the same goes for the timebase…

I also played around with your 3.11 version…i made some changes to the grid an markers… look at attachment

Keep up the good work,
Thanks.
IMAGE002.rar (2.41 KB)

I was hoping to see some radical new development and that the 3.11 source could provide a framework for that. With the Gcc version up and running (kudos to all involved – great work) all ingredients should be in place.

What about the FFT version? I would love to see a guitar tuner app and maybe a pickup microphone from Seeed to go along with this. Or perhaps replace the USB file system interface with USB serial and a PC front end DSO application?

Well, on my part I have been trying to do something: some adjustments for IAR5 and a simple PWM duty cycle, for now. Being a newcomer to embedded devices, I’m dead slow, though - and
the smallish things I’ve done are drowned by your work :slight_smile:

I’ve just started to dip my feet into available FFT algorithms in order to make out something, and Tormod’s already picked up on the post… so that’s possible.

I’d like to implement a new menu leading to frequency-domain visualization, with two cursors for accurately reading both frequency and amplitude of each sine wave component. At present, it’s only an idea - I need to study quite a bit before realizing it. Of course, advice is welcome!

Antonio

The definition is the same for me: but if I set the duty cycle at 0% I obtain a high level all the time, while choosing 100% I read a constant low - it should be the other way around, shouldn’t it? Maybe my DSO Nano is the difference: I have the v2, but from the image in your manual I’d say you have a v1.

Antonio

The v1 uses an SP3232 inverting buffer, while the v2 uses the non-inverting 74hc125.

Devil is in the details as the saying goes. There is indeed a one pixel offset error in the displayed cursor time offsets.

To fix the gain issue, I will modify the logic to just use the smallest step possible for all ranges.

As for left/right not being waveform centric in relation to voltage and time base, I have the same issue, so perhaps we should just go ahead and change that (this is a left over from the 2.5 version).

Your color scheme looks nice. If you post the color codes, I can look at adopting preference schemes.

Thanks for your input!

P.S. There appears to be an artifact of some sort on your trigger axis.

Well, that would explain why we see things differently.

How about detecting which version we run on. Any ideas?

BenF,
Have some ideas to add confortrable work,
see picture(i744.photobucket.com/albums/xx86/egochina/DSO.jpg?t=1274252682)
Can you add option to show/hide on screen triger/etc values as on picture from this dso?

Hi Benf,

first of all i’d like to congratulate you because you have done an awesome work. Your programming skills and knowledge have taken DSO Nano to a superior stage. Absolutely.

In regard to version detection, maybe it’s possible to have it and also zero calibration. My idea is to use Fout to distinguish between V1 and V2. As V1 inverts Fout signal and V2 not, it easy to discern one from another only by feeding Fout to the probe. Other option is to use B button (not present in V1).

But in V2 we have another advantage as 74HC125 is powered between 0 and 3.6V rail. When Fout is ‘0’ (0% cycle or low, whatever you want) the gate will propagate the ‘0’. As the gate is a CMOS device and DSO input is high impedance, one can expect a few mV in Fout when low, leaving room for automatic zero calibration across all gains.

So the procedure could be something like this:
1-Program starts. Read an internal flash memory ‘variable’ to discern whether version identification and/or calibration has been done.
2-If needs calibration / version ID, connect probe to Fout.
3-Identify version
4-Calibrate ground reference.
5-Done!!!

Hope it helps!!

Hi BenF,
Thanks again for all your work. The multi-range calibration seems to work while the DSO is still turned on (I have been playing with the offsets so far, not the gain), but saving to the profile doesn’t seem to work. After setting the offsets for all ranges I can go up and down between ranges and the zero holds. But if I save the profile to ‘S Flash’ then cycle the power, I lose all my offsets. Doing a manual load of the profile from ‘L Flash’ doesn’t help either. Am I missing something? Do I need an SD card to save this new cal data to?
Cheers,
Adrian.
p.s. that was 3.31 I was testing with…

Thanks for your input!

Are you suggesting there is a way to connect Fout to probe input without asking the user to do so?

The button idea might work. As soon as it gets pressed, we would know which version it is. In hindsight however one might wish for an unused IO pin tied to a known logic level to check against.

Hi BenF,

I added a second grid color (GRD2_COLOR) and Flag (GRD2_FLAG) in LCD.h and ASM_Function.s:

[code]//======================= display color mapping ================================
// R = 5 bits 0:4, G = 6 bits 5:10, B = 5 bits 11:15
#define RGB(_R,_G,_B) (((_R & 0x3E) >> 1) | ((_G & 0x3f) << 5) | ((_B & 0x3e) << 10))

#define C_GROUP 0x1082 //0x1082 // 00010 000100 00010
#define F_SELEC 0x18E3 //0x18E3 //was 0x18E3 // 00011 000111 00011
#define WAV_FLAG 0x0080 //0x0080
#define CH2_FLAG 0x0002
#define REF_FLAG 0x1000
#define LN1_FLAG 0x0020
#define LN2_FLAG 0x0800
#define GRD_FLAG 0x0001
#define GRD2_FLAG 0x0040
#define LN1_COLOR (RGB(0,63,0) & ~F_SELEC) | LN1_FLAG
#define LN2_COLOR (RGB(63,24,0) & ~F_SELEC) | LN2_FLAG
#define GRD_COLOR (RGB(24,24,24) & ~F_SELEC) | GRD_FLAG
#define GRD2_COLOR (RGB(13,13,13) & ~F_SELEC) | GRD2_FLAG
[/code]

So al little code had to be added to erase this grid in __Erase_Color function in ASM_Fuction.c

[code]ERASE_GRD:
MOVW R5, #GRD_FLAG
ANDS R5, R5, R3
BEQ ERASE_GRD2 ;restores background
MOVW R5, #GRD_COLOR
ORR R3, R3, R5 ;Restore grd color
ERASE_GRD2:
MOVW R5, #GRD2_FLAG
ANDS R5, R5, R3
BEQ ERASE_3 ;restores background
MOVW R5, #GRD2_COLOR
ORR R3, R3, R5 ;Restore grd color
ERASE_3:
STR R3, [R7, #ODR] ;[LCD_DATA] = R3
STR R4, [R6, #OUT_L] ;WR = 0

MOVW    R6,  #LCD_Ctrl_PORT  
MOVT    R6,  #GPIO              ;DELAY 2 CYCEL

STR     R4,  [R6, #OUT_H]       ;WR = 1

LDMIA   SP!, {R4-R7}           
BX      LR[/code]   

To display the new grid i changed LCD.c:

[code]// horizontal grid2 lines
for (j = MIN_Y; j <= (MAX_Y + 1); j += 5) // for (j = MIN_Y + 5; j <= (MAX_Y - 5 + 1); j += 5)
{
for (i = MIN_X; i <= (MAX_X + 1); i += 1) //for (i = MIN_X + 3; i <= (MAX_X - 3 + 1); i += 1)
{
if (j == (MIN_Y + Y_SIZE / 2)) {
for (n = -1; n <= 1; n++) {
Point_SCR(i, j);
Set_Pixel(GRD2_COLOR);
}
} else {
Point_SCR(i, j);
Set_Pixel(GRD2_COLOR);
}
}
}

// vertical grid2 lines
for (i = MIN_X; i <= (MAX_X+ 1); i +=5) //for (i = MIN_X + 5; i <= (MAX_X - 5+ 1); i +=5)
{
for (j = MIN_Y; j <= (MAX_Y + 1); j += 1) //for (j = MIN_Y + 3; j <= (MAX_Y - 4 + 1); j += 1)
{
if (i == (MIN_X + X_SIZE / 2)) {
for (n = -1; n <= 1; n++) {
Point_SCR(i, j);
Set_Pixel(GRD2_COLOR);
}
} else {
Point_SCR(i, j);
Set_Pixel(GRD2_COLOR);
}
}
}

// horizontal grid lines
for (j = MIN_Y; j <= (MAX_Y+ 1); j += 25) //for (j = MIN_Y; j <= (MAX_Y+ 1); j += 25)
{
for (i = MIN_X ; i <= (MAX_X + 1); i += 1) //for (i = MIN_X + 3 ; i <= (MAX_X - 3 + 1); i += 1)
{
if (j == (MIN_Y + Y_SIZE / 2)) {
for (n = -1; n <= 1; n++) {
Point_SCR(i, j);
Set_Pixel(GRD_COLOR);
}
} else {
Point_SCR(i, j);
Set_Pixel(GRD_COLOR);
}
}
}

// vertical grid lines
for (i = MIN_X; i <= (MAX_X + 1); i += 25)
{
for (j = MIN_Y; j <= (MAX_Y + 1); j += 1)
{
if (i == (MIN_X + X_SIZE / 2)) {
for (n = -1; n <= 1; n++) {
Point_SCR(i, j);
Set_Pixel(GRD_COLOR);
}
} else {
Point_SCR(i, j);
Set_Pixel(GRD_COLOR);
}
}
}[/code]

The Left - Right Swap is easy change Left in Right and Right in Left for both x and Y sensitivity…

I also liked to see the GND as a line, so i changed case gnd_position in main.c

case GND_POSITION: Draw_Vi_Mark(Item_Index[V0], ERASE, GND_COLOR); Draw_Vi_Line(Item_Index[V0], ERASE, GND_COLOR); Erase_Sensitivity(); if ((Key_Buffer == KEYCODE_RIGHT) && (Item_Index[V0] < MAX_Y - 1) && (Item_Index[VT] < (MAX_Y - Item_Index[TRIG_SENSITIVITY] - 1))) { Item_Index[V0]++; Item_Index[VT]++; } if ((Key_Buffer == KEYCODE_LEFT) && (Item_Index[V0] > (MIN_Y + 1)) && (Item_Index[VT] > (MIN_Y + Item_Index[TRIG_SENSITIVITY] - 1))) { Item_Index[V0]--; Item_Index[VT]--; } Hide_Index[V0] = 0; break;

Hi Benf,

no, there is no way to conect Fout to the probe without instructing user to do so. But it would be a fast method to do zero calibration across all gains.

in regard to a hardware indication, i’m afraid that the response is no. I’ve checked both V1 and V2 schematics and from microprocessor point of view the only differences are button B, TX/RX (which are not interconected) and BOOT0 pin. BOOT0 pin is not general I/O, so i doubt a pull-up can be activated (this could allow version identification).

Maybe RX line can be used for that purpose. As RX is driven by 74HC125, you could check the level at startup, then activate soft pull-up/pull-down. In version V1 as there is nothing conected to the pin it should reflect the change. In V2 the gate output will prevent it from changing.