# STM32 L1 Morse Code Beacon

Since I’ve found STM32L uController series to be most amusing to play with I did some experiments that no one, not even the manufacturer himself would dare to call ‘normal’ use cases :). In this post I’m going to present you a way to turn your STM32L uC into fully-functional, transmitting actual RF signals, Morse code beacon. Beacon that could be picked up with nothing more than a standard FM Broadcast receiver (you know, the one that works in 87.5 – 108.0 MHz range).

## How to get RF out of “non-RF” chip?

Basically what we call RF is no more no less than signal with alternating voltage. The rate at which this voltage alternates is called frequency. We need to find a way to generate a signal with frequency between 87.5 and 108MHz on one of uC pins. Surprisingly this can be done in a chip that claims to operate only at much lower frequencies. All we need to do is to make proper improper use of PLL (Phase Locked Loop).

## Hardware

Well, not much going on there, all you need to have soldered is a crystal oscillator, in order to be able to use it as PLL’s source clock (HSE). To be completely honest, you don’t even need that for this chip to transmit, but when internal oscillator is used (HSI) a lot (and I mean: A LOT) of phase noise will be present at the output, and nobody likes phase noise of that magnitude. Believe me, things can get messy when your so called “transmitter” occupies 10% of total FM Broadcast Band, so please, please! use HSE, since it only adds three parts to your bill of materials (2 caps, 1 crystal) . Here’s the schematic:

## Configuration of PLL

The frequency that I chose for operation is equal to 96MHz, which is 16MHz (my crystal oscillator, HSE) times six. STM’s PLL does not support divider that is less than two, so in order to generate 96MHz we have to multiply PLL’s source clock frequency to get 192MHz. This implies multiplying by a factor of 12 (16MHz * 12 = 192MHz). Then we set divider’s value to 2. All is done with following code

	/* start hsi clock */
RCC_HSECmd(ENABLE);
/* wait till it stabilizes */
while (!RCC_GetHSEStatus());

/* configure pll to give out 96 MHz */
RCC_PLLConfig(RCC_PLLSOURCE_HSE, RCC_PLLMUL_12, RCC_PLLDIV_2);
/* start pll */
RCC_PLLCmd(ENABLE);
/* stabilize pll */
while (!RCC_GetPLLStatus());


Plain and simple. Only thing worth noticing is that we do not switch our MCU to operate on that what comes out of PLL. That would surely do us no good, since that frequency definitely exceeds IC’s capabilities.

## Routing RF out of chip’s insides

There is a nice feature that comes with STM32L series, called MCO (Microcontroller Clock Output), that can be used to provide MCU’s clock to other system components. The real nice thing about it is that it can source not only MCU’s system clock, but any other clock (like HSI, HSE, and .. PLL!) as well. Brilliant! The only drawback is that only Pin PA8 can be configured to act as MCO. Here’s the code:

/* initialize gpio structure */
GPIO_StructInit(&gpio);
/* use pin 13 */
gpio.pins = GPIO_P8;
/* mode: alternate setting */
gpio.mode = GPIO_ALT;
/* system */
gpio.af = GPIO_AF_SYSTEM;
/* output speed: 40MHz */
gpio.speed = GPIO_OS_40M;
/* apply configuration */
GPIO_Init(GPIOA, &gpio);

/* configure mco pin */
RCC_MCOConfig(RCC_MCOSOURCE_PLLCLK, RCC_MCODIV_1);


As you can see MCO has it’s own divider, but we are not using it as it would require PLL to generate even higher frequencies and I don’t find it possible. Please keep in mind that this output pin needs to be configured for highest output speed possible, which, in case of STM32L is 40MHz.

Last thing to do is to find a way to control the RF emission by enabling/disabling MCO. The best way to do it is to use bit-band mapped to PA8 MODER bit number 1 (not 0). By altering it’s value user can switch between Anlternate Function (which is MCO) and General Output which will just set pin low. Here’s the mapping, done as a global variable:

/* bit that controls rf output */
static bitband_t rf = BITBAND_PERIPH(&GPIOA->MODER, 17);


Now setting rf to 1 (0) will start (stop) generation of RF.

## Morse code generation

I’ve written a simple piece of code that generates all the dots and dashes form C string.  It uses a Look-Up Table for character generation. Every character in LUT was encoded on 8 bits in such manner that:

• bits 0-2 are used to represent number of dots and dashes that represent character. This information is required because Morse letters have variable length.
• bits 3-7 hold the actual letters representation, 1 represents a ‘dot’, 0 goes for a ‘dash’. Sequence should be processed from bit 7 to bit 3, and not the opposite. I stored it that way because it was easier for me to build up all those bits when looking at Morse Code Chart which is written from left to right, obviously.

Here’s the code of Morse code generation:

/* encoded morse letters from A to Z */
const uint8_t morse_letters[] = {
0b10000010, 0b01110100, 0b01010100, 0b01100011,
0b10000001, 0b11010100, 0b00100011, 0b11110100,
0b11000010, 0b10000100, 0b01000011, 0b10110100,
0b00000010, 0b01000010, 0b00000011, 0b10010100,
0b00100100, 0b10100011, 0b11100011, 0b00000001,
0b00100011, 0b11100100, 0b10000011, 0b01100100,
0b01000100, 0b00110100
};

/* sends morse letter */
void send_morse(char c)
{
/* get code */
uint8_t code = morse_letters[c - 'a'], i = code & 0x7;
/* process every bit of morse code */
while (i--) {
/* enable rf */
*(rf) = 1;
/* dot */
if (code & 0x80) {
simple_delay(DOT_DURATION);
/* dash */
} else {
simple_delay(DOT_DURATION * 3);
}
/* disable rf */
*(rf) = 0;
/* dot space */
simple_delay(DOT_DURATION);
/* next bit */
code = code << 1;
}
}


Since it’s only a demo I didn’t go all the way to have support for numerals, spaces, commas, periods and all that stuff. Of course if you are in need of those, feel free to modify it anyway you like.

## Outcome

A video says more than a thousand words:

In this video I am using PCB from one of my projects, but you only need to stick to what was told in “Hardware” section of this article. I’ve added some LED blinks for every dot and dash for convenience.

The software that I am using to monitor RF band is called SDR#, and I definitely recommend you getting one if you are planning to go for RF projects. It performs outstandingly well with my Realtek chip based DVB-T dongle.

# STM32 L1 Tutorial #2: Boost your code (Bit-Banding)

Today I’m going to show you how to speed things up in your code by using marvelous feature called “Bit-Banding”. Basically bit-banding is a new way of addressing (and accessing) things in some parts of your Cortex-M3 uC address space. Well, you would probably ask if there is any room for any useful improvement in such simple and straightforward thing as addressing. Actually, there is.

Remember those moments when you tried to access and change value of separate bits in registers? It always involved three operations: read-update-write. Read operation was just to copy full register value to temporary variable, update was either ‘logical AND’ or ‘logical OR’ to clear or set bit of your interest respectively, and finally a write to update register’s value. As one can see, lots of computing power is involved in such simple thing as bit’s value altering. Bit-banding removes all that overhead by giving you the possibility to access register bits as separate memory locations. Neat!

## Accessing bits as they were words!

To be able to access register bits with bit-banding programmer must locate that bit’s memory location. According to STM32L Reference Manual mapping is done by this formula:

bit_word_addr = bit_band_base + (byte_offset * 32) + (bit_number * 4)

where:

• bit_band_base – a constant that indicates which memory area you are trying to access. For SRAM bits use 0x2200 0000, for peripheral registers use 0x4200 0000.
• byte_offset – this is a byte offset of register that you are trying to access. Offset is derived from actual address minus starting address of its memory section. Example 1: byte_offset of SRAM (SRAM starts at 0x2000 0000) variable located at 0x2000 0100 is 0x2000 0100 – 0x2000 0000 = 0x0000 0100. Example 2: byte_offset of GPIOA->ODR (address: 0x4002 0014) register is 0x0002 0014, since peripheral memory section starts at 0x4000 0000.
• bit_number – just the number of bit you are trying to map. Plain and simple.

## Accessing bits as they were words! With my lib!

Using bit-banding wouldn’t be that much fun if you had to use and compute above’s formula value all the time, but hey, that’s what libraries are for. Mine does it all for you, with simple macros.

Last time (Tutorial #1) we were experimenting with GPIO pin that was used to drive LED. Let’s see how it could be done with bit-banding.

/* system entry point */
int main(void)
{
/* gpio init struct */
gpio_init_t gpio;

/* reset rcc */
RCC_DeInit();

/* enable clock to GPIOC */
RCC_AHBPeriphClockCmd(AHB_GPIOC, ENABLE);

/* initialize gpio structure */
GPIO_StructInit(&gpio);
/* use pin 13 */
gpio.pins = GPIO_P13;
/* mode: output */
gpio.mode = GPIO_OUTPUT;
/* output type: push-pull */
gpio.otype = GPIO_OT_PP;
/* apply configuration */
GPIO_Init(GPIOC, &gpio);

/* bit-band definition */
bitband_t pin = BITBAND_PERIPH(&GPIOC->ODR, 13);

/* main program loop */
for (;;) {
/* set led on */
*(pin) = 1;
/* clear led */
*(pin) = 0;
}

/* never reached */
return 0;
}


Here (line #25) we have defined variable of type bitband_t which now represents bit 13 in GPIOC ODR (Output Data Register). bitband_t is a pointer to mapped memory location, so writing/reading values is done in a ‘pointer-ish’ way, with use of ‘*’ operator.  Simple as that. Using bit-banding with SRAM bits is very similar:

	uint32_t sram_flags;
/* bit-band definition */
bitband_t sram_flags_bit_0 = BITBAND_SRAM(&sram_flags, 0);
/* change value */
for (;;) {
*(sram_flags_bit_0) = 1;
*(sram_flags_bit_0) = 0;
}


## Pros and Cons.

As it was mentioned before bit-banding speeds things up. By what factor? Well, it will probably depend on whole context, but one can easily find many different use-cases that are perfectly tailored for this technique, such as:

• Clearing Interrupt status bits – saves you some cycles during interrupt routine execution
• Fast GPIO toggling – pretty much explains itself, useful when implementing bit-banging (with ‘G’ ) interfaces
• Preemption safe bit value changing – no read-update-write, just write, good for dealing with data that is processed by interrupt routines and main program loop simultaneously.

In above’s example frequency of LED toggling with bit-banding as opposed to GPIO_SetPin(), GPIO_ClearPin() increased by over 170% (was 96kHz, is 262kHz, using Os level of GCC optimization, 1MHz MSI clock (default one)). Definitely worth the effort!

There are some situations that make the use of bit-banding not practical. Those include:

• Complex Initialization – things done only once per device’s power cycle, like GPIO inits. Using bit-banding there makes hard code hard to read and debug.
• Updating multiple bit fields in registers – many of those exist, updating those bits one-by-one may lead to unwanted (and, in some cases, even unpredictable) device’s behavior.

## Limitations

Two that I am aware of. Bit-banding is available only for SRAM and Peripheral section, so no funny business operations in FLASH. Bit-banding  accesses are only legit if done by Cortex-M3 core itself. What that means is, that you cannot use DMA transfers to bit-band memory locations.

# STM32 L1 Tutorial #1: Hello, World! (LED Blink)

Today I’m about to show you how to make any use of my version of STM32L Standard Peripheral Library (post, .zip). First order of business for everyone that starts using MCU that he never used before is to get into controlling states of MCUs General Purpose Input/Output (GPIO) pins which translates to setting the voltage high or low on those pins. This can (and will) be used to lit up a LED directly connected to leads of our STM32L. I am assuming that reader has some basic knowledge about C Programming language, because I’m not planning to describe every line in every file, but to focus on what’s important. Here’s the code that does all that magic:

/* system entry point */
int main(void)
{
/* gpio init struct */
gpio_init_t gpio;

/* reset rcc */
RCC_DeInit();

/* enable clock to GPIOC */
RCC_AHBPeriphClockCmd(AHB_GPIOC, ENABLE);

/* initialize gpio structure */
GPIO_StructInit(&gpio);
/* use pin 13 */
gpio.pins = GPIO_P13;
/* mode: output */
gpio.mode = GPIO_OUTPUT;
/* output type: push-pull */
gpio.otype = GPIO_OT_PP;
/* apply configuration */
GPIO_Init(GPIOC, &gpio);

/* main program loop */
for (;;) {
/* set led on */
GPIO_SetPins(GPIOC, GPIO_P13);
/* delay */
simple_delay(100000);
/* clear led */
GPIO_ClearPins(GPIOC, GPIO_P13);
/* delay */
simple_delay(100000);
}

/* never reached */
return 0;
}


## Preparing the MCU

First step when you are dealing with STM32L will be resetting the RCC, which is done in line #8. RCC is that little MCU fragment that is responsible for enabling/disabling clock to all other modules, such as GPIO, as well as controlling MCU clock speed. After a reset we need to bring it to a known state and that’s why we call RCC_Deinit() routine.

## Configuring GPIO

In order to be able to use GPIO port (MCU pins are grouped in ports, every port can have up to 16 pins) we need to enable it’s clock. It is a common pitfall to forget about enabling particular peripheral’s clock, so keep in mind that this should be the first step before using any of peripheral’s registers.

Since we’ve got our GPIO up and running, we need to configure the operation of pin that will drive our LED. This is accomplished with the use of gpio_init_t structure. First thing that should be done here is to reset it’s contents by calling GPIO_StructInit() which will set all fields to their default values. Why bother using this function? Well, since our struct is stored on stack (it is defined inside main() function, not as a global variable) it will contain rubbish values, because stack variables aren’t initialized just as global variables are. Several fields of that data structure have been used to define pin’s behavior:

• gpio.pins – selects which pin we are about to configure. In this case it’s pin 13.
• gpio.mode – chooses pin mode of operation, which can be input, output, alternate function (pin driven by some other peripheral) or analog (pin used by analog to digital converter), in this case, since we want to *drive* LED we need to go for GPIO_OUTPUT.
• gpio.otype – output pins can operate in two modes: push-pull (MCU can set pin high and low) or open-drain (MCU can set pin low and high-impedance). We choose push-pull mode to be able to set pin high.

After setting all the fields we need to apply this configuration to given port. My LED is connected to pin PC13, I used GPIO_Init() with the first argument set to GPIOC.

## Using GPIO pin

Now the eye-candy. I have written a simple loop (lines 25 – 34) that will turn-on and turn-off the LED just to demonstrate that this tutorial actually does something. As you can see the simplest way of altering pin output states is to use GPIO_SetPin() and GPIO_ClearPin() respectively. I have also inserted some wait-sates just so the LED doesn’t blink too fast.

## Files

• Source Code – all that you need to run this example, just compile, upload to your mcu and observe the magic!

# STM32 L1 Standard Peripheral Lib Revisited

Hello everyone! Today I thought that I might actually share my version of STM32L Standard Peripheral Library that I am using for all my projects. You would probably ask if it is any different from what ST Microelectronics already gave you. Well there are few differences which are presented below. You may also ask why bother switching to my library instead of using ST’s. The main reason for that is, that all of my projects are/will be based on this piece of code, so if you are interested in those you may want to get familiar with my lib. I plan to upload some simple examples (“Hello, World!” like, you know, for basic interfaces, GPIO, SPI, I2C, DMA…), so stay tuned and watch for updates.

## Change-list

• I’ve got rid of all that CMSIS related sources – since I’m using CodeSourcery toolchain I have no need to have those. To maintain support for all ARM related things I have created separate files like nvic.c, systick.c and so on, which are no different (in terms of usage, from programmer’s point of view, of course) from any other peripheral.
• I’ve improved code formatting, because I hate it when lines of code have more than 80 characters. That gray, vertical line (a.k.a. “margin”) in your editor exists there for a reason which is called “usability”. Whenever you try to open two source code files in, let’s say, Eclipse IDE then long lines of code can really ruin your day, because not only that you have to scroll up and down but, in addition you need to go from left to right. Bummer!
• Most of functions have the same name as in ST’s version, but some of those were altered to be more descriptive about what they really do. Nevertheless you should’n have any hard time with that.
• I made some use of bit-banding feautre in some of those functions, just to improve overall performance.
• I removed all #define #if and all that macro magic used in *.c files by ST. I find it pretty hard to debug such things.
• I removed all “asserts“, wasn’t using those anyway…

# Mighty Little FM Transmitter (part 1)

Well there is one thing that’s most annoying about laptops: their speakers. People often choose to listen to their music with headphones, but still, sitting with headphones on for a number of hours is not too comfortable nor healthy. Many of us use speaker systems but that often leads to quite a mess with all those cables and power cords.

Since I’m in possession of Phillips Music Center with integrated FM receiver I wanted to make some use out of it. In order to avoid a long piece of audio cable going on my floor from my laptop to music center itself, I thought of a device that would allow me to send my audio signal in a wireless manner. Here is the whole story how this simple idea materialized.

## Step One: Concept.

To make this device functional it had to satisfy following requirements:

• Ability to transmit high quality audio signal in FM Broadcast Band (stereo, high bandwidth, etc.)
• Implement USB Audio Sound Card (driver-less solution) to get all the audio from my laptop, so that additional stereo jack connection wouldn’t be necessary.
• Power the whole system from USB port (again – no additional cables)
• Optional: Implement FM receiver, so that I could send audio from one PC to another
• Support as many different architectures/OSes/etc. as possible
• Implement an easy way to modify parameters (such as transmit frequency) over USB (single interface to rule it all)

## Step Two: Choosing the right components for the job.

… a.k.a choosing the obvious. Implementing whole FM circuitry all by myself would be pointless and painful (to say the least). The overall outcome in terms of performance would be doubtful, so I decided to choose a single IC solution that integrates all that I needed: Si4721, from Silicon Labs. Just a single glance at it’s datasheet and you know you’ve scored a home-run.

What about MCU? Well, considering my stock, again – I chose the obvious candidate for the job: STM32L151, from ST Microelectronics. I have couple of those as leftovers from my previous projects. It embeds all that is needed to make a perfect ‘heart’ of entire system and I really like working with ST MCUs

I also decided to design and implement a simple RF Power Amplifier just to pump up the output antenna swing a little bit, mainly because I’m about to use short monopole antenna, known as ‘the wire’ Using full size monopole antenna for FM Band would be a project-killer IMHO (75 cm of wire sticking out of my USB dongle? no thanks, maybe another time..)

Additional parts included: some LDO that will be capable of powering all ICs and PA as well, LEDs just to notify the user of current mode of operation, USB state, etc.., passive components, blah blah…

Stay tuned for more !