GPIO Write operation

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

GPIO Write operation

Jump to solution
5,906 Views
Jetoleg
Contributor II

Hi, 

I have a problem  with setting value (other then all 1's or or all 0's) for group of GPIO pins .

Below is code fragment. Comments shows what's working/not working. 

For now I made clunky piece of code when I open and manipulate each pin  individually through GPIO_IOCTL_WRITE_LOGx. But I have feeling there is better way of doing it ether through ioctl() or write(). 

 

FILE_PTR port_file1;   
uint_32 set_value = 10;
uint_32 pins1[] = {
      GPIO_OUTPUT1,
      GPIO_OUTPUT2,
      GPIO_OUTPUT3,
      GPIO_OUTPUT4,
      GPIO_LIST_END
   };
port_file1 = fopen("gpio:write", (char_ptr) &pins1);

ioctl(port_file1, GPIO_IOCTL_WRITE_LOG0, NULL);         //Works! pins value 0x00
ioctl(port_file1, GPIO_IOCTL_WRITE_LOG1, NULL);         //Works pins value 0x0f

ioctl(port_file1, GPIO_IOCTL_WRITE, (char_ptr) &set_value);    //Doesn't work. Pins value 0x00

 

write(port_file1,(char_ptr) &set_value, 1);            //Doesn't work. Pins value 0x00

pins1[0]=GPIO_PIN_STATUS_1;
write(port_file1,(char_ptr) &pins1, sizeof (pins1));        //Doesn't work. Pins value 0x00

0 Kudos
Reply
1 Solution
1,686 Views
JuroV
NXP Employee
NXP Employee

Use this:

 

   GPIO_PIN_STRUCT pins[] = {
      BSP_LED1,
      BSP_LED2,
      BSP_LED3,
      GPIO_LIST_END
   };

followed by:

pins[0] |= GPIO_PIN_STATUS_1;   //LED1 on
pins[1] &= ~GPIO_PIN_STATUS_0;  //LED2 off
pins[2] |= GPIO_PIN_STATUS_1;   //LED3 on

ioctl(output_port, GPIO_IOCTL_WRITE, &pins);

 


Jetoleg wrote:
What a waste of code...

In fact, abstracting GPIO pins to behave similary to all MCUs via driver will be always waste of code. In the real consumer application deployed, you usually use direct access to GPIO registers. GPIO driver is here just not to concern to GPIO pins from the beginning of development.

Message Edited by JuroV on 2009-06-04 09:02 AM

View solution in original post

0 Kudos
Reply
9 Replies
1,686 Views
Jetoleg
Contributor II

Jeez,

only way I could use GPIO_IOCTL_WRITE command is this:

   

    pins1[0]=GPIO_OUTPUT1 | GPIO_PIN_STATUS_1;
    ioctl(port_file1, GPIO_IOCTL_WRITE, (char_ptr) &pins1);

 

But it's practically the  same as using GPIO_IOCTL_WRITE_LOG1! 

Is there any more direct way to send variable to a GPIO port? Now I have massive "Select" operation to brake incoming byte into a bits and then "if" operation to set or clear individual port pin depending on particular bit value. This is very wasteful! 

 

0 Kudos
Reply
1,686 Views
Jetoleg
Contributor II

I hate to meke this conclusion, but  I am right about GPIO_IOCTL_WRITE operation - it's not really working. All examples done by using LOG1/LOG0

 

         switch (signal) {
             case HVAC_FAN_OUTPUT:
                ioctl(output_port, (state) ? GPIO_IOCTL_WRITE_LOG1 : GPIO_IOCTL_WRITE_LOG0, 

 

What a waste of code to pass bit value to a pin!

Are there any plans to make true write/read to GPIO port? Currently, it sure looks like a real issue to me.

0 Kudos
Reply
1,687 Views
JuroV
NXP Employee
NXP Employee

Use this:

 

   GPIO_PIN_STRUCT pins[] = {
      BSP_LED1,
      BSP_LED2,
      BSP_LED3,
      GPIO_LIST_END
   };

followed by:

pins[0] |= GPIO_PIN_STATUS_1;   //LED1 on
pins[1] &= ~GPIO_PIN_STATUS_0;  //LED2 off
pins[2] |= GPIO_PIN_STATUS_1;   //LED3 on

ioctl(output_port, GPIO_IOCTL_WRITE, &pins);

 


Jetoleg wrote:
What a waste of code...

In fact, abstracting GPIO pins to behave similary to all MCUs via driver will be always waste of code. In the real consumer application deployed, you usually use direct access to GPIO registers. GPIO driver is here just not to concern to GPIO pins from the beginning of development.

Message Edited by JuroV on 2009-06-04 09:02 AM
0 Kudos
Reply
1,686 Views
OOLife
Contributor III

pins[0] |= GPIO_PIN_STATUS_1;   //LED1 on
pins[1] &= ~GPIO_PIN_STATUS_0; //LED2 off
pins[2] |= GPIO_PIN_STATUS_1;   //LED3 on
ioctl(output_port, GPIO_IOCTL_WRITE, &pins);

 

 

This code is not working correctly.

Please try as follow...

 

// write something

pins1[0] |= GPIO_PIN_STATUS_1;
pins1[1] &= ~GPIO_PIN_STATUS_0;
pins1[2] |= GPIO_PIN_STATUS_1;
ioctl(ptf1, GPIO_IOCTL_WRITE, &pins1);

 

// toggle something

pins1[0] &= ~GPIO_PIN_STATUS_0;
pins1[1] |= GPIO_PIN_STATUS_1;
pins1[2] &= ~GPIO_PIN_STATUS_0;
ioctl(ptf1, GPIO_IOCTL_WRITE, &pins1);

This code makes all LEDs to ON.

Because GPIO_PIN_STATUS_0 is defined as 0x00000000.

As a result,

    pins1[0] &= ~GPIO_PIN_STATUS_0;

this code can't change pins1[0]'s output.

 

Follow code is woring well.

 

// write something

pins1[0] |= GPIO_PIN_STATUS_1;
pins1[1] &= ~GPIO_PIN_STATUS_1;
pins1[2] |= GPIO_PIN_STATUS_1;

ioctl(ptf1, GPIO_IOCTL_WRITE, &pins1);

// toggle something

pins1[0] &= ~GPIO_PIN_STATUS_1;
pins1[1] |= GPIO_PIN_STATUS_1;
pins1[2] &= ~GPIO_PIN_STATUS_1;
ioctl(ptf1, GPIO_IOCTL_WRITE, &pins1);

FYI.

BR.

 

0 Kudos
Reply
1,686 Views
javax
Contributor I

Hi everybody

I've got same problems using GPIO driver. Before putting my question on the table, I'd like to share  the way I sometimes adrress GPIO handling. I'm working with CW 6.3 and MQX 3.6.2 and TOWER for MCF51CN128  is my  hardware plarform.

 

I made a copy of MCF51CN128.h provided by CW 6.3 and include it in my MQX project. There is a definition that is overrriden, but this didn't mean a huge problem, I just left out definition on MCF51CN128.h. Once this is included MCF51CN128.h in a code module,it is possible to drive a pin just through code lines like these.

 

 /*PortE5 is set as out put by regular instruction. No MQX driver is used*/
    PTEDD_PTEDD5 = 1;
    PTED_PTED5 = 1;

 

/*Into the task code*/

PTED_PTED5 = ~PTED_PTED5;

 

Now this is my question.

What reasons can cause an instruccion like "CSnfile = fopen("gpio:write", (char_ptr) &CSn_handler
" returns NULL????

 

In my application I constantly open and close MQX_FILE_PTR variables for handling GPIOs...and after a while (10 or 12 hours) code line:"CSnfile = fopen("gpio:write", (char_ptr) &CSn_handler" returns NULL. I have used klos to track stack use but all is OK with this.

 

Regards and thanks for your idea.

 

 

 

0 Kudos
Reply
1,686 Views
JuroV
NXP Employee
NXP Employee

It's difficult what could be the reason. Do you have multiple tasks? Perhaps one taks is opening the file and the second one closing and there is race condition.

0 Kudos
Reply
1,686 Views
Jetoleg
Contributor II
Understood. I may consider direct register access instead. Thanks for advice.
0 Kudos
Reply
1,686 Views
mjbcswitzerland
Specialist V

Hi

 

Macros are also a useful method. They are usually very portable between processors and result in direct register access.

 

Eg.

    #define _SETBITS(port, x)   PORTIN_SET##port = x
    #define _CLEARBITS(port, x) CLEAR##port = ~x

 

Examples of use:

_SETBITS(TC, PORT_TC_BIT1);

_CLEARBITS(UB, PORT_UB_BIT5) ;

 

These result in 

PORTIN_SETNQ = 0x02; and

PORTUB_SETNQ = ~0x20; respectively.

 

Assuming the registers PORTIN_SETNQ and PORTUB_SETNQ are defined accordingly:

eg. 

#define PORTIN_SETUB    *(volatile unsigned char *)(PORT_MODULE_ADD + 0x42) 

 

Regards

 

Mark

 

 

0 Kudos
Reply
1,686 Views
Jetoleg
Contributor II

Thanks folks,

My code with LOG1/LOG0 way of accessing GPIO ports works. I was just wondering if is a better way of doing it. I checked MQX source and looks like write() function is not available for GPIO driver. I'll stick to ioctl for now.

0 Kudos
Reply