Capabilities

Materials

- Steel and stainless steel
- Aluminium
- Titanium
- Composites
- Plastics

3D CAD Design

- 3D modelling
- Photo realistic rendering
- Joint design
- Design optimisation

Analysis

- Hand analysis
- FE analysis
- Fatigue analysis

Systems Engineering

- Specifications
- Requirements
- Testing & verification
- Documentation

IP Protection

- Patent process
- Prior art
- Costs and benefits

 

Flashing ARM Micro using ST Discovery board as a programmer

This guide shows how to program an ARM micro controller using a ST Discovery board as the programmer. The best thing is that this even works in Linux with a graphical user interface. Therefore this is currently my preferred way to flash my Keil board.

There are off course dedicated USB – JTAG programmers available. Keil sells one which works well with their (commercial) Windows only development environment. If you write your code in Linux there is the ARM-USB-OCD from Olimex. I believe this can be set up to work in Eclipse but otherwise I think there is only a command line interface which is pretty painful.

A really cheap and hassle free way to program a board is to just use a ST discovery board as the programmer.

  1. Install qstlink2 from here. It is licensed under GNU GPL v3.
  2. Remove the two jumpers from the discovery board to disable programming of the processor on the discovery board (ST-Link setting). Instead the signals are available on the SWD header.
    1. SWD pin 1 not connected
    2. SWD pin 2 (SWCLK) to JTAG pin 9 (TCLK)
    3. SWD pin 3 (GND) to any JTAG GND pin
    4. SWD pin 4 (SWDIO) to JTAG pin 7 (TMS)
    5. SWD pin 5 (NRST) to JTAG pin 15 (RESET)
    6. SWD pin 6 (SWO) to JTAG pin 13 (TDO)
  3. Connect the signals on the SWD header to the following JTAG signals:
  4. Plug the discovery board programming interface into your host machine’s USB port.
  5. Power up your development board and the discovery board.
  6. Open the qstlink2 program, click connect and upload and download your software as required.

That’s it. Cost effective micro controller programming in Linux with graphical user interface. Dreams come true!

ARM Microcontroller bare metal programming

This is article summarises some of my experiences programming ARM Cortex M3 and M4 microcontrollers without an operating system. This guide is intended for the beginner, probably with some C programming experience.

Why bare metal and not use an operating system?

 

In my opinion bare metal programming is slightly more basic. The advantage is that you “only” have to learn how the microcontroller works. If you use an operating system some of the microcontroller issues are hidden but instead you have to figure out how the operating system works. If you want to do something that is not enabled by the operating system then you have to go back to understanding the processor as well. At this stage the operating system route becomes very complex. I would say that after you figured out the processor it is much easier to figure out how to fix an operating system and add features. I would therefore start with bare metal programming.

I would say you exceed the limits of bare metal programming if you require a file system to read an SD card or if you need a wired internet connection. USB is also very complex. If you need these features a real time operating system with these features built in would make sense. It is possible to implement Ethernet without an operating system but this is definitely beyond the beginner.

 

Select your tools

If you have never played around with Linux and don’t know what a makefile is then I would start with a commercial development board and software package. Have a look on the ST, Keil, IAR, Hitex and Raisonance websites. Be aware that in some cases you have to buy an additional debugger to transfer the compiled code from your computer onto the development board. Other boards have the debugger built in. For basic programming the free version of the software kits is good enough. It will be a while until you reach the code size limit.

 

With these kits you should be able to have the example programs running in minutes. Load the example, compile and load (flash) the binary file onto the development board. If you decide to use a ST board you will have to use one of the other development programs since ST doesn’t provide one. ST does provide a lot of examples which are tailored to the Keil, IAR and other software tools.

 

If you do have Linux experience I would use open source tools. As a minimum you will have to install a GCC cross compiling tool chain and some sort of software to flash the microcontroller. I’m using the Mentor Graphics Sourcery CodeBench Lite edition. There is also YAGARTO (yet another GNU ARM toolchain). I would also download the Olimex OpenOCD_OnlinePackage. It contains makefiles, linker scripts, startup code and peripheral libraries. It also comes with examples. If everything has been set up correctly you only have to type “make” at the command line and the sample projects should compile.

 

Once this is all working you can also install the ECLIPSE software development kit. It is state of the art but will take some effort to set up. It is entirely possible to edit the source files with a regular text editor.

Basic structure of a program

What do you actually have to do to the micro controller so that these programs run? As a first step you will have to download the reference manual for your processor from the net and the schematic of your board. The reference manual is usually lengthy (around 1000 or more pages) and describes every peripheral of the processor in detail. Don’t worry. You don’t have to read it all. You only have to get your head around the peripherals you are using. If you can’t find the manual don’t use the processor. Some of them require a NDA or don’t describe the features of the processor fully. This is not a problem with lower power processors which are very well documented.

All processor level programming is done by setting bits in registers to 0 or 1. For example the following line sets the control register of Port D to 0x44BB44BB or 1000100101110110100010010111011.

 

GPIOD->CRL = 0x44BB44BB;

 

The reference manual will tell you what this means.

 

Most of this setting up is done using hexadecimal numbers. I often use a calculator to convert hex to binary or the other way round. The standard Windows calculator has a useful “Programmer” mode for this. After a while you will be an expert at converting binary to hex and back.

 

Quite often you will see operators like |=, &=, ^= or << when assigning values to registers. They are usually used when there are already values written to the register but the register has to be modified. How do they work?

 

|= is a bitwise or assignment and is usually used to set bits (set them to 1). For example if previously  0x44BB44BB has been written to the Port D control register and one would like to set bit two without changing all the other bits one would write:

 

GPIOD->CRL | = 0x00000004;

 

After this operation the register value would be 1000100101110110100010010111111.

 

Another way of achieving this is to use the left shift operator to shift a 1 to bit position 2. This is done the following way:

 

GPIOD->CRL | = (1 << 2);

 

&= is the bitwise and assignment and used to clear bits. To change bit two back to 0 without changing any other bit one would write:

 

GPIOD->CRL & = 0xFFFFFFFB;

 

Type these hex numbers into a calculator and convert them to binary. You will quickly understand what is happening.

 

^= is the exclusive or assignment and used to toggle bits. If the bits were on they are switched off and if they were off they are switched on. If one was sure that bit two of the Port D control register is currently 1 but it has to be switched off one could write:

 

GPIOD->CRL ^= 0x00000004;

 

Now that we know how to modify registers we can look at what a regular program actually does.

 

Below are the basic steps required in order for programs to run. It is all very basic low level stuff far removed from higher level programming.

 

 

 Set up the clock tree

Every microcontroller needs a clock and this has to be set up. There are usually different clock sources, clock paths, clock dividers and multipliers. Usually the processor is clocked from a higher precision external crystal in run mode.

 

The good thing is that the clocks are usually set up by a standard system file which comes with the examples. As long as you include the standard system file in your code the clocks should work. You still have to find out what the frequency of certain peripheral clocks is if you want to program the correct baud rate for a serial port for example. Therefore I would go through the system file, find out how the clock signal is routed and what the resulting frequencies are.

 

2.      Set up pin multiplexing

Most processor pins can be used for more than one function. For example one pin might be used as a CAN bus data line or a USB data line depending on to which peripheral the pin is connected. You have to consult the schematic and the reference manual to find out if the particular peripheral is used with the default pins or re-mapped to other pins. Sometimes there is more than one re-map option.

 

3.      Set up the pin mode

Every pin has to be configured as input, output or analogue. Again the reference manual should tell you what the requirements of the particular peripheral pin are and how to configure the pin correctly.

 

4.      Enable the clock

In order to use a pin the clock of the particular port, the peripheral clock and if required the alternate function clock has to be enabled.

 

At this stage the pin should be able to send or receive signals and the signals should be routed inside the processor to the correct peripheral.

 

5.      Set up the peripheral

Most of the peripheral systems have multiple configuration options as well. The options have to be enabled or disabled as required. Again this is done by writing bits into control registers. The reference manual will give details.

 

At this stage your peripheral should be able to send and receive data. For example to send an ‘A’ (hex code 0x41) over serial port 1 one would write something like:

 

USART1->DR = 0x0041;  

 

 

Standard Libraries

The processor and peripheral set up can be done by standard libraries written especially for the particular processor. If you are choosing a processor download the available libraries first to see what is available. The better the libraries are, the easier it is to develop software. With libraries you don’t have to worry about writing to special registers. This is done by the functions in the library. For example the code below sets the options for USART1 which is equivalent to step 5 above.

 

USART_InitStructure.USART_BaudRate = 115200;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 

USART_Init(USART1, &USART_InitStructure);

 

It is still important to know what is going on here so understanding the above steps is essential even if it is painful.

 

With this knowledge you should be able to write workable software where most of the work is carried out in a big, endless loop. To receive data over a serial port there would be an ‘if’ statement that checks if data has been received. If there is data this data is processed. After the data has been processed a button is checked for its status for example. All this happens in a big loop.

 

Advanced Functions

Big loops quickly get out of control and there might be large delays due to the amount of processing that is going on. For example if the loop is too big data from the serial port might be missed because the characters arrive at a higher frequency than the frequency of the loop. The frequency of the loop might also change depending on the work that is done. So this is not a very reliable way to program a microcontroller. This brings us to advanced functions.

 

Interrupts

In most cases the endless loop can be completely empty if interrupts are used. The main function does nothing at all.

 

Interrupts are triggered if certain conditions are met (button is pressed, character arrives on serial port). If an interrupt is triggered a special function is executed depending on the priority of the interrupt. If two interrupts are triggered at the same time the one with the higher priority is dealt with first.

 

The interrupt handler function is usually quite short and very descriptive. Complex programs can have multiple interrupts. All “work” is carried out in these interrupt handler functions. Below is an example for a serial port byte received interrupt.

 

void USART2_IRQHandler(void)

{

  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)

  {

    /* Read one byte from the receive data register */

    RxBuffer[RxCounter++] = USART_ReceiveData(USART2);

 

    if(RxCounter == NbrOfDataToRead)

    {

      /* Disable the USART2 Receive interrupt */

      USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);

    }

  }

}

 

Interrupts can be triggered by peripherals (data received, transmit register empty, error…), external lines (buttons) or software.

To use interrupts the interrupt controller channel has to be enabled. Usually one doesn’t have to change the priority from the default priority. If all interrupts have the same priority they are executed in the order they are received. It gets complicated if you would like to stop execution of an interrupt routine if a higher priority interrupt has been received.

 

In the peripheral control register the “enable interrupt” flag also has to be set. After that the function which is defined in the startup file is executed whenever an interrupt has been received.

 

DMA

DMA stands for direct memory access. It is very useful for transferring data without loading the processor.

Imagine you want to transfer 50 characters over a serial port. First you would have to check if the transmit register is empty. If it is empty the next character is copied into the register until all characters have been transmitted.

Without a “transmit data register empty” interrupt the processor would be busy transmitting these 50 characters from the start of the transmission to the end of the transmission. This would be a great waste of resources because most of the time the processor is waiting for the transmit register to be empty.

 

Using an interrupt is a much better option. The “transmit data register empty” interrupt would be executed 50 times. Between interrupts the processor could do other jobs because no waiting for an empty register is required.

 

The best way to transmit those 50 characters would be to use a DMA. The DMA would automatically transfer the next character from memory to the transmit register whenever the transmit register is empty. To use the DMA one would have to do the following steps:

 

1.      Set up the source address for the DMA (the address of the first character to transmit)

2.      Set up the destination address for the DMA (address of the serial port data register)

3.      The number of characters to transmit

4.      Some DMA options. In this case the source address would be automatically incremented after each character transmission and it might be useful to enable an interrupt after the DMA has finished transferring the data. In the interrupt routine the DMA is switched off.

5.      Switch on the DMA

6.      Enable serial port DMA transmission

 

After the DMA has been set up the processor has nothing to do until the DMA has finished at which stage the DMA is switched off by the interrupt routine. The processor could do other jobs during the whole period of the transmission. We are almost multi-tasking!

 

One of the dangers of using a DMA is that it would be possible to change the transmit buffer contents (source data) while the DMA is transmitting from it. This would obviously lead to corrupted data being transmitted. Therefore before writing to the transmit buffer check if the DMA is enabled or not!

 

Bit Banding

Bit banding maps a complete word (32 bits) to a single bit in the bit band region. On the Cortex M3 processor the bit band region covers the whole SRAM.

 

So what is this good for? It significantly speeds up and simplifies checking for set bits and manipulating single bits. In the Port D control register example we had to use bitwise assignments and operators to modify bit 2. Instead one could just write 0 or 1 to the mapped word address.

To set this up one would first define the variable and the word address which is mapped to the particular bit of interest. For example the DMA1 channel 6 enable bit is mapped to address 0x42400FEC.

 

#define DMA1CH6_EN         ((DMA1CH6_EN_Type *)   0x42400FEC)

 

To enable the DMA one would simply program

 

DMA1CH6_EN = 1;

 

To disable the DMA the code is

 

DMA1CH6_EN = 0;

 

Often there are horrible if statements like this one which checks if a certain bit is set or not. In this case it checks of the CAN1 transmit mailbox 0 is empty.

 

if ((CAN1->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)

 

With bit banding this could be changed to

 

if (CAN1_TSR_TME0 == 1)

How to make your own circuit boards

If you are toying with electronics you might want, at some stage, design your own circuit board. It is not very difficult. There are a lot of schematics available which could be used as the basis of a custom board.

This guide summarises my experience with different tools and methods. There are a lot of other tools available and probably better ways to come to the end result.

Step 1: Choose your PCB design software

PCB design software is used to draw the schematics, lay out the components on a board and to create the manufacturing files. I only looked at two free software packages. I personally decided to use KiCad.

Eagle

This is a very popular software package and runs on Windows, Linux and OS X. I think it is easier to use than KiCad but the free version is limited to one schematic sheet, 100mm x 80mm board and two copper layers. For these reasons I dismissed Eagle. If you can live with these limitations Eagle is probably the quickest to learn.


KiCad

KiCad also runs on Windows, Linux and OS X and is open source. It does not have the Eagle limitations and is definitely useful for quite complex boards. It also comes with a viewer for manufacturing files and a 3D viewer for your board provided you created the 3D footprints for all components first. The 3D viewing function is still a bit difficult to use but quite useful. You can for example export a 3D file of your board and import it into 3D cad software to design your custom case.

Compared to Eagle, KiCad is slightly more difficult to use. Some people don't like the fact that for example the schematic symbol is not liked to a component footprint. Once the schematic has been drawn you have to assign a footprint to each part. The advantage is that in order to change a footprint, for examples from a through-hole resistor to a SMD resistor, no changes to the schematic are required.

Step 2: Design your board

I don't want to go into details how to design circuit boards. The basic steps are:

  • draw schematic
  • assign footprints to parts
  • lay-out the board and route signals
  • create the manufacturing files

One of the bigger issues for the hobbyist is the footprint selection. Most people probably have soldered through-hole components. These days it is quite difficult to obtain integrated circuits in through-hole packages and therefore I would think it is pretty much mandatory to used SMD parts. The big question is how small can you go?

I had no problems assembling boards with 0402 (1mm x 0.5mm) resistors and ICs with 0.65mm pin spacing. These are very tiny parts. With 0.65mm pin spacing you are likely to get solder bridges across pins. This is easily fixed with de-soldering braid. At 1.27mm pin spacing solder bridges are unlikely.

Thermal pads on the back of the IC are no problem. I haven't used BGA packages yet but I like the idea of using them. The big problem with home soldering is to apply the correct amount of solder paste. With BGA packages the solder is already on the IC in form of small balls. Therefore this critical step is already taken care of and the only issues left are part placement and the correct reflow temperature profile. Although once soldered it is impossible to inspect the connections since they are under the chip.

The output of your design effort should be the following Gerber files (for a two layer board):

  • Top silk screen layer. This is the visible artwork on the top of the board. The layer is optional but recommended to reduce part placement errors.
  • Top solder mask. The board manufacturer will apply a solder mask according to the data in this layer. You can solder anywhere where there is no solder mask. I make the solder mask exactly the same size as the pads.
  • Top copper layer.
  • Bottom copper layer.
  • Bottom solder mask. On singe sided boards there should only be bare areas around through-hole pins.
  • Bottom silk screen layer. This layer is usually not required unless you intend to place parts on the bottom of the board which is not recommended for home manufactured boards.
  • PCB outline file. This layer should contain the outline of the board and any large holes or slots that are CNC routed.
  • Drill file. This file contains the location and diameter for all drilled holes for through-hole components and vias.

Step 3: Make the board

There are different options and manufacturers to get your board made. I used PCBCART and had very good results. You basically fill out an online form which defines your PCB and you get a quote straight away. If you decide to go ahead you upload the Gerber files and a few days later the PCB arrives via courier. In my case they even send me an email to clarify one issue.

One disadvantage is the relatively high set-up cost. For quantities of one PCBCART is probably not a good choice.

Step 4: Do I need a solder paste stencil?

The most difficult step in assembling a PCB is to apply the correct amount of solder paste. A stencil allows to “screen print” the correct amount of solder paste onto the board. This definitely makes sense for greater production volumes. For prototypes the expense is probably not worth it. It is definitely possible to solder 0402 components onto a board without a stencil. The thickness of the stencil dictates how much solder paste is applied. There are more durable metal stencils or laser cut plastic stencils available.

Step 5: Assemble the board

If you assemble the first board it probably makes sense to do this in steps. For example first solder all the power supply components, check if the power supply works and then assemble other components that create other functional blocks. Just remember as soon as you assemble through-hole components it is difficult to reflow afterwards. Through-hole components come last after all SMD components have been soldered.

It is also a good idea to start with the smallest components first and finish with the large ones. Without a solder paste stencil I apply the solder paste using a tooth pick dipped into solder paste. This way it is quite easy to apply tiny blobs of paste to the pads. Other people use a small syringe. I found that the solder paste keeps running even after I stopped applying pressure to the syringe. This is a bit messy and for me the toothpick blob method worked better.

I never ever applied too little solder paste to a pad. If in doubt apply less! Especially larger components encourage you to apply big blobs of paste to the large pads. Don’t do it. It is amazing how little paste is needed.

Check if all the components have been placed. Especially with 0402 parts it is actually difficult to see if there is a part on the pad or not. A magnifying glass would help but it is possible to do all this without one if you have good eyes. One of my next investments is going to be an USB microscope. These are quite cheap and they should be great for inspecting a PCB, taking pictures and movies.

Step 6: Reflow the board

I have only used the electric skillet method and I must say it works a treat for small boards. It is a good idea to first do a small test with a scrap board and some scrap parts to see how quickly the solder starts to melt. On full power it takes less than 2 minutes with my skillet which is a bit too fast. Recommended is about 3 minutes which can easily be achieved by turning the skillet heater off for a short period. With larger boards you might also encounter problems that some areas of the skillet are hotter than others. If you found a good set-up I would always place the board roughly in the same area to more reliably create the same results. If you have an aluminium plate or similar it would be great to use it as a heat spreader. Place the plate into the skillet and the board on top of the aluminium plate. Aluminium is a very good thermal conductor.

You don’t necessarily need a thermo couple to measure the temperature. Just use a stop watch and a test PCB to roughly melt the solder at the 3 minutes mark. Switch the skillet on and off until the solder melts at the right time. For example heat for 1:20, switch off for 20 seconds, heat for 1:20, solder melts, switch on and off for 10 seconds for a total of 1:30, switch off, wait 30 seconds, open lid to cool down. Something like this should give you a pretty good temperature profile.

Step 7: Check the board and fix solder bridges

Check the board for missing parts and solder bridges between pins. Solder bridges are easily fixed by placing a de-solder wick across the pins and heating it up with a regular solder iron. The wick sucks up the excessive solder.

Sometimes tiny parts float away because of too much solder or if the skillet is not horizontal. If this is the case I use a hot air solder gun to locally heat up the board to remove the stray part. With hot air it is also possible to reflow a single part. Remove any excessive solder using a de-solder wick, apply new solder paste, place the part and locally heat up the board using a hot air gun.

Step 8: Solder through-hole components

Most boards probably have some through-hole components. These are soldered last. Once pins stick out of the bottom surface it is difficult to reflow using the skillet method since the board floats on top of the skillet. Therefore ensure all reflow has been done before hand soldering.

Step 9: Power up and test!