Embarrassingly simple question about IO pins

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Embarrassingly simple question about IO pins

Jump to solution
13,746 Views
injunear1
Contributor IV

I have been looking for several hours and I hate to admit I don't know where else to look. All I am trying to do is read an input from PTB9 and send an output to  PTE5. I have the components installed in my program and there's a fair chance they are installed correctly.

 

I have been unable to find out how to access them from a C program. I expect I can do it by writing to and reading from the memory locations, but that is not a good idea in general. So, would anyone care to enlighten me on this obviously simple technique that I am failing to locate?

 

Thank you very much.

Labels (1)
1 Solution
4,736 Views
BlackNight
NXP Employee
NXP Employee

In case that this is still helpful: I have put together steps how to configure input and output pins using the Freedom FRDM-KL25Z board with Processor Expert:

Tutorial: Bits and Pins with Kinetis and the FRDM-KL25Z Board | MCU on Eclipse

I hope this is useful. It shows as well how to configure the reset button on the board as a normal input button.

Erich

View solution in original post

0 Kudos
6 Replies
4,736 Views
injunear1
Contributor IV

After looking at the control register for the pin (PORTB_PCR8) in the register view, it appears as though both the slew rate and pull up resistor are hard set to on.

I was not able to clear them with:

PORTB_PCR8 = (PORTB_PCR8 & 0xFFFFFFF8);

FWIW, it appears the same is true for PORTB_PCR9 as well. And PORTB_PCR10 has the slew rate set off, but the pull up resistor seems to be hard coded on.

Is this a bug or a "feature" or am I not using these pins correctly?

And where do I find a definition of "slew rate", please?

Addendum: It appears that only one pin in the entire MCU can be set for pull-down; PTA0.

See "3.10.1.2 Port Control and Interrupt Summary" in the KL25 Sub-Family Reference Manual beginning on p100.

(That one sentence could have saved me 12 hours of bit twiddling. Sigh.)

0 Kudos
4,737 Views
BlackNight
NXP Employee
NXP Employee

In case that this is still helpful: I have put together steps how to configure input and output pins using the Freedom FRDM-KL25Z board with Processor Expert:

Tutorial: Bits and Pins with Kinetis and the FRDM-KL25Z Board | MCU on Eclipse

I hope this is useful. It shows as well how to configure the reset button on the board as a normal input button.

Erich

0 Kudos
4,736 Views
injunear1
Contributor IV

THANK YOU ERICH!!!!!!

I will study your tutorial carefully.

0 Kudos
4,736 Views
injunear1
Contributor IV

I apologize for the vagueness of my question. At the time, I had been assuming this forum section was for the Freedom board only.

I am using CodeWarrior 10.3 with a FREEDOM board. I am using Win XP installed on VirtualBox on Ubuntu 12.04.

On the Freedom board I am using pins 1, 3, & 5 of J9 for input (PTB8, PTB9 & PTB10 respectively), and pins 9, 11, 13, & 15 of J9 (PTE2, PTE3, PTE4, & PTE5) as outputs to LEDs connected to P3V3 (pin 8) on the Freedom board.

For input I have a button connected from P3V3 3.3V to PTB8 and a 2 pole toggle switch connected to GND on PTB9 & PTB10.

My intent is to read an input high on PTB8 when 3.3V is applied, and lows on PTB9 or PTB10 when the respective switch is activated.

I can't find any documentation to explain how to do this. It took me a week of my own time to figure it out.

Where do I find real life examples of how to do this beyond the (admittedly excellent) beginner tutorials by Erich Styger?

I searched through the Help pages and the closest thing to helpful was for the GPIO buried in

Processor Expert Manuals - Processor Expert Components Manual - Installed Components - GPIO_LDD.

It appears this is for all the MPUs in general, so how does one know which parts to apply to the Freedom board, and which won't work at all?

I know I want to read inputs but how am I to apply engineer speak to read a bit from a port?

EG.

GetPortValue - This method returns the current port input data value. Only configured pins (through all of bit fields in this component) are returned.

ANSIC prototype: ComponentName_TPortValue GetPortValue(LDD_TDeviceData *DeviceDataPtr)

DeviceDataPtr: Pointer to LDD_TDeviceData - Device data structure pointer returned by Init method.

Return value:ComponentName_TPortValue - Unaligned current port input data value masked for allocated pins of the port. The bit 0 corresponds with the pin which has index 0 within the port, the bit 1 corresponds with the pin which has index 1 within the port, etc. Only configured pins (through all of bit fields in this component) are returned. The others are zeros.

Where does one find the definitions of:

ANSIC prototype

ComponentName_TPortValue

LDD_TDeviceData

*DeviceDataPtr is a pointer of some kind but what is it for? Where does it come from? How is it used?

It is defined with the following:

DeviceDataPtr: Pointer to LDD_TDeviceData - Device data structure pointer returned by Init method.

What is LDD_TDeviceData? I have a general understanding of what a data structure is, but how is it used to read a bit on a port? And, isn't my pin being initialized automatically at CPU start up? Does this apply to the Freedom board or is it for older boards that do not have auto init?

There was a slight example presented with the definitions. But does that apply to all the chips or just the Freedom board? And, it still does not answer how I can read a pin from a given port on the Freedom board and use it to make a decision in my program.

After perhaps 50-60 hours of experimentation (without pay) I figured out most of the answers I need.

(I would have preferred Freescale to have incorporated something as simple as the following in with their examples so I would not have had to use [effectively] a week's worth of vacation to get answers I must have in order to use their board in a new medical device I am designing.)

Here is the current program.

int MyPTB8=0, MyPTB9=0, MyPTB10=0;

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                ***/

PORTB_PCR8 = (PORTB_PCR8 | 0x2);                   // Set pin 8 to use pull up or down resistors.

PORTB_PCR8 = (PORTB_PCR8 & 0xFFFFFFFE);   // Set pull down resistor

PORTB_PCR9 = (PORTB_PCR9 | 0x3);                   // Set pull up resistor on pin 9

PORTB_PCR10 = (PORTB_PCR10 | 0x03);              // Set pull up resistor on pin 10

// Are these needed or are they redundant because the GPIO-LDD configuration set them up?

// I included them here because I can't find any other way to set PORTB_PCR8 to use a pull down resistor.

// If how the above works is not clear to others I can include an explanation.

for(;;)

{

    MyPTB8  = (GPIOB_PDIR & 0x100); // Read the bit from port B pin 8

    MyPTB9  = (GPIOB_PDIR & 0x200); // Read the bit from port B pin 9

    MyPTB10= (GPIOB_PDIR & 0x400); // Read the bit from port B pin 10

     if(!MyPTB10)

     {

  GPIOE_PDOR = 0xe7; // Turns on middle two LEDs

     }

     if(!MyPTB9)

     {

   GPIOE_PDOR = 0xDB;// Turns on outer two LEDs

     }

     if(MyPTB8)

     {

   GPIOE_PDOR = 0xFF;  // Turns all LEDs off

     }

}

The outputs now work as expected. I did have some trouble because at first I connected them to J9 p10 and when off they were still dimly lit. This appears to be because at 5V they were sinking to the 3.3V of P3V3 when the MPU output was high. Connecting them to P3V3 has corrected that problem.

[IMPORTANT NOTE: The max current any 16 consecutive pins can handle is 25 mA. And the entire MCU can only handle 100 mA. I have no idea how many mA my LEDs were drawing, so I was lucky I didn't damage the MCU. Since I am using at least a dozen pins for output, and another dozen or so for input, I need to make sure I do not overload the MCU pins. (I am using SI8660 digital isolators for all digital I/O functions. Perhaps this note will save others the trouble of finding this out the hard way and not knowing what to do about it.)]

Inputs PTB9 and PTB10 work as expected. However, I am not getting the correct response on PTB8 yet. It reads high all the time in the GPIOB_PDIR register (in the register view).

When I ground PTB8 it reads the input as expected.

How does one set it for pull down mode, please?

How are others reading and setting the header pins on this board, please?

Clearly I am missing something about how to read inputs and set outputs and I don't know where to find the answer.

Thank you.

3,651 Views
enrikm84
Contributor II

#include "MKL25Z4.h"

/* TODO: insert other definitions and declarations here. */
#define INPUT0 (0)
#define INPUT1 (1)
#define INPUT2 (2)
#define INPUT3 (3)
#define INPUT4 (4)
#define OUTPUT16 (16)
#define OUTPUT17 (17)
#define OUTPUT18 (18)
#define OUTPUT19 (19)
#define OUTPUT20 (20)
#define MASK(x) (1UL<<(x))
/*
* @ This project sets-up GPIOs on Port E
* bits 0 through 4 as GPIO inputs and bits 16 through 20 as GPIO outputs*
*/
int main() {

/* Enabling Clock on Port E. */
SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK;

/* Making pins GPIO */
PORTE->PCR[INPUT0] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[INPUT0] |= PORT_PCR_MUX(1);
PORTE->PCR[INPUT1] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[INPUT1] |= PORT_PCR_MUX(1);
PORTE->PCR[INPUT2] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[INPUT2] |= PORT_PCR_MUX(1);
PORTE->PCR[INPUT3] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[INPUT3] |= PORT_PCR_MUX(1);
PORTE->PCR[INPUT4] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[INPUT4] |= PORT_PCR_MUX(1);
PORTE->PCR[OUTPUT16] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[OUTPUT16] |= PORT_PCR_MUX(1);
PORTE->PCR[OUTPUT17] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[OUTPUT17] |= PORT_PCR_MUX(1);
PORTE->PCR[OUTPUT18] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[OUTPUT18] |= PORT_PCR_MUX(1);
PORTE->PCR[OUTPUT19] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[OUTPUT19] |= PORT_PCR_MUX(1);
PORTE->PCR[OUTPUT20] &= ~PORT_PCR_MUX_MASK;
PORTE->PCR[OUTPUT20] |= PORT_PCR_MUX(1);

/* Setting as input pins */
PTE->PDDR &= ~MASK(INPUT0) & MASK(INPUT1) & MASK(INPUT2) & MASK(INPUT3) & MASK(INPUT4);

/* Setting as output pins */
PTE->PDDR |= MASK(OUTPUT16) | MASK(OUTPUT17) | MASK(OUTPUT18) | MASK(OUTPUT19) | MASK(OUTPUT20);

/* Set pin to low */
PTE->PCOR = MASK(INPUT0); // Port E pin 0 = 0 (low)

/* Set pin high */
PTE->PSOR = MASK(OUTPUT16); // Port E pin 16 = 1 (high)

/* Toggle pin */
PTE->PTOR = MASK(OUTPUT20); // Toggle Port E pin 20
}

0 Kudos
4,736 Views
BlackNight
NXP Employee
NXP Employee

Hello,

what Processor? CodeWarrior for MCU? I would say the easiest thing would be to use Processor Expert: use a BitIO (for non-Kinetis), or use a GPIO_LDD for Kinetis/ColdFire+. If you right click on a component and select 'Help on component', then you get as well typical usage example code.

Hope this helps,

Erich