Netburner Tutorial 3:

Utilizing the PWM IO Hardware on the MOD 5213

Keywords: PWM, PWM IO, PWM on DSP


Motivation and Audience

This tutorial's motivation is to teach the basics of the PWM driver within the MOD5213 chip. Readers of this tutorial assumes the reader has the following background and interests:

The rest of the tutorial is presented as follows:

Parts List and Sources

US-based vendors to obtain material to complete this tutorial is the Embedded Netburner Development Kit (the MOD5213), found here.

To complete this tutorial, you'll need the following items:

TABLE 1: Parts needed to build (fill in the blank)
PART DESCRIPTIONVENDORPARTPRICE (1999)QTY
Netburner Development Kit Netburner Inc.MOD5213 $99.001
USB to Serial Adapter*--------$10 and up 1 

 *If your computer does not have a 9 pin RS-232 Serial port, you will need to purchase a USB Adapter. They can be found almost anywhere on the internet, or in a computer store near you.

Construction

Step 1

Create a Project File for the PWM project.  Label is as you wish, I used PWM_DevBoard as the project file name. (If you need further help with building the project, refer to the PIN IO Tutorial.

Step 2

Once the project file is created, expand the project file and navigate to the main.cpp file, and double click it.  This will open in the primary window with the basic code needed to run the MOD5213. 

Step 3

Under the include files at the top of the main.cpp code file, add the files "<pins.h>, and <..\MOD5213\system\sim5213.h>" (less the quotation marks).  These header files are used for the pin definition (<pins.h>) and for accessing the registers to enable and set up the PWM. (<..\MOD5213\system\sim5213.h>)  See the program code section below for setting the registers.  I included print statements after the line of code to debug when the register is set when ran in the processor.

 

 

Programming

The source code to the source code (main.cpp file) for the PWM Project is provided below:


To be compiled with the Netburner Eclipse IDE
Note: download main.cpp rather than cutting and pasting from below.

#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <basictypes.h>
#include <serialirq.h>
#include <system.h>
#include <constants.h>
#include <ucos.h>
#include <SerialUpdate.h>
#include <pins.h>
#include <..\MOD5213\system\sim5213.h>

// Instruct the C/C++ Compiler not to mangle the function name
extern "C" {
void UserMain(void * pd);
}
// Name for the Development IDE to identify this application
const char * AppName="PWM_DevBoard";

// User Main - Main task
void UserMain(void * pd) {

	SimpleUart(0,SystemBaud); 		// Start UART 0 at 115200 baud for chip communication
	assign_stdio(0);
	OSChangePrio(MAIN_PRIO); 		// Set the Priority of the UserMain loop to 50 (in the RTOS) 
	EnableSerialUpdate();

	Pins[24].function( PIN24_PWM0 ); 	// Configure Pin 24 for PWM Channel 0 functionallity
	iprintf("Pin Function Set.\n"); 	// Debug register set to Mttty Terminal
	sim.pwm.pwme = 0; 			// Disable all PWM channels before making any settings
	iprintf("PWM Channels Disabled.\n");	// Debug register set to Mttty Terminal
	sim.pwm.pwmpol &= ~0x01; 		// Set to have an initial low signal, then set high on Duty cycle output compare
	sim.pwm.pwmclk |= 0x01; 		// Set to use clock SA (Scale A)
	sim.pwm.pwmprclk |= 0x07; 		// Set to use clock A prescale value of 2 (Internal Bus Clock/ 2^1)
	iprintf("Pin Prescaler Set.\n"); 	// Debug register set to Mttty Terminal
	sim.pwm.pwmcae &= ~0x01; 		// Set to operate channel 0 in left-aligned output mode
	sim.pwm.pwmctl = 0; 			// All channels are 8-bit channels, doze and debug mode disabled
	sim.pwm.pwmscla = 0x04; 		// Use scale divisor value of 2 to generate clock SA from clock A
	iprintf("PWM Scale Divisor Set.\n");	// Debug register set to Mttty Terminal
	sim.pwm.pwmcnt[0] = 1; 			// Write any value to this register to reset the counter and start off clean
	iprintf("Counter is reset.\n"); 	// Debug register set to Mttty Terminal
	sim.pwm.pwmper[0] = 100; 		// Set PWM Chnnel Period register to a value
	iprintf("PWM Period Set.\n"); 		// Debug register set to Mttty Terminal
	sim.pwm.pwmdty[0] = 50; 		// Set PWM Channel Duty register to a value of 3
	iprintf("PWM Duty Cycle Set.\n");	// Debug register set to Mttty Terminal
	sim.pwm.pwme |= 0x01; 			// Enable PWM Output for PWM Channel 0
	iprintf("PWM's are enabled.\n"); 	// Debug register set to Mttty Terminal
	
	iprintf("Application started\n"); 	// Debug register set to Mttty Terminal
	while (1) {

		OSTimeDly( TICKS_PER_SECOND ); 		// The while loop keeps the processor running, since the PWM module
					// is external to the processor. 
	}
}


main.cpp Fuller Code Description

The main.cpp code above is mainly geared around setting the registers rather than running the main loop.  (Take note that the only line of code inside the while loop is OSTimeDly( TICKS_PER_SECOND ).  This is only keeping the processor alive, since the PWM Module is separate from the main DSP Processor.

Final Words

This tutorial's objective was to get acquainted with setting the registers to access the PWM Module on the DSP.  Once the concepts were conveyed the reader could use the PWM Module and the registers to generate any PWM signal, whether it for direct motor control, or PWM for servo motors. 

Speculating future work, derived from this tutorial, includes data acquisition for a typical robotics based sensor using a standard serial UART to communicate.

Click here to email me