written at 21:19 by faberman
GPIO detection

If you should ever be in a situation where you have a piece of hardware on your bench without schematics, nobody to answer questions and you have to figure out where those pins are connected to.. gpiofinder to the rescue!

gpiofinder utilizes all GPIOs not already in use (e.g. because configured as dedicated periphery) and performs a binary search, so within log2(N) steps you should have your pin identified.

Why not as shell script? Embedded systems often have minimal shells with very limited features. Before building a full featured bash, hacking together a small C program seemed more feasable.


  1. Connect an oscilloscope or level meter to the GPO you are identifying
  2. Run gpiofinder with the maximum number of gpios as argument, e.g. 223 on the i.MX6
  3. Answer the questions with y/n:
    $ ./gpiofinder 223 Initializing all GPOs to 0.. Is the level you are looking for currently low? (y/n) y Beginning search.. Enabling 0..111..did the level go up? (y/n) y Enabling 0..55..did the level go up? (y/n) y Enabling 0..27..did the level go up? (y/n) y Enabling 0..13..did the level go up? (y/n) n Enabling 14..27..did the level go up? (y/n) y Enabling 14..20..did the level go up? (y/n) y Enabling 14..17..did the level go up? (y/n) n Enabling 18..20..did the level go up? (y/n) y Enabling 18..19..did the level go up? (y/n) y Enabling 18..18..did the level go up? (y/n) n Enabling 19..19..did the level go up? (y/n) y GPIO=19


written at 20:52 by faberman
Monkey Typer

For automated tests of user input, not connected input boards or buttons that are not there yet, I wrote this small tool to inject keypresses in the event system.


$ keysim KEY_F1 KEY_A KEY_B KEY_C

Will enter F1 a b c with a 200ms delay. For a list of all supported key names please look in the source, you can easily add new keys or other events.


A kernel with CONFIG_INPUT_UINPUT support.


written at 22:02 by faberman
IMX.6 PWM Configuration

To experiment with different PWM configurations to reduce display flickering I wrote this little tool. It reads and writes the IMX.6 registers and bypasses the Linux drivers.


$ pwmconfig -h Usage: pwmconfig [-r] ([-f val] [-d <val>]) | ([-p <val>] [-s <val>] [-P <val>] [-S <val>]) <pwmid>] -r show the register contents Automatic PWM configuration: -f set the PWM frequency for the given PWM -d set the duty cycle, 0..100 Manual PWM configuration: -p set the period value for the given PWM -s set the sample value for the given PWM -P sets the clock prescaler, 0..4095 -S sets the clock source, 0..3

Example: To set the PWM clock of PWM 1 to 15 kHz and the duty cycle to 50%, run

$ pwmconfig -f 15000 -d 50 1

To read the registers of a PWM peripheral, run

$ pwmconfig -r 1 *** PWM1 Registers PWMCR 0x03c20001 FWM FIFO Water Mark : 0 STOPEN Stop Mode Enable : 1 DOZEN Doze Mode Enable : 1 WAITEN Wait Mode Enable : 1 DBGEN Debug Mode Enable : 1 BCTR Byte Data Swap Control : 0 HCTR Half-word Data Swap Control : 0 POUTC PWM Output Configuration : 0 CLKSRC Select Clock Source : 2 PRESCALER Counter Clock Prescaler: 0 SWR Software Reset : 0 REPEAT Sample Repeat : 0 EN PWM Enable : 1 PWMSR 0x00000038 FWE FIFO Write Error Status : 0 CMP Compare Status : 1 ROV Roll-over Status : 1 FE FIFO Empy Status Bit : 1 FIFOAV FIFO Available : 0 PWMIR 0x00000000 CIE Compare Interrupt Enable : 0 RIE Roll-over Interrupt Enable : 0 FIE FIFO Empty Interrupt Enable : 0 PWMSAR 0x00001104 SAMPLE: 0x1104 (4356) PWMPR 0x00001102 PERIOD: 0x1102 (4354) PWMCNR 0x0000042d COUNT: 0x0cea (3306) *** PWM1 Configuration Period : 4354 Duty cycle : 4356/4354 = 100% PWM clock rate: 66000000 Hz PWM prescaler : 1 PWM frequency : 15158 Hz