free logic analizer

aster
Tue Apr 11, 2017 10:10 pm
hello!

trying to discover the maple mini for another project i thought to port this old avr project to stm32:
don’t except too much, i wrote it when i started with mcu, it is just a loop reading of the 328’s PORTB and then a nice processing interface

https://www.hackster.io/vincenzo-g/diy- … zer-f61ee5

so coming back to the stm32, how could i reset the timer used by micros()?

this is the code for the maple mini:
#define samples 200
#define boardLed 33
uint8_t initial, state, old_state;
uint8_t pinChanged[samples];
uint32_t timer[samples];
uint16_t event = 0;

void setup() {

Serial.begin(115200);

pinMode (boardLed, OUTPUT);
digitalWrite(boardLed, LOW);

for (byte pin = 28; pin <= 31; pin++) {
pinMode(pin, INPUT_PULLUP);
}

startLA();

}

void startLA() {
delay(1000);

//reset_timer1(); //reset the timer? how?
event = 0;

digitalWrite(boardLed, HIGH);
initial = GPIOB->regs->IDR >> 12;
state = initial;

}

void loop() {

old_state = state;
state = GPIOB->regs->IDR >> 12;

if (old_state != state) {
timer[event] = micros();
pinChanged[event] = state ^ old_state;
event++;

if (event == samples) {
sendData();
while (Serial.read() != 'G') ; //wait for the "go"
startLA();
}
}
}

void sendData() {
digitalWrite(boardLed, LOW);

//initial data
Serial.println("S");
Serial.print(initial); Serial.print(":");
Serial.println(samples);

//data
for (int i = 0; i < samples; i++) {
Serial.print(pinChanged[i]); Serial.print(":");
Serial.println(timer[i]);
}
}


mrburnette
Tue Apr 11, 2017 11:02 pm
I would suggest that you familiarize yourself with the timer hardware…
http://docs.leaflabs.com/static.leaflab … imers.html

Good luck,

Ray


aster
Tue Apr 11, 2017 11:41 pm
Great a simple reflash() should work
All the libraries from the maple team are already included or i should include it?

ag123
Wed Apr 12, 2017 2:03 am
it seemed that Timer() and HardwareTimer()
http://docs.leaflabs.com/static.leaflab … dwaretimer
are part of the core libmaple library, this probably means it’s not necessary to include an additional library

it would seem using an interrupt could help, the example on leaflabs’s HardwareTimer() page actually shows an interrupt example

but i’m thinking you could even do interrupts directly
http://docs.leaflabs.com/static.leaflab … rupts.html
http://docs.leaflabs.com/static.leaflab … hinterrupt

especially if you are sampling against a clock source, attachInterrupt() has nice triggers params, e.g. to trigger on rising edge, falling edge or transitions

with stm32f1 it would seem it may even be able to monitor at spi speeds (i.e. mhz), could be interesting to test that


ddrown
Wed Apr 12, 2017 8:36 pm
ag123 wrote:with stm32f1 it would seem it may even be able to monitor at spi speeds (i.e. mhz), could be interesting to test that

aster
Sat Apr 15, 2017 4:50 pm
ag123 wrote:it seemed that Timer() and HardwareTimer()
http://docs.leaflabs.com/static.leaflab … dwaretimer
are part of the core libmaple library, this probably means it’s not necessary to include an additional library

it would seem using an interrupt could help, the example on leaflabs’s HardwareTimer() page actually shows an interrupt example

but i’m thinking you could even do interrupts directly
http://docs.leaflabs.com/static.leaflab … rupts.html
http://docs.leaflabs.com/static.leaflab … hinterrupt

especially if you are sampling against a clock source, attachInterrupt() has nice triggers params, e.g. to trigger on rising edge, falling edge or transitions

with stm32f1 it would seem it may even be able to monitor at spi speeds (i.e. mhz), could be interesting to test that


stevestrong
Sat Apr 15, 2017 4:53 pm
Please use PXY (e.g. PA4) notation for pins instead of raw numbers.

ag123
Sun Apr 16, 2017 5:56 pm
aster wrote:
yep using interrupt it would be better but for semplicity i would rather to read the port

i tried this but it didn’t work, any idea?

HardwareTimer timer(0);

void setup() {

Serial1.begin(115200);
pinMode(32, INPUT_PULLUP);

}

void loop() {

Serial1.println(millis());
if (digitalRead(32)) {
Serial1.print("A");
timer.refresh();
}

}


aster
Sun Apr 16, 2017 7:56 pm
I should had said before that i didn’t have problem with the Serial but with the timer timer.refresh(); from maple documentation should reset the counter, and overflow but for some reason it doesn’t work

ag123
Sun Apr 16, 2017 9:00 pm
@aster
while hardware timer is also rather new to me
http://docs.leaflabs.com/static.leaflab … dwaretimer
if you take a look at the example for hardware timer
the ‘blink led’ example, there are various statements configuring the timer in setup()
then within setup
timer.attachCompare1Interrupt(handler_led);

dev
Tue Apr 18, 2017 2:15 am
Hi,
Is this Logic Analyser working now.

aster
Tue Apr 18, 2017 11:16 pm
dev wrote:Hi,
Is this Logic Analyser working now.

dev
Sat Apr 22, 2017 2:21 pm
Sounds great.
btw, are you using SUMP protocol or different?
Let me know if i can be helpful.

aster
Sat Apr 29, 2017 11:55 am
annnnnd finally it is completed and it works well!! :D

https://www.hackster.io/vincenzo-g/diy- … zer-f61ee5
https://github.com/aster94/logic-analyzer

I’m very surprised that the STM32 is able to spot a change of only a microsecond between two pulses
if someone with a real logic analyzer or oscilloscope would like to test how this code works i will be very happy to know the results!

to reset the system timer i had to do little dig in the core files, this is the result of my researches:

void reset_timer() {
systick_uptime_millis = -1; //millis counter
SYSTICK_BASE->CNT = 0; //micros counter
}


Pito
Sat Apr 29, 2017 12:25 pm
Vincenzo, nice project!
Some ideas:
1. you can use the DWT register (32bit counter) which increments in 13.88ns period on the Maple Mini – that could be your resolution then.
It works on F407 but it is implemented on F103 as well, double check. UPDATE: It works on Maple Mini too.. Here is the code:
http://www.stm32duino.com/viewtopic.php … 234#p26692
So instead of reading micros() you read the cpu clock ticks with CpuGetTicks() in 13.88ns resolution.
2. you must not reset the timer (you cannot with DWT reg), the timer[0] carries the start point (zero point timestamp), the other duration[1] = timer[1] – timer[0], duration[2] = time[2] – time[1], etc.
3. you may wait on a “trigger event” when the input signal matches your TRIGGER_MASK, then start with sampling, for example
void startLA() {
//delay(1000);
event = 0;
digitalWrite(boardLed, HIGH); // Armed, waiting on trigger
reset_timer();

while( (initial = GPIOB->regs->IDR >> 12) != TRIGGER_MASK ) {}; // here we wait till the input signal matches the TRIGGER_MASK
state = initial;
}


ag123
Sat Apr 29, 2017 3:53 pm
so it reaches 1 msps resolution, would try it out 1 day
the loop seem to look ‘deceptively’ simple, no interrupts? :D
i’ve a strange feeling that that loop may well be doing millions of loops per sec
e.g. no change, no change, no change, no change, … ok 1 change, no change, no change … :lol:

i’m also trying to figure out how to receive data over at my linux box at > 115200, i’d think those ttyACM* should be able to do mbits per sec or even mbytes per sec, then it may be able to probe in ‘real time’, imagine if it is possible to let the dma do all that probing and then dma that via usb to the host, the 72mhz cpu literally ‘do nothing’, maybe it can play an mp3 in the mean time, while the dma controller is busy doing all that LAing :lol:

hmm, i’m wondering what would happen if this is run on f407 @168mhz with that ART accelerator, beware pito would push it at 240 mhz + ART accelerator (0 wait states) maybe it reaches > 100 msps? :lol:


Pito
Sat Apr 29, 2017 5:43 pm
Updated my above link – the “nanoseconds” measurement on Maple Mini works too.
1 usec is 1041.660 nanosecs long
1 usec is 1041.660 nanosecs long
1 usec is 1041.660 nanosecs long

ag123
Sat Apr 29, 2017 6:23 pm
i’m wondering what would happen if we (ever) read that clock train SPI style, e.g. setup as a SPI slave, feed the clock into SCK and we ‘lazily’ just read the input on MOSI (e.g. read_byte = SPI.transfer(0x00); ), then 1msps become 10-30 msps? :lol:

ddrown
Sat Apr 29, 2017 7:15 pm
I posted my sump device code here https://github.com/ddrown/stm32-sump

It’s based on stmcubemx and uses dma and a timer to sample the gpio.


aster
Sun Apr 30, 2017 9:13 pm
Pito wrote:Vincenzo, nice project!
Some ideas:
1. you can use the DWT register (32bit counter) which increments in 13.88ns period on the Maple Mini – that could be your resolution then.
It works on F407 but it is implemented on F103 as well, double check. UPDATE: It works on Maple Mini too.. Here is the code:
http://www.stm32duino.com/viewtopic.php … 234#p26692
So instead of reading micros() you read the cpu clock ticks with CpuGetTicks() in 13.88ns resolution.
2. you must not reset the timer (you cannot with DWT reg), the timer[0] carries the start point (zero point timestamp), the other duration[1] = timer[1] – timer[0], duration[2] = time[2] – time[1], etc.
3. you may wait on a “trigger event” when the input signal matches your TRIGGER_MASK, then start with sampling, for example
void startLA() {
//delay(1000);
event = 0;
digitalWrite(boardLed, HIGH); // Armed, waiting on trigger
reset_timer();

while( (initial = GPIOB->regs->IDR >> 12) != TRIGGER_MASK ) {}; // here we wait till the input signal matches the TRIGGER_MASK
state = initial;
}


dev
Sat May 06, 2017 2:29 pm
Thanks for sharing such a good work.
I have downloaded code, but i don’t see .exe file there. I am not sure how to use it without .exe. Please guide me.

aster
Sun May 07, 2017 7:05 pm
dev wrote:Thanks for sharing such a good work.
I have downloaded code, but i don’t see .exe file there. I am not sure how to use it without .exe. Please guide me.

myweb
Wed Oct 31, 2018 10:41 am
[ddrown – Sat Apr 29, 2017 7:15 pm] –
I posted my sump device code here https://github.com/ddrown/stm32-sump

It’s based on stmcubemx and uses dma and a timer to sample the gpio.

Hello,

I like the implementation, but faced with issues – no data/channels are shown in ols-0.9.7.2.
Bug is also created in git: https://github.com/ddrown/stm32-sump/issues/2

I also tried sigrok PulseView – I see data, but:

  • Timings are incorrect
  • Data is partially shown

I have “fixed” timings with the following code change:
static void setupDelay(uint32_t divider) {
if(divider >= 11 && divider < 65536) {
divider = (int) 260 * divider / 361;


Leave a Reply

Your email address will not be published. Required fields are marked *