Difference between revisions of "A simple design with Wishbone bus"
Line 12: | Line 12: | ||
The main functionality of this component is to do the same things | The main functionality of this component is to do the same things | ||
− | that [[FPGA_and_led | benoît]] project : switch on a | + | that [[FPGA_and_led | benoît]] project : switch on a LED when a button is |
pressed. | pressed. | ||
Line 22: | Line 22: | ||
'''i.mx''' processor. A Linux driver on '''i.mx''' will read ''irq_mngr'' and | '''i.mx''' processor. A Linux driver on '''i.mx''' will read ''irq_mngr'' and | ||
acknowledge irq by writing '1' on a register. And finally, Linux driver will | acknowledge irq by writing '1' on a register. And finally, Linux driver will | ||
− | toggle | + | toggle LED value by writing on ''led'' register. |
[[image:Wb_buttonled_top.png|center|frame|'''figure 1''' - ''Schematics of wishbone example''|500px]] | [[image:Wb_buttonled_top.png|center|frame|'''figure 1''' - ''Schematics of wishbone example''|500px]] | ||
Line 106: | Line 106: | ||
This component is a simple 16-bit Wishbone slave output port, from [http://www.opencores.org/projects.cgi/web/wishbone/wbspec_b3.pdf wishbone specification example] (p110). | This component is a simple 16-bit Wishbone slave output port, from [http://www.opencores.org/projects.cgi/web/wishbone/wbspec_b3.pdf wishbone specification example] (p110). | ||
− | [[image:wbs_led.png|center|frame|'''figure 3''' - '' | + | [[image:wbs_led.png|center|frame|'''figure 3''' - ''LED internal structure''|600px]] |
− | It is a simple register, that can be read and write. The | + | It is a simple register, that can be read and write. The LED is controlled with register pin 0. |
The two registers are : | The two registers are : | ||
Line 154: | Line 154: | ||
The description of IRQ management module is available [[POD_Interrupt_handler | here]]. The module code source can be found [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/main.c?view=markup here]. | The description of IRQ management module is available [[POD_Interrupt_handler | here]]. The module code source can be found [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_irq_mngr/main.c?view=markup here]. | ||
− | === | + | === LED === |
− | + | LED driver is seen in linux like a character driver. Writing in dev file will enable or disable LED. | |
The driver is composed of two modules : | The driver is composed of two modules : | ||
− | * [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_led/g_led.c?view=markup g_led] : this module implement generic | + | * [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_led/g_led.c?view=markup g_led] : this module implement generic LED driver mechanisms. |
− | * [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_led/board_leds.c?view=markup board_led] : This module describe specific datas for each | + | * [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_led/board_leds.c?view=markup board_led] : This module describe specific datas for each LED-component available in design. These datas are described in structure ''plat_led_port'' and ''plat_led_device''. The module will register each LED with ''platforme_device_register'' function. When a ''plat_led__port'' device is registered, ''g_led'' driver will detect it and will probe it with ''led_probe'' function. |
=== button === | === button === | ||
Line 167: | Line 167: | ||
Button driver is seen in Linux like a character driver. When a process want to read value in button register, the driver will block reading until an interrupt occur. | Button driver is seen in Linux like a character driver. When a process want to read value in button register, the driver will block reading until an interrupt occur. | ||
− | Structure of button driver is similar to | + | Structure of button driver is similar to LED driver, it is decomposed in two modules : |
* [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_button/gbutton.c?view=markup gbutton] : This module implement generic button driver mechanisms. | * [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_button/gbutton.c?view=markup gbutton] : This module implement generic button driver mechanisms. | ||
Line 190: | Line 190: | ||
[*] Drivers for wishbone example | [*] Drivers for wishbone example | ||
<M> Wishbone Button driver | <M> Wishbone Button driver | ||
− | <M> Wishbone | + | <M> Wishbone LED driver |
<M> IRQ manager with wishbone interface | <M> IRQ manager with wishbone interface | ||
</pre> | </pre> | ||
− | + | Make linux drivers | |
<pre class="host"> | <pre class="host"> | ||
make linux26 | make linux26 | ||
Line 201: | Line 201: | ||
Then Flash [[Target_Software_Installation#Linux_kernel_installation | Linux]] and [[Target_Software_Installation#rootfs_installation | rootfs]]. | Then Flash [[Target_Software_Installation#Linux_kernel_installation | Linux]] and [[Target_Software_Installation#rootfs_installation | rootfs]]. | ||
− | === Play with button and led === | + | === Play with button and LED === |
+ | |||
+ | ==== Mount modules ==== | ||
+ | |||
+ | Modules must be mounted in right order with ''modprobe'' command : | ||
+ | |||
+ | * IRQ manager : | ||
+ | <pre class="apf"> | ||
+ | # modprobe irq_ocore | ||
+ | </pre> | ||
+ | * Button generic module must be mounted before board module: | ||
+ | <pre class="apf"> | ||
+ | # modprobe gbutton | ||
+ | # modprobe board_buttons | ||
+ | BUTTON0: MAJOR: 251 MINOR: 0 | ||
+ | button: irq registered : 193 | ||
+ | BUTTON0 insered | ||
+ | </pre> | ||
+ | * LED generic module must be mounted before board module: | ||
+ | <pre class="apf"> | ||
+ | # modprobe g_led | ||
+ | # modprobe board_leds | ||
+ | LED0: MAJOR: 252 MINOR: 0 | ||
+ | LED module LED0 insered | ||
+ | </pre> | ||
+ | |||
+ | ==== Device access ==== | ||
+ | |||
+ | Devices access are done with special caracters file. These file must be created with major and minor number given when modules are mounted (see ''Mount modules'' above in this page) : | ||
+ | |||
+ | * Make LED access : | ||
+ | <pre class="apf"> | ||
+ | # mknod /dev/led0 c 252 0 | ||
+ | </pre> | ||
+ | * Make button access : | ||
+ | <pre class="apf"> | ||
+ | # mknod /dev/button0 c 251 0 | ||
+ | </pre> | ||
+ | |||
+ | ==== Test LED ==== | ||
+ | |||
+ | A test program is available in [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_led/testled.c?view=markup module directory], simply compile it with arm-linux-gcc compiler : | ||
+ | |||
+ | <pre class="host"> | ||
+ | $ arm-linux-gcc testled.c -o testled | ||
+ | </pre> | ||
+ | |||
+ | Download it in apf, then test it : | ||
+ | <pre class="apf"> | ||
+ | # ./testled /dev/led0 | ||
+ | Testing led driver | ||
+ | Read 1 | ||
+ | Write 0 | ||
+ | Read 0 | ||
+ | Write 1 | ||
+ | Read 1 | ||
+ | Write 0 | ||
+ | Read 0 | ||
+ | </pre> | ||
+ | |||
+ | LED is blinking slowly. | ||
+ | |||
+ | ==== Test Button ==== | ||
+ | |||
+ | A test program is available in [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/wb_button/testbutton.c?view=markup module directory], simply compile it with ''arm-linux-gcc'' compiler : | ||
+ | |||
+ | <pre class="host"> | ||
+ | $ arm-linux-gcc testbutton.c -o testbutton | ||
+ | </pre> | ||
+ | |||
+ | <pre class="apf"> | ||
+ | # ./testbutton /dev/button0 | ||
+ | Testing button driver | ||
+ | Read 1 | ||
+ | Read 0 | ||
+ | Read 1 | ||
+ | Read 0 | ||
+ | Read 1 | ||
+ | Read 0 | ||
+ | Read 0 | ||
+ | Read 1 | ||
+ | Read 0 | ||
+ | Read 1 | ||
+ | </pre> | ||
+ | |||
+ | Each button push or release activate reading register value. | ||
+ | |||
+ | ==== Switching LED with button ==== | ||
+ | |||
+ | A simple program is available in [http://armadeus.svn.sourceforge.net/viewvc/armadeus/trunk/target/linux/modules/fpga/wishbone_example/push-led.c?view=markup wishbone example directory] to switch on the LED when button is pressed. | ||
+ | |||
+ | To compile : | ||
+ | <pre class="host"> | ||
+ | arm-linux-gcc push-led.c -o push-led | ||
+ | </pre> | ||
+ | |||
+ | To use it, simply type : | ||
+ | |||
+ | <pre class="apf"> | ||
+ | # ./push-led /dev/button0 /dev/led0 | ||
+ | Blink a led pushing button | ||
+ | </pre> | ||
+ | |||
+ | Push the button to switch on the LED. |
Revision as of 11:34, 9 March 2009
Page under construction...
Informations on this page are not guaranteed !!
This article intended to explain how to design Wishbone compatible components with simple example. The VHDL code sources can be found in sourceforge tree.
Description of wishbone structure for ARMadeus can be found here in french.
Contents
General structure
The main functionality of this component is to do the same things that benoît project : switch on a LED when a button is pressed.
But to learn about designing Wishbone component and linux driver, the design is little bit more complicated (!).
When button is pressed, the component button send interrupt signal to irq_mngr. irq_mngr will toggle a flag and send interruption to i.mx processor. A Linux driver on i.mx will read irq_mngr and acknowledge irq by writing '1' on a register. And finally, Linux driver will toggle LED value by writing on led register.
imx_wrapper, syscon and irq_mngr are standards ARMadeus-Wishbone IPs that just been instantiated in our design.
button and led are simple slave component we want to integrate in the FPGA.
All these components are connected together with the 'glue logic' component intercon.
Wrapper
The wrapper is used to convert i.MX interface signals into Wishbone signals. Table above show signals from i.MX and signals to wishbone conversion :
i.MX signals | function | Wishbone signals |
---|---|---|
imx_address(12) | Address vector | wbm_address(13) |
imx_data(16) | Data vector | wbm_writedata(16) and wbm_readdata(16) |
imx_cs_n | Chip select | wbm_strobe and wbm_cycle |
imx_oe_n | Read signal | /wbm_write |
imx_eb3_n | Write signal | wbm_write |
- | Acknowledge | wbm_ack |
Intercon
The intercon is a component used to manage signal between wishbone master and slaves component. This component decode Wishbone-master addresses and dispatch its to Wishbone-slave components.
Wishbone slave application components
In this example their are 3 wishbone-slave components :
irq manager
Some component (here, just button) generate interrupts, irq manager is used to group these interrupts for i.MX. The irq_mngr can manage up to 16 internal interrupts.
IRQ manager component has tree registers, one to enable interrupts, one for flags/acknowledge interrupts and one identification register :
register | function |
---|---|
mask | write '1' to allow irq |
ack/pend | read for pending irq, write to acknowledge irq |
id | identification register |
wb_led
This component is a simple 16-bit Wishbone slave output port, from wishbone specification example (p110).
It is a simple register, that can be read and write. The LED is controlled with register pin 0.
The two registers are :
register | function |
---|---|
LED | Write '1' in LSB to shutdown LED |
id | read identification number |
wb_button
Wb_button component, is like led but in read only and with an edge detector to rise irq.
The two registers are:
register | function |
---|---|
Button | read LSB to know button state |
id | read identification number |
Components drivers
Each component is drove with a Linux driver described above. All driver code is in armadeus directory in target/linux/module/fpga/wishbone_example/.
Each component has an identification register with unique number. This number is used by driver to unsure that device is present when it modproded.
irq manager
The description of IRQ management module is available here. The module code source can be found here.
LED
LED driver is seen in linux like a character driver. Writing in dev file will enable or disable LED.
The driver is composed of two modules :
- g_led : this module implement generic LED driver mechanisms.
- board_led : This module describe specific datas for each LED-component available in design. These datas are described in structure plat_led_port and plat_led_device. The module will register each LED with platforme_device_register function. When a plat_led__port device is registered, g_led driver will detect it and will probe it with led_probe function.
button
Button driver is seen in Linux like a character driver. When a process want to read value in button register, the driver will block reading until an interrupt occur.
Structure of button driver is similar to LED driver, it is decomposed in two modules :
- gbutton : This module implement generic button driver mechanisms.
- board_button : Like LED module, this module describe specifics datas for each button-component available in design.
Using the design
All code for this design is available in ARMadeus tree, firmware (VHDL) and software (Linux drivers).
Make the FPGA bitstream
ISE Webpack is mandatory to generate the bitstream, then its installation is required. Once bitstream generated, it can be downloaded in FPGA with U-Boot or Linux.
Compile Linux drivers
To compile driver for this design select it in make linux26-menuconfig :
Device Drivers ---> Armadeus specific drivers ---> FPGA Drivers ---> [*] Drivers for wishbone example <M> Wishbone Button driver <M> Wishbone LED driver <M> IRQ manager with wishbone interface
Make linux drivers
make linux26
Play with button and LED
Mount modules
Modules must be mounted in right order with modprobe command :
- IRQ manager :
# modprobe irq_ocore
- Button generic module must be mounted before board module:
# modprobe gbutton # modprobe board_buttons BUTTON0: MAJOR: 251 MINOR: 0 button: irq registered : 193 BUTTON0 insered
- LED generic module must be mounted before board module:
# modprobe g_led # modprobe board_leds LED0: MAJOR: 252 MINOR: 0 LED module LED0 insered
Device access
Devices access are done with special caracters file. These file must be created with major and minor number given when modules are mounted (see Mount modules above in this page) :
- Make LED access :
# mknod /dev/led0 c 252 0
- Make button access :
# mknod /dev/button0 c 251 0
Test LED
A test program is available in module directory, simply compile it with arm-linux-gcc compiler :
$ arm-linux-gcc testled.c -o testled
Download it in apf, then test it :
# ./testled /dev/led0 Testing led driver Read 1 Write 0 Read 0 Write 1 Read 1 Write 0 Read 0
LED is blinking slowly.
Test Button
A test program is available in module directory, simply compile it with arm-linux-gcc compiler :
$ arm-linux-gcc testbutton.c -o testbutton
# ./testbutton /dev/button0 Testing button driver Read 1 Read 0 Read 1 Read 0 Read 1 Read 0 Read 0 Read 1 Read 0 Read 1
Each button push or release activate reading register value.
Switching LED with button
A simple program is available in wishbone example directory to switch on the LED when button is pressed.
To compile :
arm-linux-gcc push-led.c -o push-led
To use it, simply type :
# ./push-led /dev/button0 /dev/led0 Blink a led pushing button
Push the button to switch on the LED.