From Note to self
Jump to: navigation, search



Written down thoughts

Looking at the f1rmware of the rad1o, I must say that it is either poorly documented or I fail to find the documentation. I looked at the different apps, esp. rfapp, to see how to make one myself.

There is a menu system that has an auto-generated part, in the form of the file main.gen. How it works is undocumented afaik, so I need to look at the implementation. (see the mkfirmware.pl section)


(This is mainly the result of reading the code, and may contain errors).

This script parses source code to extract init, tick and menu entries.

If a function is preceded with //#MENU parentmenu? menu, the next function definition will be used as a handler function for that menu entry (parentmenu is optional).

Any function starting with the name init_ or tick_ will be remembered and called from a function generated_init or generated_tick, respectively.

One example where this is used is campapp/rgb_leds. The function generated_init in main.gen contains these lines:

inline void generated_init(void) {

Right after calling the generated_init() function from main, nick_init() is called again, defeating the purpose of doing it automatically. Apparently having these undocumented features causes predictable outcomes ;-).

Also, some other init functions are called explicitly from the main function, like inputInit(), fsInit(), lcdInit(), ... Some init functions will probably need to be called in a specific order, a functionality that the generated_init code does not provide (it does sort them alphabetically, but using that is probably wicked and unmaintainable).


(This is mainly the result of reading the code, and may contain errors).


The headphone output is connected to the DAC of the mcu (schematic p.9), pin ADC0_0, 2.3B (multiplexed with the DAC). Microphone input is connected to ADC0_7/1.2C. There is an amplifier that can be enabled and disabled from software (MIC_AMP_DISABLE/1.2B). This one pin controls both the microphone and headphone amplifier. The dac has a 10 bit resolution and a max conversion rate of 400kHz or 1MHz (depending on the settling time configuration).


There is an audio library implementation at rad1olib/audio.c. Some things that I find weird:

  • Volume is 0-9, but it is calculated as out = in * (vol&7) >> 2; If the volume is 9, amp is turned on. This implies that volume 8 means no volume? Will need to test this. (Update: tested, bug indeed)
  • The range for the samples is not documented
  • The type for the audio samples is unsigned
  • this is how the dac value is determined: dac_set((audio[audio_pos] * (audio_volume & 7)) >> 2);
  • 585*7/4 is 1023 (actually 1023.75) (This is not weird, it is basic math, but I just want to say it's a weird limit).
  • Changing the output volume will affect the microphone amplifier.

Random pieces of knowledge:

  • The init function requires a ritimer clock rate. This is a counter running at BASE_M4_CLOCK rate.

FM Receive

Trying to make a FM receiver with the rad1o. The portapack code is not working as is (no big surprise there).

I Started with the spectrum example and tried to adapt it so that it does WBFM rx. What I got is just a ton of noise...

  • I don't know the range of the output samples of the FM demodulator. I tried adding debug min/max variables, and I get something like -70 to 1. (yesterday -30 to 60).
  • The noise does not really seem to be influenced by the volume, but if I turn it to 0, there is no more sound. The sound seems rather loud for such a small input range.
  • portapack_init() calls systick_set_clocksource(uint8_t). I think it lowers the systick rate 8 times, which I had already noticed with the getTimer() function (I estimated that it went 10 times slower).
  • I have no idea why it needs the systick to be slowed down.