Tag Archives: Raspberry pi

Device driver to interface shift reg with Raspberry pi 2

Hello Folks, after a long time my schedule allowed me to write some thing.

Today i am going to explain you the way to interface the shift register  with Linux based raspberry pi 2 board.  The shift register is the sequential logic which can used for data storage/parallel to serial conversation/ parallel to serial conversation. Hardware based stack can be constructed using several shift resister.

Shift registers are broadly distinguished in two types.

  1. Serial in, parallel out (SIPO):  In this configuration data is serially inserted in to shift register and output will be in form of parallel data bits. This is register used when more output ports are needed then available. This allows several binary devices to be controlled using only three pins, the binary controlled devices are attached to the parallel outputs of the shift register, then the desired state of all those devices can be sent out of the microprocessor using a single serial connection.
  2. Parallel in, serial out(PISO):  In this configuration parallely inserted data to shift register and output will be serial stream of bits. This configuration used to add binary inputs and give it in single stream to process. In this less micro-controller  pins are required to read the data.

This tutorials demonstrate how to interface SIPO  shift register (sn74hc595) to the raspberry pi 2. In addition to this, it explains how to write Linux device driver to control this hardware.

The sn74hc595 has an 8 bit storage register and an 8 bit shift register. Data is written to the shift register serially, then latched onto the storage register. The storage register then controls 8 output lines. Lets examine the ping configuration of sn74hc595 first. That will give us understanding about “How to drive sn74hc595 ? “.

Top_view

Ping configuration of sn74hc595

sn74hc595 register has 18 pins. which is shown in the image at left. Pin 16 is for VCC, which should be connected to 5v. Pin 8 is connected to common ground in the system. Pin number 1 to 7 and 15 is parallel data output pins.  Pin 14 is the serial data input pin.  Pin 11 is serial clock pin. when pin 11(SRCLK) goes from Low to High the value of pin 14(SER) is stored into the shift register and the existing values of the register are shifted to make room for the new bit. Pin 12 (RCLK) is used for latch. This pin should be low when data is written in the sift register. When it goes High the values of the shift register are latched to the storage register which are then outputted to pins Q0-Q7.  Pin 13 is to enable output. All latch output is enable if this pin is set to low.  Pin 10 is use for clear the output state on pins. Output pins will be cleared if low to high pulse is given to this pin. Default value of pin 10 is high.

How to co

So to drive this register, we need to control 5 pins.  Pin # 14,13,12,11 and 10. We need to connect output pins to LEDs  to check output of shift register. Based on this, we have derived a circuit diagram.

First-schamatic

Circuit diagram

Above image shows circuit diagram. Here we are using GPIOs of raspberry pi to control shift registers. RPI GPIO 9 is used as serial data line when is connected to SER(pin 14) of sn74hc595 . RPI GPIO 11 is used as latch clock line which is connected to RCLK (pin 12) of sn74hc595. RPI GPIO 25 is used as serial clock line which is connected to SRCLK (pin 11) of sn74hc595.  RPI GPIO 8 is used as serial clear line which is connected to SRCLR(pin 10) of sn74hc595. In addition to this, it is essential to connect VCC ad 5v and Common Ground with RPI.

Now, its time to design driver to control these GPIO pins. Driver will expose sysfs interface to change value represented by leds. Value which is written to this sysfs file will be represented by leds which is connected with sn74hc595.

So, lets start understanding responsibilities of init function of driver. As part of initialization of this driver, we need to Configure pin 21, 22,23 and 24 as GPIO which corresponds to GPIO 8, 9, 25 and 11.  In addition to this, we have to resigter sysfs class and device to control shift register.

Les take a deep dive  into source code of driver.  As first part we have declared to global GPIOs pins which can be used in all driver code. As per our circuit design above we have declared the pins which is shown in below code snippet.

declatation of GPIO

GPIO Declaration

As part of initialization we have to configured this pins as GPIO pins. Below code snippet configures and request this pings as GPIO. The below snippet is part of init function of driver.

requrst_GPIO

Configure Pings as GPIO

Now we have to configure this pins as output pins and set to appropriate default value.  As explained above we need to configure Pin 10(serial clock bar) to high.  The default value of all other pins will be low. The below snippet shows this.

op

Configure GPIOs as output

Lets register sysfs interface to control output of shift register.  I have created new sysfs class and device to represent shift resister.

sysfs

Registration of Sysfs interface

Every device interface in sysfs has attributes which can be read or write. Corresponding read write function registered with the attribute will get called when read or write operation performed on the this interface. Below snippet shows the registration of attribute named value with set and get value callback.

The attribute name should be the same as given by the time of creating file. Here we have given name as dev_attr_value. So out attribute is the value for which we have registered set and get routine. when we tried to read the file(sysfs Interface) from application, get_value_callback will be triggeres in the driver. In case we tried to write some value to file(sysfs Interface) from application,  set_value_callback will be triggers with the value to write in shift register.

attribute

Registration of sysfs device attribute

On low to high transmission of clock pulse,  internal register(storage register) value will shift by one and value on data pin will be moved to LSB of internal register. At the end after 8 bit data is shifted to the shift register,  by providing the latch pulse from low to high, all data from the internal register(storage Register) is latched to shift register pins. We have connected LEDs to the output pins of shift register.  This is shown by below snippet. To write some value to shift register,  it is essentials to put that value on data pin of shift register and then provide a clock pulse. On this clock pulse, data on internal register gets shifted and adds new bit(which is present on data pin) at the end presently shifted data.  So here in code, I am setting bit by bit this new_value variable on data pin and after setting one bit providing clock pulse. At the end i am providing the latch pulse so the 8 bit value which stored in the internal storage register will be  latched to the pins.

set_attribute

Routine to set value

When user application tries to  read the value from the sysfs interface, the get_value_callback will get called.  The callback will return old_value which was updated by the get value callback. The below snippet shows that. get_attribute

Here you can get full code for this driver. you can follow this steps to add module to Linux kernel source code and compile it.

Cheers !!!

Leave a comment

Filed under Linux Device Driver, Uncategorized

Virtualize(Emulate) your raspberry pi on windows…

Today, I am gonna talk about emulation of raspberry pi on windows.

This post is for specifically windows lovers 🙂

What is emulator ?

As wiki states, An emulator is hardware or software or both that duplicates (or emulates) the functions of one computer system (the guest) in another computer system (the host), different from the first one, so that the emulated behavior closely resembles the behavior of the real system (the guest).

It means that, virtual raspberry pi environment will be set up. Using which we can develop and test any application when Raspberry pi is not to hand, or when it’s not convenient or possible to power it up.

Here, in this post i am explaining to do this in four easy steps.

1. Get ARM emulator for windows

Raspberry pi has a ARM 11 based SoC. Open source processor emulator QEMU has a support for ARM architecture.  The QEMU site itself does not have a Windows binary download. Some one(Eric Lassauge) has tweaked qemu for windows. You can get latest qemu from here.

Extract the ZIP file to a folder on your PC.

2. Get kernel for raspberry pi with Qemu support

Here, are the steps to compile Linux kernel with qemu support.

To escape this step toy can just download the pre-compiled image from here.

Move this file to the QEMU folder which is created in previous step.

3. Get any of Raspi distro image

I am using the raspian “raspbmc” image. You can download this image from raspberry pi site.

Extract the file and put it in qemu folder.

4. Finally launching the emulator

Now, its time to launch the emulator with your kernel and disc image. The below command has to be hit on dos prompt on windows.

To do that, press Window button, search cmd in search bar. You will get one application named “cmd”. Open that application to write command. This is basically Dos prompt. The below image will provide you more information about it.

Finding cmd prompt in windows 7

Finding cmd prompt in windows 7

So, navigate to the directory where you have extracted qemu and all downloaded binaries.

Hit the below command to start qemu-arm for raspberry pi. In my case, i have kernel-qemu (which is downloaded in step #2) is the kernel for raspberry pi and raspbmc.img (which is downloaded in step #3)  is the image of file system.

qemu-system-armw.exe -M versatilepb -m 256 -cpu arm1176 -no-reboot -serial stdio -kernel kernel-qemu -hda raspbmc.img -append “root=/dev/sda2 panic=1”

The break down of the above command is :

1)  qemu-system-armw : the command to emulate an arm system on windows

2) -M versatilepb : the machine we need to emulate

3)  -m 256 : the amount of memory set that this version of the R-Pi has (The maximum memory size you can specify is 256Mb – that’s a limitation of QEMU for this hardware emulation – it may not work if you specify more)

4) -cpu arm1176 : the cpu we need to emulate

5) -no-reboot -append “root=/dev/sda2 panic1” : we mount our root filesystem to /dev/sda in the emulated R-Pi

installation of raspBMC

installation of raspBMC

First time,qemu will run raspbmc setup  and configure it accordingly. After setup, u will get command prompt of raspbmc.

rpi shall

rpi shall

And thats it !!!

you are done with your virtual raspi configuration.

6 Comments

Filed under Uncategorized

Make Own LED blinking Driver for Raspberry pi ….

In this post, i am going to explain step by step procedure to make simple driver which can blink led on Linux powered raspberry pi. Raspberry pi is a credit-card sized computer developed by Raspberry pi Foundation ,UK. The Raspberry pi is equipped by Brodcom BCM2835 SoC, which includes an ARM1176JZF-S core clocked with 700 MHz. Raspberry pi was originally shipped with 256 MB of RAM, later upgraded to 512 MB of RAM. This card sized computer uses the SD card for booting and data storing purpose.

This tutorial demonstrates how to develop and debug a basic hardware driver for Raspberry PI. It will demonstrate the following techniques:

  • Controlling the BCM2708/BCM2835 peripherals by accessing their hardware registers
  • Handling of interrupts in Device driver
  • Creating a sysfs device object to provide user-mode control interface

Here, for my setup i am using raspberry pi model-A. I have compiled kernel(with my led blinking driver) for raspberry pi.

Compilation of Linux kernel for Raspberry pi

1. Get the kernel Source  code for here.

2. Get the tools(cross-compiler) from here.

3. Extract both files in your home directory. Here, i have extracted in /home/bhargav/rpi/.

3. Set the environment variable CCPREFIX:
export CCPREFIX= /home/bhargav/rpi/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-

4. Set the environment variable KERNEL_SRC:
export KERNEL_SRC=/home/bhargav/rpi/linux-rpi-3.2.27

5. In KERNEL_SRC: execute “make mrproper” to ensure you have a clean kernel source tree

6. In KERNEL_SRC: execute below command  to configure  kernel source tree for raspberry pi

make ARCH=arm CROSS_COMPILE=${CCPREFIX} bcmrpi_defconfig

7. In KERNEL_SRC: execute below compile  kernel source tree for raspberry pi

make ARCH=arm CROSS_COMPILE=${CCPREFIX}

This process will give you kernel Image file at < KERNEL_SRC>/arch/arm/boot/  which can be places as kernel.img in boot partition of MMC.

Adding LED blinking device in board file

To add led blinking driver support in your build, you have to register your device in the board file of your board.

Board file for raspberry pi is located at <KERNEL_SRC>/arch/arm/mach-bcm2708/bcm2708.c which includes the subroutines for registering of all devices.

First, you need to add your header file of driver in to <KERNEL_SRC>/include/linux/ directory.

Here i am adding blinkled.h in the same directory. The below image will provide you more details about contain of file.

Header file for led blink driver

Header file for led blink driver

Include this header file in board file for raspberry pi. Add the below code in board file.

Defining a device in board file

Defining a device in board file

Here, i am declaring device named “LED_Blink” which has gpio number as a platform data on which it is connected.

Its time to register this declared device. In board file, bcm2708_init is a function which register all the peripherals devices with the kernel.

So, in this function we need to registered our device with the kernel platform bus.  Add the below line in in bcm2708_init function which register our device(“LED_Blink”) with kernel.

This device is added as platform device. I am not going in to much details of platform device, explanation can be found here.

Registration of Drivice

Registration of Device

At this stage we have registered our Led_Blink device to Linux kernel virtual bus. Now its time to write a driver for “Led_Blink” Device.

Writing driver for LED Blinking device

In the driver file, we need to declare one driver and register it with the kernel virtual bus with the same name which we gave to register device(“Led_Blink”). Linux kernel will compare the name of device and driver which is available on virtual bus and call the probe function of same driver. This is the basic concept of platform bus which is explained in the previous post.

Registration of Driver

Registration of Driver

Here, driver is declared with the  probe and remove function. Important thing is the name of the driver which is same as the device which we declared in device( In board file). Init function is the first function, which will be called on the successfully insertion of driver in the kernel. In our init function we have registered the platform driver to the bus.

On availability of the same device on the bus, kernel will calls the probe function of the same driver. So, after init function, probe will get called by the Kernel subsystem. Basically, probe will do all the initialization of device(GPIO) .

According to the BCM2835 peripheral  manual, the GPIO pins can be controlled by first configuring them as output by writing to one of GPFSELx registers and then writing to GPFSETx/GPFCLRx registers. We will define a structure describing the GPIO registers and provide functions for controlling GPIO pins using it.

Probe routine of LED blink driver

Probe routine of LED blink driver

Above snippet shows the body of probe function. In the probe function, there are three impotent things  are done.

1. Configure Pin as GPIO

The below snippet shoes the routines for set pin functionality and set output value of pin.  This functions uses the structure pointer to access the registers of SoC.

Gpio Routines

Gpio Routines

2. Setup time for On and Off timing of LED

When timer elapse, state of pin will get changed and again timer will be re initialized from timer subroutine. The snipped below shows the body of time handler.

This subroutine causes the blinking of the LED.

Timer handler subroutine

Timer handler subroutine

3. Register /sys interface  to change blink period from user domain

Sys interface is used to change the blinking period from user space. From the probe function BlinkLed_attr is registered for sys interface which has only one attribute name “period”.  User can get and set time interval using this interface. s_BlinkPeriod variable is used to store blanking period. The snippet below shows the subroutines for same.

Sys interface routines

Sys interface routines

You can download full driver code from here.

You have to add this add this module to linux source code. Here are the steps to do that.

Now, its time to compile your tweaked kernel using the steps shows above. Repeat from steps #5.

Enjoy your driver  !!!

19 Comments

Filed under Linux Device Driver