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
root@openglow_std:/sys/openglow#
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
154
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.
PWM / LEDs
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.