Hey all,
I am trying to learn my way through the FRDM-KE02Z board using Kinetis Design Studio.
For this set of experiments, I am trying to communicate (I2C) with the on-board accelerometer (MMA8451Q).
Currently, I am trying to debug through consoleIO using printf, and this bit seems to work fine.
However, it would appear that I am doing something horribly wrong in the way I am trying to communicate with the I2C module...
Since I'm using the processor expert "beans," I guess I need to supply some background, so here goes:
~~~~~~~ CPU settings ~~~~~~~~~~~
CPU type: MKE02Z64VLH2 (yes, I know this is incorrect, but KDS won't let me select the VQH2 option)
Interrupts enabled
watchdog disabled
clock: 10MHz external crystal
Internal peripherals:
NMI disabled
Reset pin enabled
Flash config field disabled
MCM setting not selected
LVD module not selected
Clock Gating not selected
All CPU interrupts/resets disabled
Low power settings not selected
Clock config : ~16.8MHz bus/core clock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I have added also an internal I2C component (named Accelerometer)
This component uses I2C0 in Master mode, with an internal freq of ~4.2MHz
frequency divider bits give an SCL freq of ~95kHz with an SDA hold time of ~2.6us
I have tried using this component both with, and without the Interrupt service event enabled.
The device is set up for 7-bit addressing and high speed mode.
~~~~~~~~~ Code (Major comments removed)~~~~~~~~~~~~~~
/* MODULE main */
/* Including needed modules to compile this module/procedure */
#include "Cpu.h"
#include "Events.h"
#include "CsIO.h"
#include "IO1.h"
#include "Accelerometer.h"
#include "IntI2cLdd1.h"
/* Including shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
/* User includes (#include below this line is not maintained by Processor Expert) */
#include <stdio.h>
/*lint -save -e970 Disable MISRA rule (6.3) checking. */
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
/* Write your local variable definition here */
char AData[7] = {0,1,2,3,4,5,6}; // Funny initialization for troubleshooting
unsigned short status = 0x55;
short xG = 0;
short yG = 0;
short zG = 0;
word bytes = 0;
int error = 58;
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
/* Write your code here */
error = Accelerometer_Enable(); // enable the accelerometer
printf("Err:%3d \r\n", error);
error = Accelerometer_SelectSlave(0x1D); // accelerometer address is 0x1D
printf("Err:%3d \r\n", error);
error = Accelerometer_SendChar(0x40); // reset the accelerometer
printf("Err:%3d \r\n", error);
error = Accelerometer_SendChar(0x00); // Send start address
printf("Err:%3d \r\n", error);
error = Accelerometer_RecvBlock(AData, 7, &bytes); // read back 7 bytes
printf("Err:%3d \r\n", error);
error = Accelerometer_RecvChar(&bytes);
printf("Err:%3d \r\n", error);
status = AData[0];
// xG = (AData[1]<<8) + AData[2];
// yG = (AData[3]<<8) + AData[4];
// zG = (AData[5]<<8) + AData[6];
xG = AData[1];
yG = AData[3];
zG = AData[5];
printf("Err:%3d BytesRX:%3d Status:%3d X:%6d Y:%6d Z:%6d\r\n", error, bytes, status, xG, yG, zG);
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
/*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of RTOS startup code. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;){}
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
~~~~~~~~~~~~~~~~~~~ END CODE ~~~~~~~~~~~~~~~~~~~~~~
Running this results in the following output:
Err: 0
Err: 7
Err: 7
Err: 7
Err: 7
Err: 7
Err: 7 BytesRX: 0 Status: 0 X: 1 Y: 3 Z: 5
Error 7 seems to be "ERR_DISABLED" ???
Yesterday evening, I also saw a an error 12 "ERR_BUSOFF" ??
Any clues? Help, please? Probably something simple I'm missing, but I'd sure like to get it sorted out.
Thanks in advance,
-Tom
Solved! Go to Solution.
Hi,
In the attachments you can find a sample project which I migrated from CodeWarrior 10.6 to Kinetis Design Studio and for the FRDM-KL25 to the FRDM-KE02Z. The core is configured in FEI mode,
The application is getting data from the accelerometer and use this data to modulate PWM outputs through the RGB leds. Please check the example to have a better understanding of the Accelerometer device.
I hope this information can help you.
Regards,
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. It would be nice!
-----------------------------------------------------------------------------------------------------------------------
Hi,
In the attachments you can find a sample project which I migrated from CodeWarrior 10.6 to Kinetis Design Studio and for the FRDM-KL25 to the FRDM-KE02Z. The core is configured in FEI mode,
The application is getting data from the accelerometer and use this data to modulate PWM outputs through the RGB leds. Please check the example to have a better understanding of the Accelerometer device.
I hope this information can help you.
Regards,
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. It would be nice!
-----------------------------------------------------------------------------------------------------------------------
Last question(s) (for the moment):
1) Even though I have not checked "auto init," my init function/method is still greyed out. I can still use it in code (I think), but I'm curious about any ramifications...
2) In the examples that were attached, I see that "CheckBus" is used. Is this necessary? Should the bus be idle when the OnMasterBlockSent event is called? Or is this something for general transportability to a system that might be multitasking, etc, as a sort of semaphore between competing threads (and if so, wouldn't it make sense to set up a semaphore just for that?)
Thanks,
Tom
Answering to your questions:
Q: Even though I have not checked "auto init," my init function/method is still greyed out. I can still use it in code (I think), but I'm curious about any ramifications...
A: This init method is greyed out and also have a check mark because it indicates that this is a method you can not select if you want to generate or not the code.
Q: In the examples that were attached, I see that "CheckBus" is used. Is this necessary? Should the bus be idle when the OnMasterBlockSent event is called? Or is this something for general transportability to a system that might be multitasking, etc, as a sort of semaphore between competing threads (and if so, wouldn't it make sense to set up a semaphore just for that?)
A: In this example is no more than a security measure; in the step before the checkbus we check if the data is sent but we want also to check if the buss is now free to start another transmission. In some other application can be used as you say.
Hope this helps.
Best regards,
Adrian
Okay, I've been perusing your code, and I noticed something interesting - at least I think I did... Actually, now that I look at it, it makes sense, and I realize that I thoroughly misread the contectual help, etc... So, I'll go ahead and post my ramblings here in the hopes that they'll help someone else...
So, in common.h, the following data structure is declared:
Fine and dandy. I also see that the events generated on block sent/received "twiddle" this data structure.
Also fine and dandy, as we like our semaphores to tell us when things are done (especially when they're asynchronous), right?
So, looking at main.c, I see that a structure of the TDataState is declared (DataState)...
What I find interesting is that the pointer to this variable is handed to the init function... When I read the context-sensitive help on this function, it gives the following:
I misread this such that I thought the pointer to be handed in was the pointer referenced in the Auto-Initialization contextual help below:
I understand, now, why things were not working correctly!
So, to put the use of this particular component (and likely many others) succinctly:
1) PointerToMyData = &MyData; // (sort of)
2) DeviceDataPointer = Device_Init( PointerToMyData );
3) Device_MasterSendBlock( DeviceDataPointer, DataPointer, NumBytes, <pertinent parameters>);
Izzat about right?
Also, another question: Must the data be handed into the Send/Receive function in order for the Device_On...BlockSent/Received events to work on them, or is there another way to hand the data into those functions?
Also, I'm having some trouble figuring out this last piece (I think it's the last, anyway) - If I were to select the "Auto Init" box, what is the component name? does it remain the default name, or if I use the advanced properties to rename my I2C to "Accel" (for instance), would the device pointer become "Accel_DeviceData" ??
Are there any advantages to using the Auto Init over not using it?
One last thing (maybe), what are the ramifications to all this if I were to try to use polled mode, rather than interrupts? How do you do the checking that the data has been TXd/RXd - just check the state of the buffers? If that's the correct thinking, would I need to flush the buffers once the send/receive function has completed?
Thanks,
Tom
Answering to your questions:
Q: Must the data be handed into the Send/Receive function in order for the Device_On...BlockSent/Received events to work on them, or is there another way to hand the data into those functions?
A: Since the I2C protocol is handled by frames it is better in Processor Expert to handle all the receive and send frames with this two function which handle the coming and going blocks. Also this function handle the interrupts and check the bus traffic. For me, this is the best way to use the module using Processor Expert.
Q: If I were to select the "Auto Init" box, what is the component name? does it remain the default name, or if I use the advanced properties to rename my I2C to "Accel" (for instance), would the device pointer become "Accel_DeviceData" ??
A: If you select the Auto initialization the module will be initializated in the PE_low_level_init and a pointer to the component will be created in the .h file of the component; and every time you need to point to the component in any of it method you need to use this pointer. You can see this in the image below:
To select auto initialization or not will depend on your application for some reasons:
1. If you want to create your own pointer to the component then do not select auto initialization.
2. If you want or need to initializates the component in other part of your code that is not the PE_low_level_init function then do not select auto initialization.
Q: what are the ramifications to all this if I were to try to use polled mode, rather than interrupts? How do you do the checking that the data has been TXd/RXd - just check the state of the buffers? If that's the correct thinking, would I need to flush the buffers once the send/receive function has completed?
A: Here is where you have to say we are lucky to have Processor Expert on our side. You can check that if we do not check the Interrupt service box a new method is generated, this is the method Main. You can see this method has the complete sequence to handle the I2C protocol without interrupts.
I hope this information solve your queries.
Regards,
Adrian
Let me ask a stupid question real quick, as I can't quite seem to figure it out. In KDS, how do you open up a project that's not in the workspace?
Menu
File > Import > General > Existing Projects into Workspace
Erich
Of course, I finally figured it out just as I got your update. D'oh!
Hahah! Thank you, this is exactly what I was trying to do! I just downloaded the code and am perusing it now. Hopefully, it answers my questions!