#avr Logs

Sep 23 2019

#avr Calendar

05:58 AM JanC_ is now known as JanC
09:12 AM soreau: Hi, I'm trying to make audio device class on stm32f103c8 using https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F1/libraries/USBComposite as a base for my implementation and I have audio data getting to the host but it seemingly doesn't send data fast enough or something because in audacity it records slow and plays back about 5x as fast and pulseaudio loopback module sounds like a helicopter, playing the audio data at a high rate an
09:12 AM soreau: d then a moment of silence
09:13 AM soreau: I'm trying a control test just sending 32 bytes of silent/consistent data every 1ms urb from the host but it has the same problem as when sending real data
09:13 AM soreau: at 16000 sample rate stereo
09:16 AM soreau: trying other sample rates like 8000 and 44100 have the same problem
09:17 AM soreau: If I set 72Mhz in arduino IDE, does this mean the device is actually running at 72Mhz?
09:18 AM soreau: It just feels like stuff is happening too slow
09:20 AM soreau: I've made it this far without using any debugging techniques but it would be nice if I could use printf from the C code somehow
09:24 AM Fuchikoma: ArduinoIDE has no control over how fast the device is actually operating.
09:25 AM Fuchikoma: You just put that in so any code that relies on clock speed for timing is using the right number
09:26 AM soreau: So I might be running at 8Mhz?
09:26 AM soreau: How can I know for sure?
09:26 AM Fuchikoma: Look at the board. Does it have a crystal on it?
09:26 AM soreau: yes
09:27 AM Fuchikoma: Then it's a good starting point to assume it's running at whatever frequency that crystal is
09:27 AM soreau: so how do I make it run at 72Mhz?
09:27 AM * soreau googles
09:29 AM soreau: I guess I need to do stuff like http://amitesh-singh.github.io/stm32/2018/06/17/overclocking-blue-pills.html ?
09:30 AM Fuchikoma: Probably. This is a channel for AVR not STM32 so *shrug*
09:31 AM soreau: * Topic for #avr is: 8bit avr and stm32
09:32 AM soreau: According to RM0008 "If the USB interface is used in the application, the PLL must be programmed to output 48 or 72 MHz. This is needed to provide a 48 MHz USBCLK."
09:37 AM nohit: Fuchikoma: read the topic
09:43 AM * soreau is no closer to figuring out how to set the clock to 72Mhz
09:44 AM Strogg: you could always toggle a pin with a timer and measure the pulse width
09:49 AM soreau: Strogg: How might I do that in a sketch?
09:49 AM Strogg: a sketch?
09:49 AM soreau: My thought is instead of toggling a pin, I could just measure the time with micros() or so
09:50 AM soreau: but I don't really know how to setup the Timer
10:17 AM soreau: I just put in some code to measure how many micros elapsed in the main loop and it varies from about 50-100
10:23 AM cehteh: mhm this is #avr not #arm :) .. iirc timers are somewhat different there
10:24 AM cehteh: also, when you need constant timing then make your main loop branchless sometimes that works better, even when it costs more cycles
10:26 AM soreau: well the thing about timers that I see, is in examples I've found, TimerX.setPeriod(); is used.. so if I set the period, then it isn't telling me anything useful about the actual mcu clock speed
10:26 AM Fuchikoma: Do you have an oscilloscope?
10:26 AM Fuchikoma: 50MHz or better ideally
10:26 AM soreau: no
10:27 AM cehteh: soemwhere you set/configure the main clock speed
10:27 AM soreau: cehteh: yes I can't figure out how to do that
10:27 AM cehteh: on avr's you know the speed (by the crystal/osc you choose) and tell the runtime clib that by definin F_CPU
10:27 AM cehteh: on stm32 you have CMSIS or whatever
10:28 AM soreau: I'm using stm32duino/libmaple
10:29 AM cehteh: dunno that
10:30 AM cehteh: anyway when you get sloppy timing then it might be some bug, corner cases, integer overflows, data races, ...
10:30 AM cehteh: timer handling has some corner cases when you want to do it correctly
10:31 AM cehteh: and imo *duino* software stacks give a fuck about doing things correctly and handling/returning errors
10:32 AM soreau: yea I've seen a lot of TODO's and FIXME's
10:32 AM Fuchikoma: If you don't have a scope or logic analyzer, determining the actual clock speed is going to be nearly impossible. The arduino software makes it even worse
10:33 AM cehteh: many DMM's have frequency measurment
10:33 AM Fuchikoma: 70+MHz?
10:33 AM soreau: Fuchikoma: I've had my eye on a Rigol DS1054Z but can't afford it yet unfortunately
10:34 AM cehteh: you might be able to divide the frequency on a debug pin
10:34 AM soreau: I don't think my DMM has any such capability
10:35 AM cehteh: uint8_t counter; ..... if(!++counter) toggle_debug_pin();
10:35 AM cehteh: the counter global, the if()... in the counter overflow isr or whatever
10:36 AM Fuchikoma: And pray arduino doesn't do anything too dumb
10:36 AM cehteh: somehow you could at least get the clock out divided in some sensible way you even handle with a stopwatch
10:37 AM cehteh: anyway .. get a $12 logic analyzer, thats cheap and good
10:37 AM cehteh: ok cant handle 70mhz either, you have to divide it somehow
10:37 AM soreau: I'd rather find the code to set the clock to 72Mhz
10:37 AM Fuchikoma: mm
10:37 AM cehteh: even when you find that, thne you have to debug and confirm that it works reiably
10:38 AM cehteh: and we are programming, not copypasting, read the manual/datasheet
10:38 AM soreau: I'm not just trying random things..
10:38 AM Fuchikoma: You'll never make any progress with that attitude ;)
10:39 AM soreau: heh
10:39 AM Fuchikoma: (Seriously though sometimes just trying shit is how you solve the problem)
10:39 AM cehteh: even 'trying' is most often the wrong approach :) .. understanding is the goal
10:39 AM merethan_w: Do any of you know how the brown-out level can be changed from user code, if at all?
10:39 AM cehteh: merethan_w: nop its fused and hardcoded
10:40 AM cehteh: iirc you can turn it off from user code
10:40 AM Fuchikoma: merethan_w: What device specifically? Probably not possible but worth checking into
10:40 AM merethan_w: I found it indeed in the fuses section. But can it be changed away from the fuse configuration at runtime?
10:41 AM merethan_w: I have a xmega32E5
10:42 AM cehteh: read datasheet
10:45 AM Fuchikoma: Yeah programmable fuses only
10:49 AM merethan_w: Damnit. Due to poor programming practices at the production department, a bunch of devices were shipped without BOD set.
10:49 AM merethan_w: I hoped to fix this in firmware.
10:50 AM merethan_w: Unless thereĀ“s a trick for it (not documented in the manual, because there it lists none) I am out of luck on that one.
10:50 AM cehteh: merethan_w: do you really need BOD enabled? somtimes it can do more bad than good, needs careful evaluation
10:50 AM merethan_w: I prefer the device restarting over EEPROM going bad.
10:50 AM cehteh: do you write EEPROM that often?
10:51 AM merethan_w: Once every 15 minutes.
10:51 AM cehteh: i rather do round robin/redundant eeprom writing with checksum, then i always fin a valid config in eeprom
10:51 AM merethan_w: It is unlikely to happen just as power cuts out. But this many hours per device times that many customers.. At some point you win the lottery (already have).
10:52 AM cehteh: not alll features i wanted implemented here but i have some plans for reliable config writing (currnetl it is already reliable, but lacks some of the advanced features)
10:53 AM merethan_w: A proper redundant EEPROM setup (every page having a backup page) is in the works cehteh
10:53 AM cehteh: include checksum and generation counter
10:53 AM merethan_w: Will do, tnx
10:54 AM cehteh: then write round robin, when starting you pick the entry with the highest generation number with valid checksum
10:54 AM merethan_w: cehteh, you mean version field or write cycle counter with generation counter?
10:54 AM cehteh: just some number you increment on each write
10:54 AM merethan_w: Ah and when reading take the latest with valid checksum.
10:56 AM cehteh: struct {data ...; uint32_t gencount; uint16_t crc16; } config [N]; with N as big as possible
10:56 AM cehteh: (eeprom size/ sizeof(struct config))
10:57 AM cehteh: add smart writing and write verification and good
10:57 AM cehteh: no need for BOD for EEPROM ..
11:16 AM soreau: ok, so I just output F_CPU which the code uses to setup the clocks and it is running at 72Mhz
11:18 AM soreau: It's a shame I have audio-over-serial-bulk-transfer working decently but trying to do it correctly with isochronous transfers as audio class device is failing horribly
11:25 AM Fuchikoma: Where is the audio data coming from?
11:35 AM soreau: Fuchikoma: analogRead()
11:36 AM soreau: for testing purposes I just send same thing over and over though
11:36 AM soreau: for consistency
11:36 AM Fuchikoma: So this is raw sample data you're gathering yourself from the built in ADC
11:36 AM soreau: now I just finished timing the requests from the host and it is happening consistently at 1ms intervals on the nose
11:37 AM soreau: Fuchikoma: Yea I have some code to do that too
11:37 AM soreau: but for now I'm just using crude methods
11:38 AM soreau: but since I'm getting the requests at consistent intervals, I guess it's somehow not getting the data to the host quickly enough
11:38 AM soreau: and that's a mystery to me so far
11:38 AM Fuchikoma: Well first and foremost, you need to make sure the sample rate and bit resolution are properly defined and consistent
11:39 AM soreau: Fuchikoma: They are AFAIK, I'm sending 32 byte packets each 1ms frame, for 16000 stereo
11:39 AM soreau: but I've tried sending more or less data and it doesn't help get any closer to solving the problem
11:40 AM Fuchikoma: And you're sending this to the PC and writing it to file I guess?
11:41 AM soreau: Fuchikoma: using pulseaudio loopback module to get it to the speakers or record with audacity
11:41 AM soreau: with the loopback module it stutters like a slow helicopter and with audacity, it records slow but plays back like 5x speed
11:42 AM soreau: Fuchikoma: bit res is set to 16 and 2 packets per subframe
11:42 AM soreau: I tried adjusting maxpacketsize too and that didn't seem to help either
11:43 AM Fuchikoma: This might be a problem with the module
11:43 AM soreau: erm, 2 bytes per subframe
11:43 AM soreau: Fuchikoma: which module?
11:44 AM Fuchikoma: pulseaudio is software is it not?
11:45 AM Fuchikoma: analog audio -> your STM device (ADC) -> Serial data stream -> Some software -> analog audio
11:45 AM Fuchikoma: That's what it sounds like you're doing
11:46 AM soreau: Fuchikoma: Not serial, isochronous as audio device class
11:46 AM soreau: unless you meant it in different context
11:47 AM Fuchikoma: It's a serial stream
11:47 AM soreau: Well I have a serial implementation using CDC bulk transfers and a python program to read the data and pipe it into the audio subsystem and that works ok
11:47 AM soreau: so it *seems* like it should be fast enough
11:49 AM Fuchikoma: Try saving the raw data to file
11:49 AM soreau: Fuchikoma: Using audacity doesn't count?
11:49 AM Fuchikoma: No
11:50 AM soreau: well I'll have to read up on how to save the data manually
11:50 AM Fuchikoma: Sounds like you have data flowing all over the place. Basically you need to eliminte links in the chain to isolate where the problem is.
11:51 AM Fuchikoma: You should be able to modify the python script that takes the serial data and pipes it to the audio software, and have it piped to a file instead
11:51 AM Fuchikoma: Then you can at least compare the file to the data you *think* you're sending and see if it matches
11:52 AM Fuchikoma: If you're getting out what you're putting in, then the problem is probably downstream of the script, otherwise it's upstread of the script or the script itself
11:53 AM soreau: Fuchikoma: The python script is for my serial bulk transfer impl
11:53 AM soreau: so it reads using pyserial
11:54 AM soreau: I'd have to write something that reads from a pulseaudio source and write it to file
11:54 AM soreau: but I'd like to trust that audacity is capable enough for doing this
11:55 AM Fuchikoma: Unless pulseaudio is mangling the data before Audacity gets it
11:55 AM soreau: yea..
11:56 AM Fuchikoma: Or there's an problem with the python script and you're passing serial packet headers as audio data or someshit
11:56 AM soreau: in which case writing such a program to dump to file wouldn't help much
11:56 AM Fuchikoma: Or any number of possible issues
11:56 AM Fuchikoma: Which is why, as a general rule of debugging, you eliminate as many variables as you can.
11:57 AM Fuchikoma: You know exactly what data you're sending, right?
11:57 AM soreau: Fuchikoma: I'm not using the python script with the audio device class, it passes data using isochrnous transfer IN endpoint and shows up as an input device in pulseaudio and alsamixer
11:57 AM Fuchikoma: Like, is it a hard-coded stream of bytes?
11:57 AM soreau: Fuchikoma: Yes I am sending consistent data for testing
11:58 AM Fuchikoma: Okay
11:58 AM Fuchikoma: So on the PC end, stream that data to file
11:58 AM soreau: the nature of isochronous is that is could contain errors since there's no error checking, it just barrels on
11:58 AM soreau: but they should be marginal
11:58 AM Fuchikoma: Whatever you have to do to make that happen without using pulseaudio or audacity
11:58 AM soreau: ok so alsa
11:58 AM Fuchikoma: Eliminate all that shit from the equation
11:59 AM Fuchikoma: Just vierify that the data is making it to the PC as it should
12:01 PM soreau: It's like it gets there but it's starved for some reason so it records slow and plays back fast in audacity or stutters with the loopback module.. the bits that I can hear with the loopback module are too high pitched so it's like it gets a burst and tries to catch up
12:08 PM soreau: maybe I should just try plugging it into a different operating system and see if it has the same problem..
12:08 PM soreau: but alas, I don't have one atm
01:05 PM soreau: Fuchikoma: I used arecord and set -d 5 (duration 5 seconds) and it takes 20 seconds to record but aplay plays it in 5 seconds
01:06 PM soreau: so it seems like pulseaudio isn't at fault
03:10 PM soreau: I notice the code is using low-priority interrupts for the usb interrupt mapper but if I try to use high priority, things don't work
03:57 PM soreau: The only thing I can think is there's some bug in libmaple that ends up only sending 1/4 of the data
03:57 PM soreau: Especially since isochronous dubble buffered implementation isn't used in any example except for my code
04:27 PM soreau: I tried sending data 0-255 in succession and then the same in reverse, repeated and take a recording with arecord but viewing the file with ghex, the data portion of the file isn't at all what I expect, there are values all over the place
05:07 PM PoppaVic: https://techxplore.com/news/2019-09-recreate-d.html
05:10 PM cehteh: soreau: data race you do sometihng wrong in your program?
05:12 PM cehteh: PoppaVic: looks fragile
05:13 PM cehteh: and wheneverthis becomes available. first application will be sex toys i bet :D
05:30 PM soreau: cehteh: The host triggers an interrupt each ms and I write 32 bytes of data consistently at 16000 sample rate stereo. Each packet is (16000/1000)*2
11:57 PM day__ is now known as day