All times are UTC-06:00




Post new topic  Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Fri Jun 13, 2008 2:42 am 
Offline

Joined: Fri Jun 13, 2008 1:35 am
Posts: 5
Location: Germany
Greetings,

I am working with a MPC5200B (-tiny) board and I need to configure some of the GPIOs. I tried to find some help, but the manuals aren't quite as helpful as i thought.

I already know that i have to do this with the MBAR and the appropriate offsets, but i don't know how i can access this register and if i can do this from within my application or have to implement this in the kernel or as a module/driver.

I want to use the GPIO pins to receive a MPEG transport stream, so any other information on pinhandling and how to correctly retrieve data from the pins would be very helpful.

Thanks in advance


Top
   
PostPosted: Fri Jun 13, 2008 3:44 am 
Offline
Site Admin

Joined: Fri Sep 24, 2004 1:39 am
Posts: 1589
Location: Austin, TX
Quote:
I am working with a MPC5200B (-tiny) board and I need to configure some of the GPIOs. I tried to find some help, but the manuals aren't quite as helpful as i thought.
They have all the information you need :)

Toggling a GPIO is about as easy as it gets.
Quote:
I want to use the GPIO pins to receive a MPEG transport stream, so any other information on pinhandling and how to correctly retrieve data from the pins would be very helpful.
How many pins are you using?

You will have to do it from a kernel module since accessing the memory space the MPC5200B is at is in kernel space and not user space. You will probably need to make sure your GPIO node in the device tree is set up correctly; there are patches on the LinuxPPC list for this (and GPIOLIB stuff).

As for how to work the GPIOs, if you want to be informed of data coming in, you need to use a Wakeup pin so that an interrupt is generated. If you are only pulling in the stream regardless, then you needn't do anything but sample the data on the pin once set to "input".

What you need to do is find out which GPIO pins you have available and then resolve them somehow to the diagram on the MPC5200BUM document page 7.3.2.1.1 - setting the appropriate bits at MBAR+0xb00 to 0 will configure these pins as GPIO rather than anything else. In any well-designed system this should already be set up (all pins default to GPIO).

The following pages are the toggle bits for each GPIO type (MBAR+0xb04, 0xc00..)- set to 0 for nothing and 1 to raise the line to send a "bit". It will stay high until you flip it back to 0. The data direction register tends to whether you are sampling input or sending output (the bits to set output are at 0xb04 for simple gpio, and the bits to check the input data are at 0xb14 for the same GPIO block. There are multiple GPIO blocks).

It really is as simple as

* Set Direction of the Pin
* Make sure you are reading the right register for that pin
* Set the data for output and/or
* Check the data for input and/or
* Register an interrupt for wakeup THEN check the data for input

It's all discussed in chapter 7.3..

_________________
Matt Sealey


Top
   
 Post subject:
PostPosted: Fri Jun 13, 2008 4:42 am 
Offline

Joined: Fri Jun 13, 2008 1:35 am
Posts: 5
Location: Germany
Thanks for the help.
I tried to read the UM but as i said i can't seem to get my head around this.


So I got the address of the MBAR (0xF0000000) and the offset for the Port Configuration Register (0x0b00).

Then I would, for example, set pins 4,5,9,10,11,20,21,22, and 23 to 0 to configure PSC3, PSC6 and LP_CS6 and 7 as GPIOs.

Is setting the GPIO Enables register at offset 0x0b04 necessary, because it seems I can't enable GPIO for all pins?

Then I would need to set the GPIO Data Direction at 0x0b0c to set my pins as input.

At the GPIO Data Input values register at 0x0b14, the appropriate bits of the register would indicate whether i received 1 or 0 on this pin. Or is there a buffer where i can collect whole bytes or do I have to put the bits to bytes and so on?

I previously did work on windows applications and I did a little bit on a microchip PIC, so please excuse me if i sound a bit slow in this matter.

Never really worked with Linux extensively before and my experience with Kernels and modules is limited at best, so I thought I could do it from my application.

Does this mean I have to write a module like topic : anyone using i2c?
Or could I modify the kernel where the GPIO are set and compile the kernel again and update the board by bootloader.

I can't tell what would be simpler and easier to accomplish.

I suppose I don't need an interrupt and could just keep polling the pins for the streamed data.

I will try to take a look at GPIOLIB on how i could implement this but any (really any) help would be greatly appreciated.

Thanks in advance.

Dave


Top
   
 Post subject:
PostPosted: Fri Jun 13, 2008 4:53 pm 
Offline
Site Admin

Joined: Fri Sep 24, 2004 1:39 am
Posts: 1589
Location: Austin, TX
Quote:
Is setting the GPIO Enables register at offset 0x0b04 necessary, because it seems I can't enable GPIO for all pins?
Yes, remember there are two major types of GPIO - simple and wakeup - so two blocks to enable the GPIO pins. You need to look at 0xc00 as well as 0xb04. If you don't enable them, they stay low.

(edit, 14th June) there's also the GPT GPIO which I think are on another block..
Quote:
Then I would need to set the GPIO Data Direction at 0x0b0c to set my pins as input.
.. and 0xc08 too.
Quote:
At the GPIO Data Input values register at 0x0b14, the appropriate bits of the register would indicate whether i received 1 or 0 on this pin. Or is there a buffer where i can collect whole bytes or do I have to put the bits to bytes and so on?
If you are receiving bytes (using 8 pins) then you should use a wakeup pin on one of the bits, then using masking and or'ing them together, combine your own byte from it.
Quote:
Never really worked with Linux extensively before and my experience with Kernels and modules is limited at best, so I thought I could do it from my application.
Writing a kernel module is pretty simple. The very start is that forum post on Power Developer you mentioned in your post. Handling interrupts (because you do not want your kernel driver to constantly poll the GPIO port 8 times for every byte even when there is no new data).
Quote:
I suppose I don't need an interrupt and could just keep polling the pins for the streamed data.
You could work out some way of configuring your data input so that when data is not being sent, another GPIO input pin is set low. When it is set high, you know you need to be sampling data constantly and buffering it for userspace (or dropping it). Having that input pin as a wakeup pin means you can receive an interrupt as and when it changes, and save polling.

After all, polling is dead slow and will cripple your system if you're not careful.
Quote:
I will try to take a look at GPIOLIB on how i could implement this but any (really any) help would be greatly appreciated.
It's just a simpler way of accessing the GPIO registers without having to know the gory details, although someone needs to have written a chip driver for it, I am sure someone already did for the MPC5200B. Just take a look at the link there and read the code, it's ridiculously simple, and kind of makes this discussion redundant :)

You even get to abstract the masking off, and just get an int back (1 or 0) so you can just shift it back into a byte. That may be a little more inefficient, I was thinking about adding some kind of switch so you could get a raw bit back (just the masked off relevant bit, not the shift) so people can collate known GPIO inputs and offsets into a integers more efficiently. However with function call overhead and MMIO overhead, saving that amount of time probably just isn't worth it at all.

Even with GPIOLIB, you still need to deal with how you would move that data to your application, and the kernel module.

_________________
Matt Sealey


Top
   
 Post subject:
PostPosted: Fri Jun 20, 2008 5:36 am 
Offline

Joined: Fri Jun 13, 2008 1:35 am
Posts: 5
Location: Germany
Sorry for the long delay,

I tried the gpio-patch you linked, but it won't compile with/into my kernel. I supposed it's because my MPC5200B has a 2.6.23.1 kernel and from what I could find the gpiolib with the neccesary headers and such starts with 2.6.25.

As i couldn't work with this i tried my luck again on modules.

My makefile looks like this:
Quote:
obj-m := testmod.o

KDIR := /home/db/kernelsrc
PWD := $(shell pwd)

default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
And naturally
Quote:
make ARCH=powerpc CROSS_COMPILE=powerpc-603e-linux-gnu-

As a source of "inspiration" I used the "lite5200.c" which is found in kernelsrcdir/arch/powerpc/platforms/52xx. Therein some GPIOs are configured in its "lite5200_setup_cpu" function.

With the help of this, I could use the ioremaps of the iomem-structures "mpc52xx_gpio" and "mpc52xx_gpio_wkup" found in "asm-powerpc/mpc52xx.h" to address the necessary bits.
in_be32(..)/in_8(..) and out_be32(..)/out_8(..) could be used to read and set the bits.

As the UARTs are partly reconfigured as GPIO I lose some ability to communicate and receive information but I can still work with telnet or ssh.

Is there a way to print information to my console from kernel, as I seem to be unable to use printf in my module? Printk only prints to the syslog or my serial port.

In the exit function I reset the necessary configuration with values from before my fiddling with the MBAR.

My next step is to gain access to the databits and manipulate them.

I should be able to create a user-app which calls "insmod testmod.ko" and "exmod testmod" to start or exit the module, but as I have again no access to the MBAR where my input values are I have to create a /dev/file or a /proc/file which is accessible from my app.
At first I tried to implement a buffer in /proc like in http://www.captain.at/howto-linux-kerne ... e-fifo.php
to get to know how it works, but it creates only a read buffer/entry and i have problems removing the /proc files when unloading the module.
remove_proc_entry(..) gives me badness errors.

I can't seem to find any help on this.


Is using the /proc the right way or would it be better to use /dev ?

How can I correctly handle the incoming data? I use 8 pins for data, which i would have to bitshift to get the desired byte, 1 pin for a data validation signal , 1 pin for bytestart-condition and 1 clock signal.

Can dynamically write data to my byte-buffer from the module while it is running or da I have to do this in another way. I think I can use my data valid or clock signal to create an interrupt to check the other pins to get my data.

Any hints appreciated.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 5 posts ] 

All times are UTC-06:00


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
PowerDeveloper.org: Copyright © 2004-2012, Genesi USA, Inc. The Power Architecture and Power.org wordmarks and the Power and Power.org logos and related marks are trademarks and service marks licensed by Power.org.
All other names and trademarks used are property of their respective owners. Privacy Policy
Powered by phpBB® Forum Software © phpBB Group