Blog Sturntech

IBM Technology Symposium 2015 – Green Maintenance Discharge in Battery Backup Applications

Hi All,

It’s been a few years since my last update of this blog. I recently presented at IBM’s 2015 Technology Symposium and decided that it was worthy of posting.

The video can be found here (enjoy!):
Sturnfield-IBM-Tech-Symposium-2015-Green-Maintenance-Discharge

Written by sturnfie

November 19th, 2015 at 7:48 pm

Changing Live Video Modes with OMAPDSS

The OMAP documentation has plenty of information on how to configure a desired video mode at boot by way of kernel boot parameters. See http://gitorious.org/linux-omap-dss2/linux/blobs/master/Documentation/arm/OMAP/DSS

Recently I was tasked with implementing a method of dynamically changing video mode timings without rebooting the system. Additionally the system is very bare-bones, consisting of essentially sysvinit, sysfs and Qt/Embedded. Size requirements dictated the absence of fbset and other nice applications in the rootfs, so a more direct route to changing the video timings was needed.

The embedded system uses a TFT LCD screen that requires a particular timing video pattern. These timings are non-VESA, meaning that while the video stream will be properly parsed by the TFT’s processor, there can be no expectation for the video stream to be parsed by any other VGA device.

The timings required for the TFT (640x480M-32@60) are:
23750,640/80/16/64,480/3/13/4

The timings for VESA compliance (640×480-32@60) are:
25175,640/40/24/96,480/32/11/2

These timings are relatively close, but different enough that distortion would appear on the opposite device. The TFT screen will show scattered lines and garbling when using the VESA-compliant timings. VGA devices would show an assortment of results when using the TFT timings, including fully functional, entirely non-functional, screen clipping, screen shifting, and distortion.

My solution was to allow our sales staff a key sequence to directly modify the timings held in the display0 entry found at /sys/devices/platform/omapdss/display0 entry. The device would boot with the TFT timings, and on a key-press, would switch to the VESA-timings. The idea is that the sales staff can switch to “projector” mode when training, allowing the audience to see a clean image at the cost of slight distortion on the handheld display.

The basic approach was the following:

# Change to TFT timings
echo “23750,640/80/16/64,480/3/13/4” > /sys/devices/platform/omapdss/display0/timings

# Change to VESA timings
echo “25175,640/40/24/96,480/32/11/2” > /sys/devices/platform/omapdss/display0/timings

Written by sturnfie

January 19th, 2012 at 3:27 pm

Designing with Gumstix Overo: SYSEN floating is a major flaw (boot failure)

Gumstix Overo Fire COM

Gumstix Overo Fire COM

I designed my first embedded system that uses a Gumstix Overo FE COM for my employer about 11 months ago. The prototype circuit passed all functional tests and my PCB layout kept clean signal isolation and near-ideal power integrity (no ground/power ripples). The Gumstix Overo was easy to interface with and aside from learning how to configure X-Load and U-Boot to properly set the OMAP pin MUXs for the various system functions, use of the module was problem-free.

The system I designed for my employer is essentially a tablet computer that is dedicated to running an analysis application that receives and processes the output of a Photon Detector. The Photon Detector interfaced to the Overo via a UART link.

During bench testing I encountered only one unresolved ambiguity. This ambiguity was an Overo Fire whose NAND chip became irreversibly corrupted at the memory location read for U-Boot’s default environmental configuration. Since my employer wished to keep the entire system software on an MMC card, and since the system was executing U-Boot from the MMC storage anyway, I modified the U-Boot source to read the default configuration from a local configuration file instead of touching the NAND. That broken Gumstix became usable after the hack and the problem has not been seen again on any system. I have not been able to replicate the error that caused only that area of the one Overo’s NAND memory to become corrupted.

So after bench validation, a unit was placed into the hands of a technician for field testing. All was well for about 4 months when I’m contacted by the technician with word that the system is no longer booting. We replaced the unit and I set about determining the root cause for how and why the system broke.

The mode of failure is describable as “failure to boot”. The Gumstix Overo had a single green LED lit (middle of row of three) when power was applied, but no other LEDs lit (in particular the blue LED on the right did not light). The three inductors on the top of the Overo had voltages matching a working Overo (L1: +1.211V, L2: +1.201V, L3: +1.801V). The serial console would chirp the following characters out the console serial line during boot “@É ¼c”.

Reading chapter 29 (Initialization) of the 35xx OMAP Technical Reference Manual (linked at bottom) indicates that the broken piece is somewhere in the Stage 1 boot of the initialization sequence. In this Stage, the OMAP CPU copies the boot code from static ROM to the RAM. The chirps on the console serial line are a boot location request by the OMAP. Properly configured, the OMAP checks the MMC and NAND modules for bootability before checking the UART(s). The fact that the OMAP was failing to check the NAND or MMC modules, but seems to check the UART indicates that there is a mis-configuration or wide-spread sub-system failure.

Regardless of how/if the ROM became corrupted, the Overo was not reaching X-Load in the NAND or the MMC card.

The cause of the problem was found to be the support circuitry initializing before the Overo’s OMAP CPU fully initialized. In particular, the level shifters (used to interface the +3.3V logic of external systems to the +1.8V logic of the Overo) were immediately in Operating mode after Power-On. The OMAP on the Overo module, however, waits for the PMIC to initialize before beginning its initialization sequence. This allowed the level shifters to pass signals to the OMAP before it was ready.

My design included the external UART serial communication from the Photon Detector. This UART line was allowed to reach the OMAP CPU pins before the chip was initialized. All other interfaces used in this design were slaves to the OMAP and would not otherwise toggle the OMAP pins without communication from the OMAP (implying the OMAP had initialized at that point). The Photon Detector sends “am-alive” pulses every 500ms.

The timing of the Photon Detector initializing and the timing of the Overo initializing had never overlapped enough to expose this flaw in bench testing. It took one occasion during field testing where the photon detector initialized extra-fast and the Overo extra-slow to create the “system not booting” problem. This occurred when the “am-alive” pulse hit the Overo during the Overo’s initialization process.

The solution to is to couple all in-bound signal interfaces to the SYSEN signal provided on the Overo’s J1 connector (pin 59). This signal pulls Low when the OMAP is ready to go. Do not pull High any I/O line directly attached to the Overo prior to the signal of SYSEN.

Some very useful information sources for debugging this problem:
The OMAP 35xx Technical Reference Manual strongly discourages letting this happen (http://www.ti.com/lit/ug/spruf98u/spruf98u.pdf).
The Gumstix Signals Document lists the pins and implies their uses (http://www.gumstix.org/images/overo_signals_latest.pdf)

Written by sturnfie

November 8th, 2011 at 2:44 pm

X-Ray + Magnification of a PIC16F877A in DIP-40 Packaging

with 2 comments

I’ve used plenty of PIC16F877A’s over the years; it’s my usual goto chip for breadboard prototypes of simple micro-controlled systems. The chip in DIP-40 packaging like this:

I was curious one day, so I stuck a chip into an X-Ray machine and took pictures at different magnifications. The actual silicon is centered in the plastic packaging. The external pin legs are wire-bonded to the silicon wafer. After seeing the construction of the large-size DIP packaging, it makes perfect sense how the same chip design can be produced in many different package sizes. Unfortunately the X-Ray machine I used did not have the resolving power to see the individual features in the silicon (that would have been cool!)



Written by sturnfie

September 16th, 2011 at 9:41 pm

Posted in PIC,xray

Configuring gdm-2.30 for Autologin using serial console

Once you’ve logged into a display manager, it’s usually easy to find the relevant applet or GUI tool to configure an automatic login procedure. This article discusses how to configure GDM for autologin when using a serial console (that is, while not in the graphical environment).

GDM is the GNOME Display Manager. Of particular value to configuring GDM is the GNOME Display Manager Reference Manual.

The correct way to configure GDM for an automatic login is to create/modify a /etc/gdm/custom.conf file. As detailed in reference manual section 5.4 (Daemon Configuration): The file /etc/gdm/custom.conf supports the “[daemon]”, “[security]”, and “[xdmcp]” group sections. If you are creating the file entirely new, this is what it needs to contain (xxxxxxx is the account to log into):

[daemon]
AutomaticLoginEnable=true
AutomaticLogin=xxxxxxx

After you modify/create this file, a restart of GDM should result in an automatic login of the specified account. A system-wide reboot will restart GDM, or you could use “/etc/init.d/gdm restart” or maybe even “restart gdm”, depending on how your system is configured.

A less-correct way to set those daemon configuration variables is to directly modify the /etc/gdm/gdm.schemas file. This file outlines an XML schema for the configuration of GDM. Search for the relevant variable names (AutomaticLoginEnable and AutomaticLogin) and change the values to those desired. Changes to this file will not survive an upgrade of the gdm package.

Written by sturnfie

June 24th, 2011 at 11:44 am

Posted in embedded,gnome,linux

Tools: Using X-Ray to pick a lock

I have this 3×10 digit padlock with an unknown combination. X-Ray seemed like a fun lock-picking tool.

Here is a picture of the padlock. The first tumbler is positioned under the top digit selector. When the tumblers are positioned correctly and the side button is pressed, plungers attached to the lock’s side button assembly are pushed into open space, allowing enough movement to open the padlock. The button on this padlock is spring-loaded, so removing pressure from the button will allow the lock to close (and retract the plungers). If the plungers are not positioned correctly (i.e. incorrect combination) the plungers’ movements will be mechanically blocked.

Below are x-ray pictures of the 3 tumblers with each of [0-9] selected. The padlock was not perfectly re-positioned between digit changes, so the tumbler is not centered across the images. I also modified the kV/mA selections as I was collecting the pictures so some of the images are a bit more saturated than others. The images were captured with the x-ray source positioned beneath the padlock and the detector assembly positioned above the padlock.

I wanted to see if using X-Ray was a feasible lock-picking technique. It turns out that it is, but I had to first figure out what to look for in the X-Ray image. The below images were captured quickly and carelessly. I freely modified multiple variables resulting in a wide range of image qualities. Enough valid information was discernible from the images to make informed guesses at the correct combination (4-2-4). The pictures of the 3rd tumbler are the best set of this bunch.

The regions of darker grey indicate more attenuation of the penetrating x-ray beam (beam is passing through more mass there). We are looking for a cylindrical cavity in each tumbler (open space for the plungers to travel). Since the button actuates in from the side of the padlock, we are looking for a cylindrical cavity that is aligned such that a plunger can enter the cavity with the motion of the button. If I was to retake these images, I would make certain the exact contours of this cylindrical cavity is seen in each picture (at each angle of rotation).

The most informational pictures as the ones that show two ovals in the tumbler. These ovals are the overlapping openings to that cylindrical cavity. As the tumbler is rotated, the cylinder can be seen to rotate as well.  When no ovals are seen, we are looking into the side of the cylindrical cavity (we see the most attenuating mass). When we see distinct ovals, we are looking through one of the openings to the cylindrical cavity, but are still looking through one of the side walls, so less mass total. If both ovals are fully overlapped, we will see a single dark circle enclosing a brighter grey, meaning we are looking exactly down the center of the cylindrical cavity.

Here are pictures of the first tumbler. These are pictures of the padlock configured for each digit 0-9.

Here are pictures of the second tumbler. These are pictures of the padlock configured for each digit 0-9.

Here are pictures of the third tumbler. These are pictures of the padlock configured for each digit 0-9.

The combination ended up being 4-2-4.

 

Written by sturnfie

April 8th, 2011 at 11:36 pm

Posted in lock-picking,tools,xray

Embedded Linux: Changing TFT-LCD screens

A general approach to changing TFT-LCD screens is documented here. The platform for this posting is OMAP3 (gumstix overo and beagleboard -xm).

The OMAP2/3 Display Sub-System is nicely documented in this dev repository.

A common method for configuring omapfb is to pass the configuration parameters as boot arguments when the linux kernel is initialized.

You can find this list in the development repository at the top of this post.
This is a listing of the configuration parameters for omapfb.
vram
- Amount of total VRAM to preallocate. For example, "10M".

omapfb.video_mode
- Default video mode for default display. For example, "dvi:800x400MR-24@60". See drivers/video/modedb.c

omapfb.vram
- VRAM allocated for each framebuffer. Normally omapfb allocates vram
depending on the display size. With this you can manually allocate
more. For example "4M,3M" allocates 4M for fb0, 3M for fb1.

omapfb.debug
- Enable debug printing. You have to have OMAPFB debug support enabled
in kernel config.

omap-dss.def_disp
- Name of default display, to which all overlays will be connected.
Common examples are "lcd" or "tv".
omap-dss.debug
- Enable debug printing. You have to have DSS debug support enabled in
kernel config.

The kernel bootloader must be modified by adding these variables to the boot arguments. If you already have a working omapfb framebuffer, then most likely these variables are already being set to non-configured values.

If you are using the U-boot bootloader (found here) then it is a simple task to modify the bootargs variable. There is a pretty good writeup by Texas Instruments detailing how to modify U-boot (found here).

My bootargs line reads:
console=ttyS2,115200n8 mpurate=500 vram=12M omapfb.mode=dvi:640x480@60 omapdss.def_disp=dvi root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait

So you’ve configured omapfb and your embedded linux system is outputting a LCD signal suitable for driving a TFT-LCD panel. If the image is distorted, a possible cause is that your particular panel is not supported by the display device driver you chose to use.

The Linux Kernel has drivers. Some of these drivers were written to support TFT-LCD screen devices.

I’d suggest finding the datasheet for the new panel. Find the timing value ranges for the pixel clock, the vertical sync pulses, the horizontal sync pulses, the “front” and “back” porches, and the data enable signals.

Here is an example set of specifications (taken from the datasheet for an NEC NL6448AC33)

Find the source code for the display device driver you are using. The display device driver was selected when the “omap_dss.def_disp” and “omapfb.mode” bootargs variables were set. The various text strings used to configure that option (example, “tv”, “dvi”, “lcd”) are mapped to a device driver in the board file used to configure the linux kernel. It is usually found in the /arch/ directory of the kernel source. For example: When configuring the linux kernel for a beagleboard, it is found at /arch/arm/mach-omap2/board-omap3beagle.c

Here are the mappings for “dvi” and “tv”:

static struct omap_dss_device beagle_dvi_device = {
.type = OMAP_DISPLAY_TYPE_DPI,
.name = "dvi",
.driver_name = "generic_panel",
.phy.dpi.data_lines = 24,
.platform_enable = beagle_enable_dvi,
.platform_disable = beagle_disable_dvi,
};

static struct omap_dss_device beagle_tv_device = {
.name = "tv",
.driver_name = "venc",
.type = OMAP_DISPLAY_TYPE_VENC,
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
.platform_enable = beagle_panel_enable_tv,
.platform_disable = beagle_panel_disable_tv,
};

The driver_name variable indicates the device driver that is being used. These are found in the /drivers/ directory of the linux kernel source. For example, the “panel-generic” driver linked to the “dvi” text can be found in /drivers/video/omap2/displays/panel-generic.c

The timings can be found near the top of this file:

static struct omap_video_timings generic_panel_timings = {
/* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
.x_res = 640,
.y_res = 480,
.pixel_clock = 23500,
.hfp = 48,
.hsw = 32,
.hbp = 80,
.vfp = 3,
.vsw = 4,
.vbp = 7,

Configuring these values to match those specified by your LCD panel should be a simple task from here. After that you can rebuild your kernel and hopefully enjoying a functional embedded display running on your new LCD.

If you need to do more than simply tune the timing values, I like to find kernel patches that modified something similar in the kernel for hints on where to look for the files I would need to modify. For the task of specifying a custom driver, here’s the kernel patch that changed a set of arch board files to use generic device drivers instead of the old default drivers (found here).

Significant development for the display you’re supporting can be submitted as a patch to the Linux Kernel Development Lists to possibly become part of the Linux Kernel and allow your work to benefit the Open-Source community.

Written by sturnfie

March 26th, 2011 at 7:36 pm

Linux: ELF file extraction of 32-bit binaries on a 64-bit system (Error)

I use OpenEmbedded and Bitbake to build cross-compiled bootloaders, linux kernels, and filesystems for embedded device projects. I’m currently working with several OMAP35x based boards (BeagleBoard, Gumstix). My development system runs on an AMD64 architecture (Ubuntu 10.10 (Maverick)). My target architecture is ARMv7.

I’ve been working on building a variation of the “omap3-sgx-modules” bitbake recipe. This recipe uses the SGX SDK provided by Texas Instruments for their access functions for off-loading the graphics-processing from the Cortex-A8 ARMv7 core to the TMS320C64x+ DSP core.

When “baking” the recipe, I was getting the following error output:
OE:beagleboard lucas@godzilla:~/oe$ bitbake omap3-sgx-modules
Build Configuration:
BB_VERSION = "1.10.2"
METADATA_BRANCH = "beagleboard"
METADATA_REVISION = "13f6179"
TARGET_ARCH = "arm"
TARGET_OS = "linux-gnueabi"
MACHINE = "beagleboard"
DISTRO = "angstrom"
DISTRO_VERSION = "2010.7-20110218"
TARGET_FPU = "hard"
NOTE: Running task 96 of 213 (ID: 13, /home/lucas/oe/org.openembedded.dev/recipes/powervr-drivers/omap3-sgx-modules_1.4.14.2514.bb, do_compile)
ERROR: Task 13 (/home/lucas/oe/org.openembedded.dev/recipes/powervr-drivers/omap3-sgx-modules_1.4.14.2514.bb, do_compile) failed with 256
ERROR: '/home/lucas/oe/org.openembedded.dev/recipes/powervr-drivers/omap3-sgx-modules_1.4.14.2514.bb' failed
NOTE: package omap3-sgx-modules-1.4.14.2514-r97: task do_compile: Started
ERROR: Function do_compile failed
Log data follows:
| NOTE: make -j 4 -e MAKEFLAGS= KERNEL_PATH=/home/lucas/oe/tmp/sysroots/beagleboard-angstrom-linux-gnueabi/kernel KERNEL_SRC=/home/lucas/oe/tmp/sysroots/beagleboard-angstrom-linux-gnueabi/kernel KDIR=/home/lucas/oe/tmp/sysroots/beagleboard-angstrom-linux-gnueabi/kernel KERNELDIR=/home/lucas/oe/tmp/sysroots/beagleboard-angstrom-linux-gnueabi/kernel KERNEL_DIR=/home/lucas/oe/tmp/sysroots/beagleboard-angstrom-linux-gnueabi/kernel KERNEL_VERSION=2.6.29-omap1 CC=arm-angstrom-linux-gnueabi-gcc -mno-thumb-interwork -mno-thumb LD=arm-angstrom-linux-gnueabi-ld AR=arm-angstrom-linux-gnueabi-ar BUILD=release
| make: *** No targets specified and no makefile found. Stop.
| FATAL: oe_runmake failed
ERROR: '/home/lucas/oe/org.openembedded.dev/recipes/powervr-drivers/omap3-sgx-modules_1.4.14.2514.bb' failed

If you didn’t modify the file and left the patches as part of the bitbake recipe, bitbake will crash on the do_patch step with a quilt-related error. It won’t make it far enough to reach the make related error statements shown above. The function call to quilt (and the call to make) fail due to missing files. These files were supposed to be extracted from an archive file that passed an md5sum check.

Very strange. A glance at the OpenEmbedded temporary work directory: oe/tmp/work/beagleboard-angstrom-linux-gnueabi/omap3-sgx-modules/ shows that only a skeleton of a filesystem was created (some folders, no files). It seems that bitbake tried to initiate the ELF-file’s self-extraction but something silently failed in the process.

The root problem was the lack of the ia32-libs libraries. This library is required to read the 32-bit ELF binary-file.

Written by sturnfie

February 18th, 2011 at 6:17 pm

IMSA Intersession 2011 – Microcontroller Projects

For this year’s Intersession we will design and implement a Persistence of Vision (wikipedia) project.

This posting is my prototype design for the course. The full course documentation can be found at http://code.google.com/p/intersession2011-pov/

POV RevA Build

Build of POV RevA

This project will be based on a PIC18F46k20 microcontroller (link). The firmware for the microcontroller will be written in C and compiled with the MPLAB C18 compiler (link). The functionality of the microcontroller will be used to turn LEDs ON and OFF. Timer modules will be used to sequence timed changing of the LEDs. An EEPROM module will be used to store LED patterns to draw POV designs. Initial POV testing of the design will be battery powered and will be waved by hand. Further testing of the design will involve mounting the design to a motor rotating at 360RPM.

Overview

The idea of this project is to use a microcontroller to create a device that can draw designs in the “air” by illuminating LEDs in sequence as the device moves through a repetitive motion. For this project, our initial repetitive motion will be generated by hand-waving the board through the air.

The example board pictured above has 8 LEDs. Each of these LEDs is independently controllable. The trick is to light the LEDs in a way that a pattern is drawn with the board’s motion.

Linear Motion: Zig Zag

For our first design we will draw a zig-zag pattern using 6 LEDs while waving the board through a linear motion. The algorithm is simple: one LED will be lit at a time, starting at one side of the 6 LEDs and moving toward the other, then the direction will reverse and the pattern will repeat. While this algorithm is running, the student will wave the board through the air. A certain amount of tuning will be required to synchronize the lighting of the LEDs with the movement of the board. This tuning can occur by changing the speed of waving or by modifying the timer interval between LED changes.

POV Linear Zig-Zag

Here is an example program to generate the above pattern. This program assumes the LEDs are all connected such that they ground into PORTB[5:0]. See the Hardware Schematic further down this page for hardware implementation details.
//linear-POV-zigzag.c for IMSAInterssion 2011

#pragma config FOSC = INTIO67
#pragma config WDTEN = OFF, LVP = OFF
#include "p18f46K20.h"

void main (void) {
// We will be shifting 0's in from a side to move the 1 (lit LED)
char pattern = 0b00000001;
char shiftDir = 0; //1 RSHIFT, 0 LSHIFT

// Set TRISB to configure PORTB as OUTPUTS
TRISB = 0;

// Configure the LATB register to set all PORTB outputs HIGH
// Remember: We are grounding the LEDs into the PORT pins.
// The LED will turn on when the pin LATB OUPUT is LOW
LATB = 0xFF;
while (1) {
// Delay some cycles between each LED change
Delay1KTCYx(5);

// We are at one end of the LED string, switch directions
if(pattern == 0b1000000){
// Change shift direction
shiftDir = 1;
}
// We are at the other end, switch directions
else if(pattern == 0b00000001){
//Change shift direction
shiftDir = 0;
}

if(shiftDir == 0){
//Left shift in a 1
pattern = pattern << 1;}

//This blog´s software currently replaces certain characters with ascii command-codes.
// The above should be two left-arrow caret symbols; serving as the LeftShift operator.

else{ //if (shiftDir == 1){
//Right shift in a 1
pattern = pattern >> 1;

//This blog´s software currently replaces certain characters with  ascii command-codes.
// The above should be two right-arrow caret symbols; serving as the RightShift operator.

}

// Set the IO pin Latches
// We need to invert the pattern bit string since
// the LEDs are wired to light when LATB is LOW
LATB = ~pattern;
}
}

Hardware Schematic

The hardware schematic for the example design at the top of this page can be found below. The schematic has the full number of LEDs installed (the example only has the first 8 installed. 6 on PORTB and 2 on PORTD). The microcontroller is configured to use an internal 16MHz oscillator. Connecting the VCC pin from the ICSP connector to the circuit’s VCC bus allows the circuit to be powered from an external programming device (such as a PICKit2) during development. A 2xAA battery compartment is used to power the circuit during operation. Alternatively, this circuit will function from any 3.3V supply.

Schematic for POV RevA Device

Rotational Motion: Zig Zag

For the rotational motion we will mount the board to a motor. I chose to use a salvaged floppy disk motor. The motor control circuitry is configured to provide a 360RPM rotation rate.

Build of the POV RevA.1 design

Here is the zig-zag POV rotational pattern.

This is the zig-zag pattern shown on a POV RevA.1

The only change to the above code was modifying the delay count in the main while loop.

The modified lines should look like:
while (1) {
// Delay some cycles between each LED change
Delay100TCYx(5);

Written by sturnfie

December 26th, 2010 at 5:11 pm

ReverseEngineering: FD1231H Floppy Disk Spindle Motor Controller

with 7 comments

This weekend I took apart a NEC FD1231H 3.5″ Floppy Disk Drive (link) with the goal of re-purposing the floppy disk motor. The primary controller board IC is marked TRN9510A and thus far I haven’t been able to find a datasheet. The disk motor assembly is on its own board, connected via a backplane ribbon cable (6 pins).

Picture of the FD1231H Floppy Disk drive internals

The disk motor assembly board has a drive controller IC marked SS300 / 86CR. The motor is permanently mounted to the disk motor assembly and is marked “Y08 8428A”. The disk motor assembly board has PCB silk markings of “Sankyo KS-46 TM95C”.

Picture of the Sankyo KS-46 Motor Drive Assembly from a FD1231H

The above picture shows the motor that I wanted to drive; conveniently mounted to a board with a pre-existing controller IC, The only interconnection to the main controller board is via the 6 pin ribbon cable. My first assumption is that all power and control signals must pass through this connection. Since I haven’t found datasheets detailing the operation of any IC in this design, I started by scraping together every scrap of information I deemed relevant.

Close-up picture of the off-board ribbon connector on the Sankyo KS-46 Floppy Disk Motor assembly

First and foremost, a connectivity test on the Primary controller board’s pins indicates that one of the ribbon pins connects to GND, another connects to +12V, and the other four each connect to pin on the primary controller IC. From the silk-screened text on the Motor Drive assembly, I found useful names describing the functions of each pin on the backplane ribbon cable.

Pin 1 – Vcc (+12V)
Pin 2 – G (GND
Pin 3 – I
Pin 4 – CLK
Pin 5 – SPD
Pin 6 –  S/S

Additional interesting silk-screen text markings include “Hv+”, “Hv-“, “Hw+”, “Hw-“, “Hu+”, and “Hu-“. This indicated to me that the motor controller IC is meant to drive a stepper motor with 3 primary coils. These markings indicate the existence of sensor amplifiers used in determining the position of the motor’s rotor.

Powering the Motor Drive assembly board with +12V on Vcc and measuring the voltage on each pin indicates that the S/S and SPD signals have weak pull-ups to Vcc (32k and 47.2k respectively), whereas CLK and I signals are provided by an external circuit.

A couple hours of googling turned up several motor controller ICs for similar applications that use similar naming conventions. Most useful were the M56787FP Spindle Motor Driver  (link) and the ZMBM1015 Brushless DC Motor Controller (link).

I was able to deduce that CLK is an external clock signal. I assumed that it would be 50% duty cycle since the destination IC is a probably a Motor Controller IC (and any PWM function would be implemented by such a controller). The S/S signal is a Start/Stop logic signal. The SPD signal seems to be a voltage variable control on the motor rotation speed. I couldn’t find any direct reference to “I”, but since the only typical control line yet missing is a motor spin direction control, I assumed that this is probably what the “I” line was for.  See the comments for a more logical purpose of pin “I”. It is commonly used as an RPM output from a sensor that monitors the rotation rate of the motor.

Simulation of the 555 timer circuit used in the FD1231H Floppy Disk Controller project

For the first test run, I decided to leave SPD untouched (pulled to Vcc) and signal “I” pulled to GND. The S/S signal I pulled to GND. The CLK signal I arbitrarily decided to generate a 300kHz 50% duty cycle square wave (since this frequency was used by one of the reference Motor Control ICs I found earlier). For the CLK signal, I used a 555 timer circuit. When interfacing the 555 output to the CLK signal line, I used a BC547 NPN transistor.

The motor spins! The S/S signal was confirmed as a Start/Stop signal (GND/Float). The SPD signal is 100% Float, decreasing with voltage dividing down from the Vcc pull-up. The “I” signal does not seem to handle spin direction control CW/CCW as thought. See the comments for the information that pin “I” is commonly used as an RPM output (presumably from the position sensor that used to be mounted on the board, opps!).

A CLK of 300kHz resulted in a pretty jerky spin motion. Reducing the frequency worsened the performance. Increasing the frequency helped a lot, with a smooth continuous rotation discovered around 1MHz. Further increases in frequency heated the motor driver IC up quite a bit, without any noticeable gain in spin performance.

Using a 1MHz CLK signal, I was able to get this motor to spin at near 360RPM (measured with light strobe).

Build of the FD1231H Motor Drive Controller Project

Written by sturnfie

December 4th, 2010 at 11:23 pm