Arduino Like Function on Kinetis K82 Freedom Stupid Board © GPL3+

1000 of K82 Freedom Boards are collecting dust because of the hobbyist unfriendly IDE, pump up the duds with easy Arduino-like functions.

  • 1 comment
  • 4 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)

Apps and online services

About this project

Background Story

Well, not really! The board is not stupid, it has a very powerful MCU in there with lots of advanced functionalities. It's the IDE or me or maybe the documentation is stupid. If you are here, I can guess that you have got one of this board from NXP as a participant of "Flex Your Mind" contest. I also assume that many of us who received this board can't use it because of the daunting IDE environment and professional level documentation.

So, I decided to give it a shot and turn this board useful by functionizing I/O, ADC, DAC etc info Arduino like style. I hope it will be of some use to you for doing Analog Sensing and Load Control type projects.


Since, this is just like a project template, all you need is the K82 Freedom board, some protoboard, LEDs and buzzer. Here is how my hardware looks like:

But, I would recommended adding a Arduino Prototyping Shield on the top like this one and build from there:

Other Shield options: Relay Shield or Motor Control Shield or Analog Sensor Shield etc.


We will need to install the Kinetis Design Studio for writing code and Arduino IDE for using its built in serial monitor.

There is a void setup() and void loop() part in the middle of the code where you can write code in Arduino style:

Top part of main.c has header files and bottom part has Arduino function body. These areas should be untouched or the functions may malfunction!

Installation Instruction

(Coming soon, after I prepare the screenshots)


Download and Install KDS (Kinetis Design Studio)

Download and Install K82 Freedom Board Driver (if necessary)

Download and Install K82 Freedom Board OpenSDA Bootloader (if necessary)

Download SDK for Example Driver/Apps (optional)

Here is a Getting Started Video Instructable

Download Project Generator (optional)

Download the attached Code, save and unzip on your Computer.


To install the Bootloader, unplug the board, press & hold reset, plug the board into computer's UBS. Now release reset button, drag and drop the bootloader bin file into the appeared USB Disk. Now,unplug and plug the K82 FRDM Board to boot SEGGER LINK Bootloader.

Now download the zip file from the Code section below, save on desktop and unzip it.

Step 1: Importing Existing Project

Open Kinetis Design Studio on your computer. Go to File>Import.

Select Projects for Projects>Next ,then browse the downloaded unzipped files, find ArduinoFn_K82frdm.wsd and Open. Click Finish to complete Import.

Step 2: Opening and Editing Code

On the left column click on '+' of ArduinoFn_K82frdm_MK82FN256VLL15, now double click on the main.c file to open the code editor.

Scroll down to find the void setup() starts here comment, below this you will write setup functions in arduino style.

Scroll down a little to find the void loop() zone inside a while(1) loop, here is where you write code in arduino style.

Scroll down further below, where you will find the arduino functions body written using kinetis design studio APIs, its better you don't modify them.

Step 3: Compiling, Flashing and Debugging

Look for the "Hammer", "Thunder" and "Bug" icons in KDS IDE (top second row) representing "Build/Compile Code" , "Flash/Upload Code" and "Debug Code".

Write your code first , click the Hammer button to compile, Flash button to upload. But don't just Flash away, use Debug first.

On the top right corner there is a C/C++ button which is useful to come back to editor ( your code ) if you get lost in some other windows in the IDE.

Step 4: Configuring SEGGER J Link Debugger

If you have the right bootloader on your K82 Freedom board, you will have no trouble following the steps, if not download and install it on your board (see instructions before step 1 - above)

Click on the little down arrow next to the BUG icon, click debug configuration. Open the '+' left to GDB SEGGER J-Link Debugging and select

ArduinoFn_K82frdm_MK82FN256VLL15 debug J-Link and click debug. Click OK in the popup window. A terms of use (License B*** S***) window will appear, just accept anyway with checking "do not show this message again today". Your recompiling is running and code will flash to the hardware after few seconds.

If this error message shows up, click OK. Then click the C/C++ Tab ( top right corner ) to go back to code editor (main.c) , click the Hammer button to compile again.

Once your code is flashed on the K82 Freedom board successfully this following debug window will appear. Click the Resume MCU button to startup your program on your Freedom board. There are many things on the debug window, unfortunately that is not with in the scope of this tutorial - so I am not going to explain these. Just check this image to see what is happening where during debugging.

Step 5: Serial Monitor on Arduino IDE

Open Arrduino IDE on your computer, go to Tools > Port > COMxx, select the com port associated with Segger J-Link , in my case its COM20. On the top Right corner click on the Serial Monitor icon.

A window will appear, select baud rate 115200 if otherwise. You will see Streaming of Data from K82 Freedom board, does not it feel like Arduio by now ?

For my code ADC value is popping on the screen.

Supported Functions

Some function are pin bound to specific pins, some pins are tied to the on board sensors, switches and LEDs. Carefully check this picture, so you get an idea which pins are not safe to use.

  • Port C pin 14,15 are allocated for Serial, should not be used as GPIO
  • Port A pin 4, Port C pin 6 are hardware connected to push switches SW2, SW3 thus should be used as GPIO Input
  • Port C pin 8, 9, 10 are allocated for PWM, should not be used as GPIO
  • Port A pin 1,2 and Port C pin 13 are connected to on board sensor, should not be used as GPIO
  • DAC0_Out is fixed for DAC output
  • Port B pin 0,1,2,3 and Port C pin 1,2 are allocated for ADC
  • All other available pins on the board may be used as GPIO

Since, I wanted to make sure I can use the additional pins out there on the board not the Arduino R3 layout covering pins, so some functions are slightly different than Arduino!

  • pinMode()

In Arduino IDE we write pinMode(13,OUTPUT) but here it will different. Suppose I want to set Port B pin 20 as Output, what parameter should be passed?

By checking the bottom side of Freedom board, we find the physical location of the Port B Pin which is not on Arduino R3 layout but still can be used as GPIO!

The function will be pinMode('B',20,OUTPUT); here 'B' (Capital B with in ' ' is passed to indicate port ! This is how it's different from original Arduino function.

  • digitalRead()

Example: To read PTA4 or Port A pin 4 we call digitalRead('A',4);

  • digitalWrite()

Example: to write PTA5 or Port A pin 5 with High we call digitalWrite('A',5,HIGH);

  • analogRead()

Since, analog pins are fixed and same as Arduino R3 location, function arguments are the same.

Example: analogRead the first ADC (PTB0 on this board) call analogRead(A0); in Arduino style or analogRead(B0); both will work the same and return a value with in 0-4095 range for 0-3.3 volts!

  • analogWrite()

analogWrite is available on PTC 8,9,10 with duty cycle 0-100 (not 0-255 like Arduino) and 24000 Hz frequency (not 490 Hz like Arduino).

Example: analogWrite(8,25); turn on PWM on PTC8 pin/ port C pin 8 with 25% duty cycle.

  • analogWriteDAC()

The DAC is 12 bit voltage DAC, so a value with in 0 to 4095 can be passed and and Analog Voltage will appear on DAC_OUT pin accordingly.

Example: analogWriteDAC(2048); will output around 1.67 volts on DAC pin

  • delay()

Exactly same as Arduino, will halt the CPU!

Example: delay (500); will do 500 milliseconds or 0.5 seconds of delay

  • Serial_println()

Same as Serial.pringln() in Arduino.

Example: Serial_println("Hello !"); will send the string "Hello !" over serial to the Serial Monitor of Arduino. Baud rate is fixed at 115200.

Possible Use Cases

Here are some basic ideas what can be done after installing this code:

  • High current load control through relay
  • Analog sensor reading, monitoring and automation
  • LED, Buzzer, Switch, 7-segment, Dot Matrix display driving
  • DAC for waveform generation
  • PWM Motor control for robotics
  • UART communication


  • No Arduino based Library support
  • Programming in Kinetis Design Studio not Arduino IDE
  • Fixed Serial baud rate 115200 bps
  • Possibility of Bug or Stall MCU
  • Same pin may not support different functions during runtime
  • 3 PWMs, 6 ADCs, 1 DAC are pin bound
  • No SPI/I2C functions (until now)
  • GPIO single pin current limit 25 mA, voltage 3.3 volt
  • Total device GPIO limit 100 mA
  • DAC current limit 1 mA (solution: use a voltage follower for drive)

Further Works

I may add following functions in future:

  • tone()
  • servo()
  • pulseIn()
  • shiftOut()
  • random()
  • getTime()
  • setTime()
  • getAccel()
  • getMagnet() etc

Also RTC capabilities for time date information. There you have it, the Stupid's Freedom Board for Smart Arduino Dudes !

p/s: ( Ha Ha Ha - read the sentence otherwise: The Smart Freedom Board for Stupid Arduino Dudes )


K82 Freedom Board
Pinout wdw71dbjbn
KDS driver files and code
Download and Unzip this, then import in Kinetis Design Studio as "Projects for Projects"


Adruino Function in K82 Freedom BoardC/C++
Supported Functions :
Serial_println() [ Serial.println() version ]
// Copyleft by PissedOff

//============== PLEASE SCROLL DOWN TO THE PART WITH void setup() =============//
//============== void loop() TO WRITE DOWN ARDUINO STYLE CODE     =============//

#include "fsl_device_registers.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_gpio.h"
#include "fsl_lptmr.h"
#include "clock_config.h"
#include "pin_mux.h"
#include "fsl_common.h"
#include "fsl_port.h"
#include "fsl_adc16.h"
#include "fsl_pit.h"
#include "fsl_dac.h"
#include "stdbool.h"
#include "fsl_lpuart.h"
#include "fsl_lptmr.h"

#define HIGH 1
#define LOW 0
#define OUTPUT 1
#define INPUT 0

// Arduino R3 Layout ADC (Single Ended 12 Bit) Location on K82, // 0-3 volt gives 0 - 4095
// R3 Eq --- ADC Channel ---- Actual Pin on K82 Board with alias to Arduino R3 layout
#define A0 		8    			// 		B0
#define A1 		9				// 		B1
#define A2 		15				// 		C1
#define A3 		4				// 		C2
#define A4 		13				// 		B3
#define A5 		12				// 		B2

// Alternative defines for ADC with Reference to the K82 Board also work
#define B0 		8
#define B1 		9
#define B2 		12
#define B3 		13
#define C1 		15
#define C2 		4

// Analog Write real PWM supported pins, don't use digital Read/Write on these pins
#define C8 		8
#define C9 		9
#define C10 	10

volatile uint32_t msruntime=0;

///!!!!!!!!!! WARNING !!!!!!!!!!!///
///!!!!!!!!!! WARNING !!!!!!!!!!!///
///!!!!!!!!!! WARNING !!!!!!!!!!!///
// millis generating timer, interrupt driven

void LPTMR0_LPTMR1_IRQHandler(void)
    LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);


DO NOT USE PortC 14, 15 pins as GPIO -> Connected to UART for debugging
DO NOT USE PortC 13 and  PortA 1, 2  pins as GPIO -> Connected to I2C for on Board Sensors

PortC 8, 9, 10 pins are connected to RGB LED ( good choice for PWM Output)
PortC 6 and PortA 4  pins are connected to tactile Switchs SW2, SW3 ( good choice for Input)

void ArduinoK82Init (void);


//*** Porvided that board speed is 120 MHz
void delay(int); // Example:  delay (500) gives 500 ms

// * provide 3 parameters port,pin state
// * The char is port 'A' or 'B' or 'C' or 'D' since this board's pin
// * are like C7 instead of 7 or A13 instead of 13,
// * port letter must be inside '' mark

void pinMode(char,int,int);        // Example: pinMode ('C',7,OUTPUT);
void digitalWrite(char,int,int);   // Example: digitalWrite('C',7,LOW);
int digitalRead(char,int);         // Example: digitalRead('A',4)

// * reads single ended 12 bit Analog value on specific 6 pins ( Arduino R3 location of ADC pins)
int analogRead(int);               // Example: analogRead(A0) or analogRead(B0) are same Port B pin 0 (ADC channel

// * Makes Real Analog Voltage fixed DAC_Out pin, no PWM
// * for 3.3 V, analogWriteDAC(4095)
void analogWriteDAC(uint32_t);

// * FTM based PWM, supports upto 3 fixed Channels now
// * C7, C8, C9 if used as PWM, should never call Digital Read/Write/Pin mode
// * or Hard Fault will occer freezing CPU
void analogWrite(int,int);

// * Primary Serial Always Enabled @ Baud rate of 115200 NO NEED Serial.begin
// * works on Arduino IDE built in serial monitor or putty
void Serial_println (char[500]);
// for serial FPRINT ("text %d", number ) also works

uint32_t millis(void);
// * Second Low Power UART usable with BT HC 05/06 module or with USB-Serial Device

int main()
// *performs necessary initialization on K82 H/W for GPIO/ADC/PWM

/// void setup() starts here ///////////////////

    pinMode('B',20,OUTPUT); // buzzer
    pinMode('A',4,INPUT); // SW 2
    pinMode('A',5,OUTPUT); // Led 1 Blue
    pinMode('B',16,OUTPUT); // Led 1 Yel
    pinMode('A',12,OUTPUT); // Led 1 Blue

/// void setup() Stops Here ///////////////////

    while (1)
/////////////// Arduino void loop() Below Here ///////////////////
    	// digital read/write
// millis test fn LED toggle at every 1000 ms
    		int ms = millis();
    		if (ms%1000 == 0)

    			int x= analogRead(C1);

    			PRINTF(" millis val: %d \r\n",ms);
    			PRINTF(" adc val: %d \r\n",x);



    	// poll check switch press
     if  (digitalRead('A',4)==1)

				for(int i=0;i<20;i++)
				{	digitalWrite('A',5,HIGH);

		// Real DAC
				for(int i=0;i<100;i++)

				for(int i=0;i<100;i++)
					else // sw on board is active low, following executes on press



                	 for(int i=0;i<500;i++)


    } // while(1) or void loop() ends here

} // main() ends here

//////////// Arduino Function Body - DONT MODIFY ///////////////////////////

// old blocking delay
void delay(int ms)
    volatile uint32_t i = 0;
    for (i = 0; i < 12000*ms; ++i)

void delaymicroSeconds(int us)
    volatile uint32_t i = 0;
    for (i = 0; i < 12*us; ++i)


// new delay
void delay( int ms)
	  SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
		    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
		    SysTick->LOAD = ms * ((CLOCK_GetFreq(kCLOCK_CoreSysClk)) / 1000U);
		    SysTick->VAL = 0U;

		    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

		    /* wait for timeout */
		    while (0U == (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))

void pinMode(char port,int pin,int state)


	gpio_pin_config_t output = {
        kGPIO_DigitalOutput, 0,

	gpio_pin_config_t input = {
	        kGPIO_DigitalInput, 0,

	if (port =='A' && state==1)
		PORT_SetPinMux(PORTA, pin, kPORT_MuxAsGpio);
		GPIO_PinInit(GPIOA, pin, &output);

	if (port =='A' && state==0)
	PORT_SetPinMux(PORTA, pin, kPORT_MuxAsGpio);
    GPIO_PinInit(GPIOA, pin, &input);
	    if (port =='B' && state==1)
	    PORT_SetPinMux(PORTB, pin, kPORT_MuxAsGpio);
	    GPIO_PinInit(GPIOB, pin, &output);
		if (port =='B' && state==0)
		PORT_SetPinMux(PORTB, pin, kPORT_MuxAsGpio);
	    GPIO_PinInit(GPIOB, pin, &input);
		    if (port =='C' && state==1)
		    PORT_SetPinMux(PORTC, pin, kPORT_MuxAsGpio);
		    GPIO_PinInit(GPIOC, pin, &output);
			if (port =='C' && state==0)
			PORT_SetPinMux(PORTC, pin, kPORT_MuxAsGpio);
			GPIO_PinInit(GPIOC, pin, &input);
				if (port =='D' && state==1)
				PORT_SetPinMux(PORTD, pin, kPORT_MuxAsGpio);
				GPIO_PinInit(GPIOD, pin, &output);
				if (port =='D' && state==0)
				PORT_SetPinMux(PORTD, pin, kPORT_MuxAsGpio);
				GPIO_PinInit(GPIOD, pin, &input);


void digitalWrite (char port,int pin,int state)
	{GPIO_WritePinOutput (GPIOA, pin, state);}
	{GPIO_WritePinOutput (GPIOB, pin, state);}
	{GPIO_WritePinOutput (GPIOC, pin, state);}
	{GPIO_WritePinOutput (GPIOD, pin, state);}


int digitalRead (char port,int pin)

	{return GPIO_ReadPinInput (GPIOA, pin);}
	{return GPIO_ReadPinInput (GPIOB, pin);}
	{return GPIO_ReadPinInput (GPIOC, pin);}
	{return GPIO_ReadPinInput (GPIOD, pin);}

void Serial_println(char str[500])


int analogRead(int adc_Ch)

	uint32_t temp=0;
	for (int j=0;j<50;j++)
    adc16_config_t adc16ConfigStruct;
    adc16_channel_config_t adc16ChannelConfigStruct;
    adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt;
    ADC16_Init(ADC0, &adc16ConfigStruct);
    ADC16_EnableHardwareTrigger(ADC0, false); /* Make sure the software trigger is used. */
    if (kStatus_Success == ADC16_DoAutoCalibration(ADC0))

    adc16ChannelConfigStruct.channelNumber = adc_Ch;
    adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;
    adc16ChannelConfigStruct.enableDifferentialConversion = false;

        ADC16_SetChannelConfig(ADC0, 0, &adc16ChannelConfigStruct);
        while (0U == (kADC16_ChannelConversionDoneFlag &
                      ADC16_GetChannelStatusFlags(ADC0, 0)))
        temp=temp+ ADC16_GetChannelConversionValue(ADC0, 0);
return temp/50;


void ArduinoK82Init (void)
	// These Functions must be included for clocking and debugging K82 Freedom //
    ftm_config_t ftmInfo;
// sets parameters for pwm signal such as Channel No, Duty etc... 3 for 3 channels
    ftm_chnl_pwm_signal_param_t ftmParam[3];

    PORT_SetPinMux(PORTC, 8U, kPORT_MuxAlt3);
    ftmParam[0].chnlNumber = (ftm_chnl_t)4U;
    ftmParam[0].level = kFTM_LowTrue;
    ftmParam[0].dutyCyclePercent = 0U;
    ftmParam[0].firstEdgeDelayPercent = 0U;

    	PORT_SetPinMux(PORTC, 9U, kPORT_MuxAlt3);
   	    ftmParam[1].chnlNumber = (ftm_chnl_t)5U;
   	    ftmParam[1].level = kFTM_LowTrue;
   	    ftmParam[1].dutyCyclePercent = 0U;
   	    ftmParam[1].firstEdgeDelayPercent = 0U;

   	    	PORT_SetPinMux(PORTC, 10U, kPORT_MuxAlt3);
   	 		ftmParam[2].chnlNumber = (ftm_chnl_t)6U;
   	 	    ftmParam[2].level = kFTM_LowTrue;
   	 	    ftmParam[2].dutyCyclePercent = 0U;
   	 	    ftmParam[2].firstEdgeDelayPercent = 0U;

    FTM_Init(FTM3, &ftmInfo);
    FTM_SetupPwm(FTM3, ftmParam, 3U, kFTM_EdgeAlignedPwm, 24000U, CLOCK_GetFreq(kCLOCK_BusClk));

    FTM_StartTimer(FTM3, kFTM_SystemClock);

    lptmr_config_t lptmrConfig;
    LPTMR_Init(LPTMR0, &lptmrConfig);
    LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(1000U, CLOCK_GetFreq(kCLOCK_LpoClk)));
    LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);


uint32_t millis(void)
	return msruntime;

void analogWriteDAC(uint32_t dacValue)

    dac_config_t dacConfigStruct;
   DAC_Init(DAC0, &dacConfigStruct);
  DAC_SetBufferReadPointer(DAC0, 0U);
 if (dacValue>4095)

  DAC_SetBufferValue(DAC0, 0U, dacValue); // dacValue range 0-4095

void analogWrite (int pin ,int duty)

	if (duty>100)
	{duty=100;} // bound)

	    /* Configure ftm params with frequency 24kHZ */
if (pin==8)
        FTM_UpdatePwmDutycycle(FTM3, (ftm_chnl_t)4U, kFTM_EdgeAlignedPwm,duty);
        FTM_SetSoftwareTrigger(FTM3, true);


if (pin==9)
		FTM_UpdatePwmDutycycle(FTM3, (ftm_chnl_t)5U, kFTM_EdgeAlignedPwm,duty);
        FTM_SetSoftwareTrigger(FTM3, true);


if (pin==10)

	        FTM_UpdatePwmDutycycle(FTM3, (ftm_chnl_t)6U, kFTM_EdgeAlignedPwm,duty);

	        FTM_SetSoftwareTrigger(FTM3, true);



Similar projects you might like

Temperature and humidity meter (iot)

Project showcase by 윤원호 and gledel

  • 3 respects

Arduinomated Car Parking with Voice Assistance in Smartphone

Project tutorial by Techduino

  • 1 comment
  • 11 respects

Sigfox Forest Fire Detector

Project tutorial by Louis Moreau

  • 16 respects

Remote Lamp

Project tutorial by Kutluhan Aktar

  • 5 respects

Magic VR Hat

Project showcase by Ron Dagdag and Johnathan Hottell

  • 8 respects


Project showcase by johan34

  • 1 comment
  • 7 respects
Add projectSign up / Login