rst
Posts: 411
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 8:35 am

To comeback on this once again:
Gavinmc42 wrote:
Thu Sep 12, 2019 1:02 am
Arduino is C++, but I use them to make apps.
There is a difference between using tools and being able to write them.
I see myself more as a baremetal tool user than a tool maker.
That's why some of my ideas are ease of user based, not maker.
It's like driving a car, not making one every time I need to go to the shops ;)
That's OK. I understand your position. There have been attempts for an Arduino integration using Circle. But I think it's not possible to develop and maintain this together with a (basically) one-man-project like Circle without a quality drop. That's why I decided myself against it. So one still need some understanding of classes for writing apps using Circle. ;)
From reading the forum you have now got Circle++ to a level that people can use for their apps.
You deserve a medal.
Thanks. But for a "correct" history I have to note, that there were already remarkable apps in 2015 using Circle. The first that I know of was an emulator for a retro computer from South Korea. In 2016 came a ArtNet-DMX gateway, which was used in real stage performances. In the meantime there are several apps.

rst
Posts: 411
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 8:45 am

MikeDB wrote:
Sat Sep 14, 2019 9:33 am
I'm aiming for Ethernet, USB & HDMI as Linux only and everything on the 40 pin extender as bare metal.
I forgot to mention, that Circle is able to do Ethernet, USB & HDMI on its own. So maybe Linux is not needed. But of course it depends on what you want to do with it. Linux and Circle together is probably not a good idea, because the startup procedure of Circle does not fit into Linux and Circle wants to take over the interrupt system and memory management for any application, which makes sense.

MikeDB
Posts: 108
Joined: Sun Oct 12, 2014 8:27 am

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 10:48 am

rst wrote:
Sun Sep 15, 2019 8:45 am
MikeDB wrote:
Sat Sep 14, 2019 9:33 am
I'm aiming for Ethernet, USB & HDMI as Linux only and everything on the 40 pin extender as bare metal.
I forgot to mention, that Circle is able to do Ethernet, USB & HDMI on its own. So maybe Linux is not needed. But of course it depends on what you want to do with it. Linux and Circle together is probably not a good idea, because the startup procedure of Circle does not fit into Linux and Circle wants to take over the interrupt system and memory management for any application, which makes sense.
Yes that's moreorless where I got to yesterday :-)

It's a live audio project so I need proper real-time (not pseudo-real time using large DMA buffers like ALSA) and Circle seemed to be one of the few with decent I2S drivers I could use as a base rather than a 'to be implemented' notice. But Linux gives me WiFi, USB, etc in a hassle free way. So maybe I need to just use some of the drivers from Circle without actually using Circle itself.

Altertnatively I may use a Pi Zero W for Linux and Pi4 for the audio using Circle and connect the two with SPI which would double the audio DSP available.
Please write out 100 times "Linux is not a real time operating system so I will not suggest it is"

rst
Posts: 411
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 3:12 pm

MikeDB wrote:
Sun Sep 15, 2019 10:48 am
It's a live audio project so I need proper real-time (not pseudo-real time using large DMA buffers like ALSA) and Circle seemed to be one of the few with decent I2S drivers I could use as a base rather than a 'to be implemented' notice. But Linux gives me WiFi, USB, etc in a hassle free way. So maybe I need to just use some of the drivers from Circle without actually using Circle itself.
I heard more than once, that the audio latency in Linux was the reason to try Circle. Unfortunately I cannot offer WiFi and yes, USB in Circle has not the features and quality of the Linux drivers. The I2S driver model in Circle is relatively simple. There are two concatenated DMA buffers of configurable size, one is filled by the the application, while the other is written out to the I2S device. I guess, it's possible to adapt this in Linux.
Altertnatively I may use a Pi Zero W for Linux and Pi4 for the audio using Circle and connect the two with SPI which would double the audio DSP available.
If you are familiar with NEON programming, you will get much processing power. I programmed a virtual analog synthesizer with Circle by myself, which supports 24 polyphonic voices (6 per core), but without explicit NEON programming and probably not in a very efficient way. I heard others have reached over 100 voices.

MikeDB
Posts: 108
Joined: Sun Oct 12, 2014 8:27 am

Re: Circle - C++ bare metal environment (with USB)

Sun Sep 15, 2019 6:05 pm

rst wrote:
Sun Sep 15, 2019 3:12 pm
If you are familiar with NEON programming, you will get much processing power. I programmed a virtual analog synthesizer with Circle by myself, which supports 24 polyphonic voices (6 per core), but without explicit NEON programming and probably not in a very efficient way. I heard others have reached over 100 voices.
Interesting idea - I'll take a look at that.
Please write out 100 times "Linux is not a real time operating system so I will not suggest it is"

MikeDB
Posts: 108
Joined: Sun Oct 12, 2014 8:27 am

Re: Circle - C++ bare metal environment (with USB)

Mon Sep 16, 2019 10:35 am

MikeDB wrote:
Sun Sep 15, 2019 6:05 pm
rst wrote:
Sun Sep 15, 2019 3:12 pm
If you are familiar with NEON programming, you will get much processing power. I programmed a virtual analog synthesizer with Circle by myself, which supports 24 polyphonic voices (6 per core), but without explicit NEON programming and probably not in a very efficient way. I heard others have reached over 100 voices.
Interesting idea - I'll take a look at that.
Okay I had a look. Unlike Intel, it's only 128 bits so you can only do two 64 bit integer operations per cycle, and there's an overhead in moving from normal registers to the NEON ones and back. And with constantly changing multiply coefficients having to come from the main processor I suspect it won't help in the central DSP funtion, but there may be tasks I can offload to it.
Please write out 100 times "Linux is not a real time operating system so I will not suggest it is"

rst
Posts: 411
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Mon Sep 16, 2019 11:02 am

MikeDB wrote:
Mon Sep 16, 2019 10:35 am
Okay I had a look. Unlike Intel, it's only 128 bits so you can only do two 64 bit integer operations per cycle, and there's an overhead in moving from normal registers to the NEON ones and back. And with constantly changing multiply coefficients having to come from the main processor I suspect it won't help in the central DSP funtion, but there may be tasks I can offload to it.
OK. Good to know.

kryptonaut
Posts: 3
Joined: Fri Nov 01, 2019 2:13 pm

Re: Circle - C++ bare metal environment (with USB)

Fri Nov 01, 2019 2:38 pm

Hi - I've been developing with Circle for a few months now. First off, thank you so much for providing this fantastic library! The sample projects are a great starting point, and there is clearly so much work that's gone into creating Circle.

Now, the problem. I apologise if this is the wrong forum for this, but it seemed a good place to get in contact.

I have a fairly large project, and all of a sudden I found that adding member variables to my main class was causing a 'stackdump' crash on bootup. The nature of the crash varied depending on where in my class definition I added the variable, which pointed to a memory overwrite issue. Luckily my project included a display device so I could add some debug output, and it appeared that the crash was happening in kernel.cpp within m_Logger.Initialize when it called CMachineInfo::GetMachineName

Further digging revealed that the m_MachineModel variable was being overwritten during the initialisation of one of my member variables, and on investigating this I discovered that the 'this' pointer of my member variable (which was declared as a regular object, not using 'new') overlapped the s_pThis value in machineinfo.cpp - that is to say the two objects were sharing the same memory location. Initialising my object was messing up the data in the MachineInfo object.

I discovered where the single CMachineInfo object was created in sysinit.cpp - but unfortunately I don't have a clear understanding of how the memory allocation and initialisation works. However, moving the definition of the MachineInfo object to the end of the file, outside the sysinit() function, seemed to resolve the problem. At least the CMachineInfo::s_pThis now contains a much lower address which does not clash with my object.

Can you confirm whether this solution seems reasonable?

Sorry for the complicated explanation, but I wanted to give as much info as possible!

rst
Posts: 411
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Fri Nov 01, 2019 8:25 pm

@kryptonaut Thanks for using and appreciating Circle.

The problem, you have described, seems to be a strange one to me and I guess, the solution to define the CMachineInfo object in lib/sysinit.cpp static (outside of a function) does only work by luck.

Unfortunately it's difficult to imagine, what happens there. Is it possible to provide some (maybe reduced) version of your source code, which shows this problem, so that I can have a look at it and maybe debug it? You can also write a personal Email to me, if you want. My Email address is noted in the header of most Circle source code files.

kryptonaut
Posts: 3
Joined: Fri Nov 01, 2019 2:13 pm

Re: Circle - C++ bare metal environment (with USB)

Sat Nov 02, 2019 11:29 am

@rst Thanks for your reply - I will try to create a simple demonstration of the issue and then I'll get in touch by email.

kryptonaut
Posts: 3
Joined: Fri Nov 01, 2019 2:13 pm

Re: Circle - C++ bare metal environment (with USB)

Mon Nov 04, 2019 4:14 pm

For the record, the bug of course turned out to be my fault - I should have been doing a 'make clean' when changing my header file. Doing a simple 'make' resulted in the kernel having an incorrect size for my class definition, which was the reason for memory being overwritten.

Many thanks to Rene for the quick response pointing this out to me.

styro
Posts: 6
Joined: Tue Nov 10, 2015 8:37 pm

Re: Circle - C++ bare metal environment (with USB)

Mon Nov 18, 2019 9:18 pm

Hello,
As i mentioned in an other post i am porting the PreenFM2-Synth to baremetal RaspberryPi with the Circle-Framework,
and so far it seems to work! its really ugly but if anybody wants to try it out: https://github.com/styro2000/RasPreenFM2/

Now am am trying to optimize things to get an better latency and was lowering the CHUNKSIZE to 32 @ 48k for the CI2SSoundBaseDevice and then it seems that the GetChunk doesent get called anymore... What could be the problem?
CHUNKSIZE 64 @ 96k works great for low latency but uses unnecessary power.

Anyway, many thanks for this great Framework!
btw I have the impression that many users of Circle are interested in synthesizerstuff, perhaps it would be nice to have
a sort of meetingpoint.

pik33
Posts: 183
Joined: Thu Sep 10, 2015 4:26 pm

Re: Circle - C++ bare metal environment (with USB)

Tue Nov 19, 2019 7:35 am

styro wrote:
Mon Nov 18, 2019 9:18 pm
Hello,
As i mentioned in an other post i am porting the PreenFM2-Synth to baremetal RaspberryPi with the Circle-Framework,
and so far it seems to work! its really ugly but if anybody wants to try it out: https://github.com/styro2000/RasPreenFM2/

Now am am trying to optimize things to get an better latency and was lowering the CHUNKSIZE to 32 @ 48k for the CI2SSoundBaseDevice and then it seems that the GetChunk doesent get called anymore... What could be the problem?
CHUNKSIZE 64 @ 96k works great for low latency but uses unnecessary power.

Anyway, many thanks for this great Framework!
btw I have the impression that many users of Circle are interested in synthesizerstuff, perhaps it would be nice to have
a sort of meetingpoint.
I am not using (yet) the Circle but it seems to be only baremetal environment running on RPi4, so... if there will be no Ultibo for RPi4 in a near future, maybe I will start to use it - I am interested in audio synthesis using baremetal RPi and RPi 3 is too slow for the thing I started some time ago on PC: https://github.com/pik33/20180824-retro-fm.

For bare metal RPi3 programming I use Ultibo which has no audio driver so I had to write one. The driver is simple enough to be converted to C/C++ and has no dependencies so it can be used outside of Ultibo environment. The source is here: https://github.com/pik33/SimpleAudio
This driver uses 8-bit PWM at 960 kHz sample rate and it has a noise shaper, which gives very good audio quality. The sample rate can be seet freely (quantized, 250 MHz divided by a const) from 8 to 960 kHz
This is low latency driver: as it uses simplified DMA, the maximum buffer length for 44100 Hz sample rate is 384 samples which is about 8 ms of audio data

rst
Posts: 411
Joined: Sat Apr 20, 2013 6:42 pm
Location: Germany

Re: Circle - C++ bare metal environment (with USB)

Tue Nov 19, 2019 9:08 am

Thanks, @styro! Good to see you are making progress with your PreenFM2-Synth port.

I did not test CI2SSoundBaseDevice with that small chunk sizes, but I guess, if you want to use a chunk size of 32 for small latency, you have to decrease the "TX Request Level" in the "DREQ_A" register of the PCM / I2S block like that:

Code: Select all

diff --git a/lib/i2ssoundbasedevice.cpp b/lib/i2ssoundbasedevice.cpp
index 75114ae..43bc78a 100644
--- a/lib/i2ssoundbasedevice.cpp
+++ b/lib/i2ssoundbasedevice.cpp
@@ -71,6 +71,9 @@
 #define TXC_A_CH2POS__SHIFT	4
 #define TXC_A_CH2WID__SHIFT	0
 
+#define DREQ_A_TX__SHIFT	8
+#define DREQ_A_TX__MASK		(0x7F << 8)
+
 //
 // DMA controller
 //
@@ -263,6 +266,8 @@ boolean CI2SSoundBaseDevice::Start (void)
 
 	// enable I2S DMA operation
 	PeripheralEntry ();
+	write32 (ARM_PCM_DREQ_A,   (read32 (ARM_PCM_DREQ_A) & ~DREQ_A_TX__MASK)
+				 | (0x18 << DREQ_A_TX__SHIFT));
 	write32 (ARM_PCM_CS_A, read32 (ARM_PCM_CS_A) | CS_A_DMAEN);
 	PeripheralExit ();
 
See page 134 of this document for a description of the "DREQ_A" register.

I think, the current meeting point for Circle stuff is in this forum. The message frequency has been relatively low so far, so I'm not sure, if a separate discussion platform does make sense.

BTW. Circle issues should be reported here.

styro
Posts: 6
Joined: Tue Nov 10, 2015 8:37 pm

Re: Circle - C++ bare metal environment (with USB)

Tue Nov 19, 2019 7:00 pm

Hallo rst!
Many thanks, it worked, CHUNKSIZE 32 @ 48kHz!
the calculation of 8Voices with 6 Operators take about 47uS and so it seems that there are even some cycles left for more fun stuff! :-)

Many thanks for Your Work & Help!
all the best
styro2000

Return to “Bare metal, Assembly language”