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
已解决! 转到解答。
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.
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!
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.
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.
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.
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.
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
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.