Drivers

From Spykee Developer Wiki

Jump to: navigation, search

Contents

GPIOS

GPIOS are available in 2 ways :

 - with /dev/gpio (output only)
 - with /dev/mem (input and output)

Device: /dev/gpio

Controls peripherals on Spykee.

GPIO Mapping:

0  - LED_0                            16 -
1  - LED_1                            17 -
2  - LED_2                            18 -
3  - LED_3                            19 -
4  -                                  20 -
5  -                                  21 -
6  -                                  22 -
7  -                                  23 -
8  -                                  24 -
9  -                                  25 -
10 -                                  26 -
11 -                                  27 -
12 -                                  28 -
13 -                                  29 -
14 - Reset                            30 -
15 -                                  31 -


Known ioctls:

IOCTL_OP_GPIOMODE  0x400cbb01   // Sets the Gpio Mode (Input/Output, with interrupts, flashing etc..)
IOCTL_OP_GPIO      0x4008bb03

Example of Use (Toggling a led on or off):


sprintf(device, "%s", "/dev/gpio");
m_GpioFd = open(device, O_RDWR);
[..]

long buf[2];
buf[0] = <LED_NUMBER>;  // LED_NUMBER is the GPIO Pin
buf[1] = <LED_STATE>;   // 0 or 1
ioctl(m_GpioFd, OP_GPIO, buf);

Example of Use (Changing GPIO Mode):

long Buf[3];
Buf[0] = <Selected PIN [0..31]>;
Buf[1] = <Pin Direction; 0 = Out ; 1 = In>;
Buf[2] = <Interrupt Mode; 1 = no interrupt ; 3 = interrupt mode>;
ioctl(GpioDev, IOCTL_OP_GPIOMODE, Buf);


Device: /dev/mem

with /dev/mem, we access GPIO by reading / writing 16 bits registers directly in memory.

GPIO are divided in 2 parts :

GPIO_L for IO 0..15
GPIO_H for IO 16..32

GPIOL control registers :

  - GPIOL_SELECT7_0  (@ 0x8000D000) -> usage unknown : default value in system = 0x5555
  - GPIOL_SELECT15_8 (@ 0x8000D004) -> usage unknown : default value in system = 0x5555
  - GPIOL_BIDIR_CTRL (@ 0x8000D008) -> bidir control of IO (1=Input / 0=output). exemple 0xff00 -> IO 0..7 are output and IO 15..8 are input
  - GPIOL_OUTPUT     (@ 0x8000D00C) -> output value for IO 0..16
  - GPIOL_INPUT      (@ 0x8000D010) -> input  value of IO 0..16
  - GPIOL_IER        (@ 0x8000D014) -> usage unknown
  - GPIOL_IMR        (@ 0x8000D018) -> Interrupt Mask Register (?)

GPIOH control registers :

  - GPIOH_SELECT7_0  (@ 0x8000D500) -> usage unknown : default value in system = 0x5555
  - GPIOH_SELECT15_8 (@ 0x8000D504) -> usage unknown : default value in system = 0x5555
  - GPIOH_BIDIR_CTRL (@ 0x8000D508) -> bidir control of IO (1=Input / 0=output). exemple 0xff00 -> IO 0..7 are output and IO 15..8 are input
  - GPIOH_OUTPUT     (@ 0x8000D50C) -> output value for IO 0..16
  - GPIOH_INPUT      (@ 0x8000D510) -> input  value of IO 0..16
  - GPIOH_IER        (@ 0x8000D514) -> usage unknown
  - GPIOH_IMR        (@ 0x8000D518) -> Interrupt Mask Register (?)

Example of Use :

#define GPIO_BASE       0x8000D000
#define GPIO_BIDIR_CTRL 8
#define GPIO_OUTPUT     12
#define GPIO_INPUT      16

unsigned char *gpio; 
volatile unsigned int *PEDR;

sprintf(device, "%s", "/dev/mem");
m_GpioFd = open(device, O_RDWR);

gpio = (unsigned char *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, m_GpioFd, GPIO_BASE); 

PEDR = (unsigned int *)(gpio + GPIO_BIDIR_CTRL);
*PEDR = 0x8001;                                     //set IO 15 and 0 to input
PEDR = (unsigned int *)(gpio + GPIO_INPUT);
printf("Reading IO 15..0 = %x",*PEDR);              //state of input 15..0


At this time, the only available IO on Hardware are IO 0..3 (Led control) mapped to J14 connector (Access with GPIOL registers).

IO are output only because a LVC04 chip (hex inverter) is between IO_ports of the ARM and the J14 connector.


WARNING :

Followings instructions can permanently damage your spykee.

To use IO port 0 as an input, which is enough to implement a bidirectional serial link, 2 solutions :

 - solder a wire directly on the pin1 of the hex-inverter, which is wired directly to IO PORT 0 of the ARM processor (easiest solution)
 - remove pin 1 and 2 of the hexinverter, and strap the free pad of pin 1 and pin 2 together. With this, IO 0 is always available on J14 connector.


Serial Control Port

Device: /dev/ttyS1

The serial control port is a serial port that control the battery module, the motor controller and the IR receiver.


Motor controller

The motor controller uses a 3 bytes protocol.

1st byte == direction
2nd byte == Speed of Left Track
3rd byte == Speed of Right Track


Direction Truth table (bin/hex)

Value Track Left Track Right
00000001 (0x01) Forward Forward
01000001 (0x41) Forward Reverse
10000001 (0x81) Reverse Forward
11000001 (0xC1) Reverse Reverse


Speed Values

0   == off
1   == Maximum Speed
255 == Minimum Speed


Battery and IR status

The Charging circuit is controlled by the i2c-algo-mv88w8xx8_pcf50633.ko module. The PCF50633 datasheet can be found here : http://people.openmoko.org/tony_tu/GTA02/datasheet/PMU/PCF50633DS_02.pdf

To get status, send 0x02 and read 5 bytes


Byte 1 = 0x80 (Acknowledge)

Byte 2 = Charging status

      bit 7 = Charging status (0 = charging in progress)
      bit 6 = state of the charge button under the spykee (0 = button pressed)
      bit 5 = ?
      bit 4 = ?
      bit 3 = MSB of Base Voltage
      bit 2 = MSB of Base Voltage
      bit 1 = MSB of Batt Voltage
      bit 0 = MSB of Batt Voltage

Byte 3 = Battery voltage (Using bit 0 and 1 of Byte 2 as MSB, making Battery Voltage a 10bits value)

Byte 4 = Base Voltage (Using bit 2 and 3 of Byte 2 as MSB, making Base Voltage a 10bits value)

Byte 5 = State of the 4 IR leds

      bit0 = RF led
      bit1 = LN led
      bit2 = RN led
      bit3 = LF led

Voltage Conversion, from raw value to Actual voltage : VoltageValue = (RawValue * 0.017) + 0.4

Battery Charge command

Send 0x03 => enable charging

Send 0x83 => disable charging


WARNING : charging process must be stopped when the battery is fully charged. If not, you will damage your spykee.


IR receiver

To be able to read the 4 IR leds state, you must enable the IR receiver

Send 0x84 => IR receiver enable

Send 0x04 => IR receiver disable

Kernel Module ov530

Device: /dev/video0

ov530 Spykee video driver, module file ov530.ko. I2C configuration + USB Frames.

Video4Linux API, except for some custom ioctls.

Known ioctls:

IOCTL_CAMERA_LED                   0x4004756b
IOCTL_CAMERA_GET_PICTURE           0x80107606
IOCTL_CAMERA_WAITFRAME_INACTIVE    0x4020760a
IOCTL_CAMERA_INIT_SENSOR_VGA       0x40047568
IOCTL_CAMERA_INIT_SENSOR_QVGA      0x40047569
IOCTL_CAMERA_INIT_SENSOR_176X144   0x4004756f
IOCTL_CAMERA_SENSOR_SET_PICTURE    0x40107607
IOCTL_CAMERA_I2C_W_SLAVE           0x400476c5
IOCTL_CAMERA_NEW_FRAME             0x40107613
IOCTL_CAMERA_WAITFRAME             0x40047612
IOCTL_CAMERA_I2C_R_SLAVE           0xc00476c6
IOCTL_CAMERA_GET_MAP               0x80887614

Camera Led

Control the camera led with IOCTL as follow :

   ioctl(m_VideoFd, IOCTL_CAMERA_LED, buffer)

with

buffer[0]=Led_state; // 1 = Led ON

buffer[1]=1; //led address

Personal tools
donation
Google AdSense