I’m using CodeWarrior for MCU V10.3 which has the ARM gcc build tools integrated for the Kinetis family. It is possible to extend the “Tutorial: Enlightning the Freedom KL25Z Board” project and to add the I2C and accelerometer, or starting with a new project. In the steps below I create a new project, but I’m not going into the details how to add the LED as this is explained in the previous tutorial.

Creating the Project

I use the menu File > New > Bareboard Project:

File New Menu to create a new Bareboard project

Next, I need to specify a name for my project:

Naming the project

Next, I select the MKL25Z128 as my device:

Hint: I can use the filter field to at the top of the dialog to filter the devices.

Selecting KL25Z128 with filter text

Next, to select the debug connection. As the Freedom Board has the new OpenSDA on it, this is my choice:

OpenSDA Debug Connection

In the next dialog, I can go with the default settings. the ARM GNU GCC is the only (and default) tool-chain for Kinetis L (Cortex M0+) family:

gcc ARM Toolchain

Next, I select Processor Expert for my project:

Processor Expert

Pressing ‘Finish’ creates the project for me:

Freedom Project

RGB LED

Hint: I can copy-paste components from one project to another project in MCU10.3, even between workspaces. Simply select the component(s), use the ‘copy’ context menu, switch to the other project and past it into the Components group of that project. Really cool!

With the LEDs added, the component list should look something like this:

LED components

I2C

Processor Expert provides an I2C component (I2C_LDD) which implements a driver for it. I make sure that I have my project selected, then I choose in the Components Library view the I2C_LDD and add it to my project:

Adding I2C_LDD

According to the schematics, the accelerometer is on the I2C0 channel (with PTE25 and PTE25), so this is already the default, so no change here:

I2C Channel with pins

I’m only using the accelerometer on the bus, and the MMA8451 is using the (hex) 1D slave address, so I specify this in the properties. To enter hex values, I need to switch the format to the ‘H’ mode:

Target Slave Address

What I need to know the maximum bus clock frequency. The MMA8451Q Reference guide gives this information:

I2C MMA8451 clock speed

And the schematic of the Freedom board has this:

I2C Inertial Sensor Schematics

So we have I2C Pullups with 4.7K Ohm, but Cb is not specified. With 100 KHz I would be on the safe side, but I tried 1 MHz and that worked fine for me:

I2C Clock Settings

❗ There is an issue with the KL25Z silicon. Please see this post for further details.

With this, I have my basic settings in place and can generate the driver code:

Generate Driver Code

Accelerometer Interface

Time to write the software :-). Using the I2C_LDD, I need to use a device data structure with flags for data received and sent. So I declare this in my header file MMA8451.h which I create and add to my project:

RGB Demo

What is missing is the demo code itself. I keep things simple here, and turn on one of the LEDs if the acceleration on an axis is exceeding a threshold. It does not matter where to place that code, but I have it placed inside MMA8451 for demo purpose:

Hi Brad,
many thanks for the feedback!
1. I have clarified this in the tutorial.
2. Interesting. Looks like a bug of WordPress to me. I see the same if I use the ‘copy to clipboard’ button on the code. But it is ok if I do ‘view source’ and then do a copy. Strange.
3. There was the http:// missing in the link. Fixed now. http://www.steinerberg.com/EmbeddedComponents/Examples/FreedomBoard/Freedom_Accel.zip
4. Re-indexing should not be required, as the compiler does not depend on the index. But what could be needed is a ‘clean’. I’ll have this added.
5. Have you added the event code in Events.c? Maybe I missed to describe an important step. Could you try the complete example from http://www.steinerberg.com/EmbeddedComponents/Examples/FreedomBoard/Freedom_Accel.zip? Otherwise: while doing the demo I have found some erratic I2C behaviour which let me think that this actually could be a silicon bug?

Having finally received my pair of Freedom boards yesterday, I was about to start playing with this, but fell at the first hurdle. When I try to select my processor, there are no Kinetis L parts! Are these only available in 10.3b, or is my 10.2 lacking a component? I just ran the updater and it said there were no updates available. (I don’t have the option of 10.3b, as I don’t have a Windows computer on which to run it – I’m an all Linux shop.)

Kinetis-L is in 10.3 only (the 10.3 is mostly about the Kinetis-L launch). Technically it should be possible to bring in GCC to 10.2, but Processor Expert would be an issue. So the only option today is Windows. I was told that only a users of CodeWarrior are on Linux, so the future of CodeWarrior on Linux will depend on it.

That’s rather disappointing. CodeWarrior has only just (in relative terms) become available for Linux so there has scarcely been time for more widespread adoption, especially in enterprise where systems may only get changed every five years.

For me, it’s been a bit selling point and a differentiation for Freescale over competitors (like TI) that tools for Linux were available. When Processor Expert finally made it onto Linux I thought “at last!”

I guess I can see if I can get 10.3 working under my ancient WinXP virtual machine and hope that USB support in the VM has improved, as this is what has caused big problems for me trying to talk to hardware in the past. (The reason why I abandoned early experiments with Freescale parts and went back to Atmel, which has the benefit of a first-class open source toolchain.)

Yes, I know. But at least in my classes at the university is that less than 5% are using Linux host, even in that environment. I’m sure if there are enough users and enough selling points for Freescale, this will have an impact. I know for my own life that maintaining and developing for two platforms does not come for free. I propose that you put your request for Linux host support and 10.3 into the blog post by Jim Trudeau on http://blogs.freescale.com/2012/09/25/codewarrior-ide-v10-3-a-whole-new-perspective/. It will be heard.

Thanks, Erich. I’ve left a more detailed argument against that thread, and have also pinged my Freescale marketing contact, just to keep him in the loop.

Regarding your students, it’s probably a Catch-22 for them, too. There’s always those people who WANT to use Linux, but there’s no point, as none of the tools from Big Silicon work on that platform. (Unless you’re into FPGAs – both Xilinx and Altera have fully-fledged Linux development environments.)

In other news, I’ve got CWMCU10.3 downloaded on to my XP VM. I think I might have a chance getting this working, as I did get USB working on a Linux VM the other day, testing the PE Micro USB Multilink before the new drivers allowed it to work natively. Seems that the VirtualBox maintainers may have finally got that fixed. So hoping to start the tutorial tomorrow 🙂

Is there any way how to make simple project without magic as eclipse and other gui ?
only vim , Makefile , linker script , startup code , hal (io, perhipeals lib) and gnu c ?
Without automatic code generation ?

Yes, sure, there is. It is just much harder :-). Simply download one of my projects and use the sources with vim and make files. As easy as that. You even can use it with eclipse and normal make files, and if you want to get rid of Processor Expert in the project then have a look at this post: https://mcuoneclipse.wordpress.com/2012/10/14/removal-of-processor-expert-for-a-project/.
Eclipse and CodeWarrior is make that you can do exactly what you are asking for. You can even do this from a DOS shell if you want.

I wanted to try a lower SCL frequency so in the I2C_LDD component (Comp. Inspector), I selected the multiplier to 10 MHz, which set SCL to 524 KHz . But after build, the program did not work with this setting (X Y Z always read -1).

I changed the multiplier setting back to the original 20MHz (SCL 1048 KHz), did a build, and started debug, but it still wouldn’t work. I needed to unplug & replug the USB cable(Power cycle) and then it worked again.

This sounds like the silicon bug I have found. Unfortunately, it seems like this one is still not present in the errata available on the Freescale web site. It seems that under certain conditions, the I2C block on the KL25Z is not properly sending a repeated start condition on the I2C bus. I had it working on one project, and it did not work in another project where I used a different clock setting. I don’t remember the details any more, but it had something to do with the presecaler used for the I2C clock: it only worked with a prescaler of 1 (that’s what I have set up in my project). So it could be that with your changes you are using a different prescaler now? Then it would not work. You might inspect the I2C signals with a logic analyzer to be sure.

I mean the I2C prescaler settings (clock into the I2C block). I cannot find the email thread on this issue :-(, but as far as I remember the OUTDIV1Prescaler and OUTDIV4Prescaler must be both 1. You can check the settings here: go to the I2C_LDD properties, then press the (…) button in the ‘Internal frequency’ field. This gives you a dialog with the frequency settings (Timing Dialog). there is a tab ‘Clock path’ with all the prescaler settings.

I have found the information I was looking for: “Avoid using multiplier factor greater than 1 if want to generate “repeat start” condition on the I2C line (settings from the “Internal frequency (multiplier factor)” property). Please, check errata information for your chip version.” But I have not found this in the errata :-(. I’ll update the post with some screenshots. But the thing is that I had to change the clock settings somehow in the CPU component. What I see is that the ‘I2C0’ value needs to be 1.

In the example, the LEDs light up only in 1 direction of inclination of X, Y, Z, i.e, only if the read values are > 50. (eg. Blue is on when the board is the right side up, but off when it is upside down, even though both positions are “Horizontal”.

This is because In the opposite inclination, the values become negative (< -50).

To light up the LEDs in both directions of inclinations of X, Y, & Z, add at the top of MMA8451.c :

HI!
In the example we have set the slave address fixed to 0x1D, as only 1 device was connected.

If 1 or more other generic I2C devices were connected to the same bus, how would I need to modify the code, as they would have different addresses ?

I am aware of the generic I2C component you have created, but I would like to expand this particular code to add other devices, as I don’t plan on using other MCUs at present. (In fact, this is my 1st Freescale MCU, and 1st ARM device !)

Hi, interesting!!! I have a question, What I have to do for creating .srec or .s19 files if I want to use the board like MSD? Your tutorial worked for me! I only have the curiosity of creting my owns .s19 or .srec files 🙂

You have mentioned there is a bug in KL25 in the silicon. Would it be right to assume the same would be there in KL05 also? I am working on KL05. I wanted to communicate with an I2C based EEPROM. Is there any tutorial available for that or would I be able to use any present tutorial?

Hi John,
best if you check the silicon errata. As the KL05 came out after the KL25Z, it could be that they have fixed that problem. You should be easily be able to verify that I2C missing start signal with a logic analyzer. As for the tutorial: you can use the same steps as for the KL25Z, of course with different pin settings. The good thing about Processor Expert is that it makes applications very portable to other microcontrollers supported by it.

I followed all the steps in this tutorial and got no success. The RGB LEDs were turned off at all positions. So I decided to copy the I2C2 component of your project. Now, the LEDs are turned on, but not in the colors specified in the tutorial. By changing the Freedom Board from one position to another, the previous LED does not turn off. Do you know whether there was any change in LED component (On Method)?

Hi Wesley,
what kind of error? if you check the details or hover over the error part, you should get more information. If you use a ByteIO component, then all the pins for that port need to free and not used by something else.

Hi Brett,
thanks 🙂
And yes, you can address any device on the same bus. You only configure the initial/default address in the component properties. And then you select the device you want to talk with using I2C0_SelectSlaveDevice() (LDD component) or using GI2C1_SelectSlave() (in my GenericI2C component).

Hi Erich
I have a question, it’s about a statement at events.c in the events called when I2C recive or send a data,
I know you define a pointer *ptr type struct MMA8451_TDataState, but what means
(MMA8451_TDataState*)UserDataPtr

Hi Fabian,
LDD_TUserData is a typedef to void, so I receive a void pointer (void*) as argument.
I cannot access content behind a void pointer without poperly casting it to a non-void type.
For easier debugging, I have defined a local pointer (ptr) to which I assign this void pointer I get as parameter.
and with (MMA8451_TDataState*) I cast it to the proper type.

Hi Erich,
Thanks for creating this site, it had help me a lot to understand kl25z board.
I followed all the steps given above and it is working. While testing i got question, i want to known what values accelerometer is sending to micro-controller. How can i get this readings of change in tilt ?

Hi Aayush,
good to hear that things are helpful for you. You can easily get the acceleration values. And base on the acceleration values you should be able to calculate the tilt angle. Or did I misunderstood your question?

I also found this tutorial very helpful for my school project, but I too have a question about the values being returned from the acceleratormeter. What are the units? I tried looking into the MMA8451Q data sheet and thought I saw that the units we given in g’s, but when I read from the accelerometer lying flat on the table the Z axis shows that Acceleration due to gravity is 65. I’m pretty confused by this. Am I missing something?

See chapter 5.2 of the data sheet:
When the full-scale is set to 2g, the measurement range is -2g to +1.99975g, and each count corresponds to 1g/4096 (0.25 mg) at 14-bits resolution. When the full-scale is set to 8g, the measurement range is -8g to +7.999g, and each count
corresponds to 1g/1024 (0.98 mg) at 14-bits resolution. The resolution is reduced by a factor of 64 if only the 8-bit results are
used. For more information on the data manipulation between data formats and modes, refer to Freescale application.

Hi,
your tutorial is very useful but i have one problem. When I built it, I got ‘undefined reference to I2C2_Deinit’
Where should I define this function?
I commented this instruction and error disappeared but LED changed color only in few position and these changes wasn’t so smoothly. Could you help me? 🙂

Hi,
the Deinit() function shall be defined in the I2C2 component. Have you loaded the latest component, or is that method disabled?
As for changing the colors: have a look at the code in the main loop where it translates the sensing values to LED changes: you can use a finer granularity if you want.

Hi Erich, Thanks so much for this tutorial.
I am begginer and have a simple doubt: How a can create a file MMA8451.h?
I did not achieve to complete this step:

“Accelerometer Interface

Time to write the software :-). Using the I2C_LDD, I need to use a device data structure with flags for data received and sent. So I declare this in my header file MMA8451.h which I create and add to my project:”

Hi,
When i tried to use the MMA8451Q component in codewarrior to program KL25Z i need to configure the LDD I2C component. So, after generating the code, when i am writing to I2C it looks like i will never finish writing sccessfully. After i2c_masterSendBlock() is executed i need to get an interrupt which will get me out of this loop
do { /* Wait until data is sent */
} while (!GI2C1_deviceData.dataTransmittedFlg);

but i am not able to come out of that do while loop.
can any one please suggest a solution for my problem.

ya i have enabled the interrupts..
while debugging sometimes i will be locked in the do while loop and sometimes i will get the the state of the bus as busy while reading the CNTL_REG_1 value from the MMA8451 using GenericI2C and I2C_LDD as referenced components in MMA8451Q component .

first of all, thanks for your work. It’s far more useful and straightforward than some docs from Freescale, even if they are improving their application notes. I would like to ask your opinion about some things related to this article (most of them). I use KL05Z-FRDM board.

QUESTION 1
——————
Your code works quite well. Thanks for sharing! However, is it possible that some times it gets stuck in either:

while (!deviceData.dataTransmittedFlg) {} /* Wait until data is sent */
or
while (!deviceData.dataReceivedFlg) {} /* Wait until data is received received */

I mean if the slave devices stops working, these lines will stop the whole program, am I right?

QUESTION 2
——————
If the answer to the previous question is affirmative, which would be the simplest way to implement it in a non-blocking manner?

QUESTION 3
—————–
On the other hand, is there any way to have a dynamic timer? I mean, one which is easy to set the timeout. In the PE components (I do not know about yours), the method for setting the timeout is not available and I have to stay with the one I set using Processor Expert. And by the way, I can only set two of them with different periods, am I right?

QUESTION 4
—————–
Which other manufacturers have you worked with, and what is your comparative opinion? 🙂

Have a nice day from Barcelona! And thanks for your work again, Erich! 🙂

Hi kazola,
thanks, compliment noted, maybe Freescale recognizes that :-).
Question 1: yes, that’s correct. That’s why I have developed a GenericI2C component which has a timeout (and more) implemented.
Question 2: have a look at my GenericI2C component which features an optional TimeOut component. The basic idea is that it waits for an answer, but if it takes to long, it will return with an error.
Question 3: here again have a look at the Timeout component: it needs a single timer, and you can specify several timeout items. See the help text about using it, or see my examples using it. In that component you set a timeout resolution (e.g. 10 ms), but you can set timeouts to a multiple of that (10, 20, 30, 40, 50, 60ms, etc) depending on your needs.
Question 4: Freescale, NXP, STM, Atmel, Microchip, TI and EnergyMicro. It all depends what you need, but for me (and I’m biased 😉 Freescale has the best options with their tools, because it is Eclipse 🙂 🙂

Good Evening Mr Styger
First able thanks for posting this tutorial and make the freedom board world easier to understand. Second, what do I have to do if i want to display the information on an LCD screen rather than on the LEDs? is that possible? if yes what do I have to do in order to accomplish this task? Once again thanks for the tutorial I have learned a lot much more than on the class.

Thank you for a great tutorial. i am using KDS 2.1 with the Processor Expert. The component inspector is slightly different. Are you planning to update this tutorial to reflect differences between the Workbench and KDS?

Hello Mr. Styger,
Thanks, yes I created a project with Kinetis SDK enabled. When I create the project without the Kinetis SDK the I2C_LDD is available, but it says “ERROR: Target processor is not selected”.
Thanks for your help

Hello Mr. Styger,
I have understood that either I can use the SDK or Kinetis repository. Now I have used Kinetis repository, as you told me to do. I now have selected the processor in Kinetis. But then the error occurs that the “GPIO_PDD.h” file does not exist. Where do I get this file?

Hi Tim,
that GPIO_PDD.h usually is located here:
C:\Freescale\KDS_3.0.0\eclipse\ProcessorExpert\lib\Kinetis\pdd\inc\GPIO_PDD.h
If your project cannot find it, probably your project has not setup the proper paths?
I have this in my Includes settings for the compiler so it gets found:
“${ProcessorExpertPath}/lib/Kinetis/pdd/inc”

Dear Erich,
I am still not able to write this register. I am starting to pull my hair out with this one! 😉
It is very strange since I am perfectly able to write in CTRL_REG1! I know you are a busy man and certainly working on more great projects and tutorials right now 🙂 But if you could find a minute or two to look at this short code, I would be very thankful! https://drive.google.com/open?id=0BxWjyCzlUmsdMnpJYzEyNmdsSWc
Thanks!
Regards, Bastien

Hey Erich, Your tutorials are really very good. Have been using your posts as my reference material and I must say they are really helping me. On this tutorial, I would like to know the necessary changes so that I can be able to port the code to TWR-K60n512; like, do I need to change the slave address or what? My kit has MMA7760 accelerometer on it.

Hi meshhack,
first: thanks 🙂
About your question: yes, if the I2C address is different, then you need to change that. However the MMA7760 has different register addresses and functions, so you will need to change this as well (or: write your own driver). You could use mine as base, but things for sure will be different. You might check my MMA7260Q driver which might be close to that MMA7760 (I never have used?)

I have a problem with my board, please help me if you can. I have an program for codeWarrior but the author says I have to connect to USB (not SDA) at my board. The problem is I dont know how, in every source on the internet is about how to use the SDA. I`ve tried with the bootloader but it wasnt a succes. Could you give me a helping hand? Thank you!

Hello,
I am using a KE02Z40M with KDS3.0 and PE. The inertial sensor on my board is the same MMA8451Q. Is my understanding that using the driver code from you as is should work wrong? I have been getting a few errors and I would be happy to share them with you if you’ would be interested to take a look at it. Also I have another question instead of using the LED component , I have used the BitIO Component that is available on KDS instead of the LED componenet here and I am not not sure why we would use the GPIO_LDD. Thanks for the tutorial.

Thank you Erich. I just worked it about one hour ago. I feel so stupid. I had to restart the board again in order to see the LED colour changes. And it does happen. I was stumped initially because the SDa and SCL lines seemed perfect on the oscilloscope. It will be great to look at the values on the terminal will do that as well. Now I am off to implementing bitbanging with I2C. Thanks a ton! Really appreciate it.

Hi SaiPriya,
you don’t need to feel stupid. The thing is that if you send wrong data, the accelerometer can be stuck and does not respond any more. You can recover from this with a power cycle. It happend many times for me too. Usually if such an I2C component is critical on my boards, I add a FET so I can power cycle it from the microcontroller in case it does not respond.

The thing is that you read the raw register values, not the g values. You need to transform the raw values into acceleration values (e.g. from -1g to +1g). I recommend that you read the MMA device data sheet and description, or that you have a look at the McuOnEclipse MMA8451 Processor Expert component which can do all the conversions and calibrartion. The example in this article is very basic and does not cover these advanvced topics.