Analog I/O Subsystem


Progress continues on development of the OpenGlow’s hardware drivers. After finishing the Thermal subsystem, I turned to the Analog I/O subsystem. I ported Glowforge’s kernel module for their SPI connected PIC microcontroller to work with the one connected via the I2C bus on the prototype board. Full source code commit can be found here.

The Analog I/O subsystem consists of a PIC 16F1713 microcontroller. The PIC provides up to 20 analog to digital converter channels, four PWM outputs, and two digital to analog outputs.

The ADC inputs are currently connected to the following: WATER_THERM1, WATER_THERM2, TEC_THERM, PWR_THERM, LID_IR_DET1, LID_IR_DET2, LID_IR_DET3, LID_IR_DET4, HV_ISENSE, and HV_VSENSE. These are primarily temperature sensors (the THERM’s). The LID IR detectors are a mystery. They appear to be IR sensors, but their exact purpose is unknown to me. The HV sensors detect the HV voltage and current.

The DAC outputs are currently connected to the following: STEP_DAC_X, and STEP_DAC_Y. These are used as analog signals to control the stepper motor drive current on the motor drivers.

The PWM outputs are used to control the lid and button LEDs.

With the addition of the PIC code the kernel module, the boot messages for the module now look like this:

openglow: loading out-of-tree module taints kernel.
openglow_init: started
openglow_pic 0-0008: pic_probe: started
openglow_pic 0-0008: pic_probe: done
openglow_thermal openglow-thermal: thermal_probe: started
openglow_thermal openglow-thermal: thermal_probe: done
openglow_init: done

And, we now have some additional user space API’s in sysfs:

root@openglow_std:/sys/openglow# ls
pic      thermal
root@openglow_std:/sys/openglow# ls pic
button_led_1    dac2_adc        hv_voltage      lid_ir_2        modalias        power           uevent          x_step_current
button_led_2    driver          id              lid_ir_3        name            pwr_temp        version         y_step_current
button_led_3    fvr_adc         leds            lid_ir_4        of_node         subsystem       water_temp_1
dac1_adc        hv_current      lid_ir_1        lid_led         pic_temp        tec_temp        water_temp_2

Analog to Digital Converters

To read an ADC input, you simply read the contents of the sysfs entry:

root@openglow_std:~# cat /sys/openglow/pic/pwr_temp

The value is a base10 representation of the ADC reading. To convert it to the voltage that is present on the PIC’s input, you use the formula (ADC_VREF / ADC_RESOLUTION) * ADC_READING. On the OpenGlow, the reference voltage is 3.3V, and the resolution is 1023 bits. This gives up a voltage reading of 0.497 V for the sample reading above.

What does 0.497 V from the power temperature sensor mean? I have no idea. The meaning of the values on most of the ADC inputs is something that still needs to be figured out.

In addition to the standard Glowforge ADC inputs, I have added the following:

  • DAC1_ADC / DAC2_ADC: The output voltages of the X_STEP_CURRENT and Y_STEP_CURRENT DAC’s.
  • FVR_ADC: The output voltage of the PIC’s internal Fixed Voltage Reference, which is used as the reference voltage for the DAC’s (2.048V).
  • PIC_TEMP: The PIC’s internal temperature sensor. Conversion details here.

Digital To Analog Converters

The DAC entries can be read from or written to. The value written is the numerator X in the formula (X/DAC_RESOLUTION) * FVR. The FVR is the PIC’s internal fixed voltage sensor (set at 2.048V). The X axis DAC has a resolution of 255, while the Y axis is 31.


The LED’s are driven by the PICs PWM outputs. The LEDs can be controlled by writing directly to the entries in the /sys/openglow/pic directory (values 0 to 1023). They also can be controlled by using the LED API’s exposed in /sys/class/leds. These API’s have a few more options:

root@openglow_std:~# ls /sys/class/leds/lid_led
brightness      max_brightness  pulse_off       speed           target          uevent
device          power           pulse_on        subsystem       trigger

I’m now working on the CNC module, and hope to have some motion soon.