Friday, March 15, 2024

Delay functions for Silicon Labs microcontrollers

Sometimes you need to delay the program execution, for example when waiting for another device to startup or respond and the software cannot continue. An interrupt driven delay is better in most cases but not in all cases. For this purpose I made two functions one for milliseconds and one for microseconds, that uses NOPs to delay the program execution for a certain amount of time. The milliseconds delay is quite accurate, the microseconds one, not so much.

For this to work, the SYSCLK must be defined first. It is recommended to be defined in the project settings. You can find a short tutorial here on how to add a global define in Simplicity Studio: https://www.programming-electronics-diy.xyz/2024/03/defining-sysclk-or-fcpu-in-simplicity.html

Tested on:

- C8051F330

For other microcontrollers the following SFR declarations include file should be replaced accordingly:

#include <SI_C8051F330_Register_Enums.h>


Library usage

 

Milliseconds delay

 
_delay_ms(uint32_t ms)
 

Microseconds delay

 
_delay_us(uint32_t us)
 

Download

delay
v1.0 delay Contains delay.h and delay.c

UART library for Silicon Labs microcontrollers using interrupts

This UART library is made for Silicon Labs microcontrollers that can be used for serial communications.

UART is a type of serial interface, as opposed to a parallel interface. A parallel interface can work at higher speeds but the disadvantage is that it needs multiple input/output lines. Other examples of serial interfaces are SPI and I2C. 

UART library for Silicon Labs microcontrollers using interrupts

Supported Devices

At the moment only following devices are supported. I might add more in the feature. It might work for other similar devices not listed below.

  • C8051F330

Defining SYSCLK or F_CPU in Simplicity Studio

The macro SYSCLK or F_CPU specifies the CPU frequency and is used by libraries such as <delay.h> to calculate the delay based on the frequency of the processor or by UART libraries to calculate baud rate.

Up until now I used to define F_CPU like this:

#define F_CPU    24500000UL

Defining this way will work but it could lead to issues and confusion when you have multiple files that define this macro. The ideal way is to define it in a single place. This could be a Makefile if you are using custom Makefiles or in the IDE project configuration.

Defining SYSCLK / F_CPU in Simplicity Studio

Open the project properties window in Project -> Properties (Alt+Enter) then in the left panel select the C/C++ Build -> Settings menu. Then in Tool Settings - > Keil 8051 Compiler -> Symbols use the green + button to define a new symbol SYSCLK=2450000UL. Of course the SYSCLK value depends on your CPU frequency that in this example is 24500000 Hertz or 24.5MHz. The UL at the end stands for unsigned integer.

Defining SYSCLK symbol in Simplicity Studio 01

Defining SYSCLK symbol in Simplicity Studio 02

That's it. Now all included files in your project will use a single SYSCLK value without giving errors such as "SYSCLK is not defined", "SYSCLK redefined", etc.

Since this method of defining is not as obvious as the first one, it is easy to forged to do it when starting a new project but there is a simple solution for that - using preprocessor conditionals.

#ifndef SYSCLK
	#warning	"SYSCLK not defined. Define it in project properties."
#elif SYSCLK != 24500000
	#warning	"Wrong SYSCLK frequency!"
#endif

This macro can be placed at the beginning of the main.c file before any type of code. If the SYSCLK is not defined it will output a warning. If SYSCLK is defined but is not the value specified in the macro, it will also output a warning. This is also helpful to see what the CPU frequency is and to ensure that the defined value in project properties is correct.

Tuesday, March 5, 2024

Open source software for programming Silicon Labs microcontrollers using C2 interface

The C2 Programmer is designed for programming Silicon Labs microcontrollers over the C2 interface by the use of an AVR microcontroller with the necessary firmware and an USB to serial adapter. The software is written in JavaScript and is based on ScriptCommunicator by Stefan Zieker.


Custom open source C2 programmer


What does it do

  • Save flash memory to .bin (binary), .txt (hex format) or .hex (Intel hex) file.
  • Write an Intel hex file to flash memory.
  • Erase device option.

What does not do

  • Everything else.

Contents


Motivation

Why use a custom programmer when you can buy one? The reason I have started developing this software is not necessarily cost related. I could have just bought a programmer and be done with it instead of coding hours and hours, but I thought it will be a good addition for the community since being custom made it can be... customized. There are other reasons such as, maybe the commercial one is not available in your area or not in stock, or you might want to program only one or two microcontrollers and consider is not worth investing in a programmer.

Actually this is how the project started. I have an RDM-6300 RFID card reader that I thought is a writer too. Then I saw it's using the C8051F330 microcontroller from Silabs and decided to give it a try and make it also write RFID cards or at least add support for other chips. By not buying a programmer I made one that I could use in my project and also make it available for others.

Note that debugging is not supported so if you need this feature, consider buying a commercial programmer.

Theory of operation

Application on the computer instructs the firmware on an AVR microcontroller on what commands to send to the C2 interface of the programmed device. The communication between computer and programming device (the AVR) is done using an USB to serial converter.

The application is build on top of ScriptCommunicator which is a scriptable cross-platform data terminal that supports serial port (RS232, USB to serial), UDP, TCP client/server, SPI, I2C, and CAN. Script Communicator it's an awesome application that unfortunately is not that well known. The best part is that the interface can be made to look how you want by using the Qt Designer included with the app.

Wednesday, January 24, 2024

Defining F_CPU in Microchip Studio

The macro F_CPU specifies the CPU frequency and is used by libraries such as <delay.h> to calculate the delay based on the frequency of the processor or by UART libraries to calculate baud rate.

Up until now I used to define F_CPU like this:

#define F_CPU    16000000UL

Defining this way will work but it could lead to issues and confusion when you have multiple files that define this macro. The ideal way is to define it in a single place. This could be a Makefile if you are using custom Makefiles or in the IDE project configuration.

Defining F_CPU in Microchip Studio

Open the project properties window in Project -> Properties (Alt+F7) then in the left panel select the Toolchain menu. Next in AVR/GNU C Compiler -> Symbols use the green + button to define a new symbol F_CPU=16000000UL. Of course the F_CPU value depends on your CPU frequency that in this example is 16000000 Hertz or 16MHz. The UL at the end stands for unsigned integer.

Defining F_CPU symbol in Microchip Studio
click to enlarge

That's it. Now all included files in your project will use a single F_CPU value without giving errors such as "F_CPU is not defined", "F_CPU redefined", etc.

Since this method of defining is not as obvious as the first one, it is easy to forged to do it when starting a new project but there is a simple solution for that - using preprocessor conditionals.

#ifndef F_CPU
	#warning	"F_CPU not defined. Define it in project properties."
	
#elif F_CPU != 16000000
	#warning	"Wrong F_CPU frequency!"
#endif

This macro can be placed at the beginning of the main.c file before any type of code. If the F_CPU is not defined it will output a warning. If the F_CPU is defined but is not the value specified in the macro, it will also output a warning. This is also helpful to see what the CPU frequency is and to ensure that the defined value in project properties is correct.

Thursday, January 4, 2024

How to program an UPDI AVR microcontroller using avrdude and USB to serial programmer

After buying some ATtiny402 microcontrollers I've noticed that newer AVR models from Microchip are now using the UPDI interface for programming. Previously the programming was done using SPI or UART if a bootloader was present.

How to program an UPDI AVR microcontroller using avrdude and USB to serial programmer
 

Contents

 

What is UPDI and how do I use it?

UPDI stands for Unified Program and Debug Interface and is proprietary to Microchip. In many ways is similar to 1 wire UART. The main advantage is that it can be used for programming and also for debugging. Now there is no need for SPI, bootloader, debugWire... It's all Unified in one pin and one interface.

On certain devices such as ATtiny, the UPDI and Reset are on the same pin. In each case, the UPDI pin can also be used as a GPIO pin. When UPDI and Reset share the same pin, the functionality can be selected using the specific fuse. By default the fuse is set to select UPDI as a pin function. If you change the fuse and enable the Reset then you will need a 12V programmer to be able to program the microcontroller.

To prevent false triggering when the line is idle, it is recommended to have a pull-up resistor of at least 10k on the UPDI pin. Although some say that it works without problems even without a pull-up resistor so if you are using the UPDI pin also as a GPIO pin, you might consider not placing the resistor.

Source: https://microchip.my.site.com/s/article/AVR---Hardware-Design-Considerations-for-UPDI-pin.

Can i manually reset the microcontroller when UPDI is shared with RESET? 

Wednesday, December 20, 2023

Library for TMC2209 driver - AVR

This library is used to control one or more TMC2209 modules via UART using an AVR microcontroller. Apart from reading and writing the TMC2209 registers, this library can also be used to drive a stepper motor by using the stepperCon library in the background. The stepperCon library provides non blocking functions by using an interrupt, to drive multiple stepper motors with custom acceleration and speed, to keep track of motor positions, 3-axis motor coordination, as well as other useful functions. UART library is also provided that can use up to 2 USART peripherals at the same time: one for interfacing with the driver IC and one for debugging (assuming the microcontroller has two USART peripherals). 

The serial communication has some extra features for checkup such as:

  • reads the interface transmission counter (IFCNT) register after every write to ensure the IC received the correct data.
  • compares CRCs.
  • checks if correct number of bytes has been received.
  • if an error occurs it retries 2 times then sets a communication error flag that the user can check after each function is executed and take the appropriate action if an error occurs. 

Library for TMC2209 driver - AVR
The principle of operation is read-modify-write so there is no need to keep all driver IC registers in memory. The library only uses an 8 bytes union structure called replyDatagram where received and data to send is stored temporary.

If you wish to learn on how to wire the TMC2209 driver, you can find a tutorial here.

Contents