Browse Source

Basic hardware test examples for adc and gpio + define hardware setup (#3324)

Nathaniel Wesley Filardo 3 years ago
parent
commit
49b09d050e
4 changed files with 308 additions and 2 deletions
  1. 2 2
      tests/NTest/NTest.lua
  2. 61 0
      tests/NTest_adc_env.lua
  3. 88 0
      tests/NTest_gpio_env.lua
  4. 157 0
      tests/NodeMCU_Test_Environment.rst

+ 2 - 2
tests/NTest/NTest.lua

@@ -202,8 +202,8 @@ local function NTest(testrunname, failoldinterface)
 
       env.eq = deepeq
       env.spy = spy
-      env.ok = function (cond, msg1, msg2) wrap(assertok, false, cond, msg1, msg2) end
-      env.nok = function(cond, msg1, msg2) wrap(assertok, true,  cond, msg1, msg2) end
+      env.ok = function (cond, msg) wrap(assertok, false, cond, msg) end
+      env.nok = function(cond, msg) wrap(assertok, true,  cond, msg) end
       env.fail = function (func, expected, msg) wrap(fail, func, expected, msg) end
 
       handler('begin', name)

+ 61 - 0
tests/NTest_adc_env.lua

@@ -0,0 +1,61 @@
+-- Walk the ADC through a stepped triangle wave using the attached voltage
+-- divider and I2C GPIO expander.
+
+local N = require('NTest')("adc-env")
+
+-- TODO: Preflight test that we are in the correct environment with an I2C
+-- expander in the right place with the right connections.
+
+-- TODO: Use the mcp23017 module in the main tree rather than hand-coding
+-- the commands
+
+N.test('setup', function()
+  -- Configure the ADC
+  if adc.force_init_mode(adc.INIT_ADC)
+  then
+    node.restart()
+    error "Must reboot to get to ADC mode"
+  end
+
+  -- Configure the I2C bus
+  i2c.setup(0, 2, 1, i2c.FAST)
+
+  -- Set the IO expander port B to channels 0 and 1 as outputs
+  i2c.start(0)
+  ok(i2c.address(0, 0x20, i2c.TRANSMITTER))
+  i2c.write(0, 0x01, 0xFC)
+  i2c.stop(0)
+end)
+
+-- set the two-bit voltage divider output value to v (in 0,1,2,3)
+local function setv(v)
+  assert (0 <= v and v <= 3)
+  i2c.start(0)
+  i2c.address(0, 0x20, i2c.TRANSMITTER)
+  i2c.write(0, 0x15, v)
+  i2c.stop(0)
+end
+
+-- read out the ADC and compare to given range
+local function checkadc(min, max)
+  local v = adc.read(0)
+  return ok(min <= v and v <= max, ("read adc: %d <= %d <= %d"):format(min,v,max))
+end
+
+-- Since we have a rail-to-rail 4-tap DAC, as it were, give us some one-sided
+-- wiggle around either rail and some two-sided wiggle around both middle stops
+local vmin = {  0, 300, 700, 1000 }
+local vmax = { 24, 400, 800, 1024 }
+
+-- Set the DAC, wait a brief while for physics, and then read the ADC
+local function mktest(fs, i)
+  N.test(fs:format(i), function()
+    setv(i)
+    tmr.delay(10)
+    checkadc(vmin[i+1], vmax[i+1])
+  end)
+end
+
+-- test all four stops on the way up, and the three to come back down
+for i=0,3    do mktest("%d up", i) end
+for i=2,0,-1 do mktest("%d down", i) end

+ 88 - 0
tests/NTest_gpio_env.lua

@@ -0,0 +1,88 @@
+-- Walk the GPIO subsystem through its paces, using the attached I2C GPIO chip
+--
+--   Node GPIO 13 (index 7) is connected to I2C expander channel B6; node OUT
+--   Node GPIO 15 (index 8) is connected to I2C expander channel B7; node IN
+
+local N = require('NTest')("gpio-env")
+
+-- TODO: Preflight test that we are in the correct environment with an I2C
+-- expander in the right place with the right connections.
+
+-- TODO: Use the mcp23017 module in the main tree rather than hand-coding
+-- the commands
+
+N.test('setup', function()
+  -- Set gpio pin directions
+  gpio.mode(8, gpio.INPUT)
+  gpio.mode(7, gpio.OUTPUT, gpio.FLOAT)
+
+  -- Configure the I2C bus
+  i2c.setup(0, 2, 1, i2c.FAST)
+
+  -- Set the IO expander port B to channel 7 as output, 6 as input
+  i2c.start(0)
+  ok(i2c.address(0, 0x20, i2c.TRANSMITTER))
+  i2c.write(0, 0x01, 0x7F)
+  i2c.stop(0)
+end)
+
+local function seti2cb7(v)
+  i2c.start(0)
+  i2c.address(0, 0x20, i2c.TRANSMITTER)
+  i2c.write(0, 0x15, v and 0x80 or 0x00)
+  i2c.stop(0)
+end
+
+local function geti2cb6()
+  i2c.start(0)
+  i2c.address(0, 0x20, i2c.TRANSMITTER)
+  i2c.write(0, 0x13)
+  i2c.start(0)
+  i2c.address(0, 0x20, i2c.RECEIVER)
+  local v = i2c.read(0, 1):byte(1)
+  i2c.stop(0)
+  return (bit.band(v,0x40) ~= 0)
+end
+
+N.test('gpio read 0', function()
+  seti2cb7(false)
+  ok(eq(0, gpio.read(8)))
+end)
+
+N.test('gpio read 1', function()
+  seti2cb7(true)
+  ok(eq(1, gpio.read(8)))
+end)
+
+N.test('i2c read 0', function()
+  gpio.write(7, 0)
+  ok(eq(false, geti2cb6()))
+end)
+
+N.test('i2c read 1', function()
+  gpio.write(7, 1)
+  ok(eq(true, geti2cb6()))
+end)
+
+N.testasync('gpio toggle trigger 1', function(next)
+  seti2cb7(false)
+  tmr.delay(10)
+  gpio.trig(8, "both", function(l,_,c)
+    ok(c == 1 and l == 1)
+    return next()
+  end)
+  seti2cb7(true)
+end, true)
+
+N.testasync('gpio toggle trigger 2', function(next)
+  gpio.trig(8, "both", function(l,_,c)
+    ok(c == 1 and l == 0)
+    return next()
+  end)
+  seti2cb7(false)
+end, true)
+
+N.test('gpio toggle trigger end', function()
+  gpio.trig(8, "none")
+  ok(true)
+end)

+ 157 - 0
tests/NodeMCU_Test_Environment.rst

@@ -0,0 +1,157 @@
+###########################
+NodeMCU Testing Environment
+###########################
+
+Herein we define the environment our testing framework expects to see when it
+runs.  It is composed of two ESP8266 devices, each capable of holding an entire
+NodeMCU firmware, LFS image, and SPIFFS file system, as well as additional
+peripheral hardware.  It is designed to fit comfortably on a breadboard and so
+should be easily replicated and integrated into any firmware validation
+testing.
+
+The test harness runs from a dedicated host computer, which is expected to have
+reset- and programming-capable UART links to both ESP8266 devices, as found on
+almost all ESP8266 boards with USB to UART adapters, but the host does not
+necessarily need to use USB to connect, so long as TXD, RXD, DTR, and RTS are
+wired across.
+
+Peripherals
+###########
+
+I2C Bus
+=======
+
+There is an I2C bus hanging off DUT 0.  Attached hardware is used both as tests
+of modules directly and also to facilitate testing other modules (e.g., gpio).
+
+MCP23017: I/O Expander
+----------------------
+
+At address 0x20.  An 16-bit tristate GPIO expander, this chip is used to test
+I2C, GPIO, and ADC functionality.  This chip's interconnections are as follows:
+
++---------+-------------------------------------------------------------------+
+| /RESET  | DUT0 reset.  This resets the chip whenever the host computer      |
+|         | resets DUT 0 over its serial link (using DTR/RTS).                |
++---------+-------------------------------------------------------------------+
+| B 0     | 4K7 resistor to DUT 0 ADC.                                        |
++---------+-------------------------------------------------------------------+
+| B 1     | 2K2 resistor to DUT 0 ADC.                                        |
++---------+-------------------------------------------------------------------+
+| B 5     | DUT1 GPIO16/WAKE via 4K7 resitor                                  |
++---------+-------------------------------------------------------------------+
+| B 6     | DUT0 GPIO13 via 4K7 resistor and DUT1 GPIO15 via 4K7 resistor     |
++---------+-------------------------------------------------------------------+
+| B 7     | DUT0 GPIO15 via 4K7 resistor and DUT1 GPIO13 via 4K7 resistor     |
++---------+-------------------------------------------------------------------+
+
+Notes:
+
+* DUT 0's ADC pin is connected via a 2K2 reistor to this chip's port B, pin 1
+  and via a 4K7 resistor to port B, pin 0.  This gives us the ability to
+  produce approximately 0 (both pins low), 1.1 (pin 0 high, pin 1 low), 2.2
+  (pin 1 high, pin 0 low), and 3.3V (both pins high) on the ADC pin.
+
+* Port B pins 6 and 7 sit on the UART cross-wiring between DUT 0 and DUT 1.
+  The 23017 will be tristated for inter-DUT UART tests, but these 
+
+* Port B pins 2, 3, and 4, as well as all of port A, remain available for
+  expansion.
+
+* The interrupt pins are not yet routed, but could be.  We reserve DUT 0
+  GPIO 2 for this purpose with the understanding that the 23017's
+  interrupt functionality will be disabled (INTA, INTB set to open-drain,
+  GPINTEN set to 0) when not explicitly under test.
+
+ESP8266 Device 0 Connections
+############################
+
++---------+---------------------------------------------------------+
+| ESP     |                                                         |
++---------+---------------------------------------------------------+
+| GPIO 0  | Used to enter programming mode; otherwise unused in     |
+|         | test environment.                                       |
++---------+---------------------------------------------------------+
+| GPIO 1  | Primary UART transmit; reserved for host communication  |
++---------+---------------------------------------------------------+
+| GPIO 2  | [reserved for 1-Wire]                                   |
+|         | [+ reserved for 23017 INT[AB] connections]              |
++---------+---------------------------------------------------------+
+| GPIO 3  | Primary UART recieve; reserved for host communication   |
++---------+---------------------------------------------------------+
+| GPIO 4  | I2C SDA                                                 |
++---------+---------------------------------------------------------+
+| GPIO 5  | I2C SCL                                                 |
++---------+---------------------------------------------------------+
+| GPIO 6  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 7  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 8  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 9  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 10 | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 11 | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 12 |                                                         |
++---------+---------------------------------------------------------+
+| GPIO 13 | Secondary UART RX; DUT 1 GPIO 15, I/O expander B 6      |
++---------+---------------------------------------------------------+
+| GPIO 14 |                                                         |
++---------+---------------------------------------------------------+
+| GPIO 15 | Secondary UART TX; DUT 1 GPIO 13, I/O expander B 7      |
++---------+---------------------------------------------------------+
+| GPIO 16 |                                                         |
++---------+---------------------------------------------------------+
+| ADC 0   | Resistor divider with I/O expander                      |
++---------+---------------------------------------------------------+
+
+ESP8266 Device 1 Connections
+############################
+
++---------+---------------------------------------------------------+
+| ESP     |                                                         |
++---------+---------------------------------------------------------+
+| GPIO 0  | Used to enter programming mode; otherwise unused in     |
+|         | test environment.                                       |
++---------+---------------------------------------------------------+
+| GPIO 1  | Primary UART transmit; reserved for host communication  |
++---------+---------------------------------------------------------+
+| GPIO 2  | [Reserved for WS2812]                                   |
++---------+---------------------------------------------------------+
+| GPIO 3  | Primary UART recieve; reserved for host communication   |
++---------+---------------------------------------------------------+
+| GPIO 4  |                                                         |
++---------+---------------------------------------------------------+
+| GPIO 5  |                                                         |
++---------+---------------------------------------------------------+
+| GPIO 6  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 7  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 8  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 9  | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 10 | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 11 | [Reserved for on-chip flash]                            |
++---------+---------------------------------------------------------+
+| GPIO 12 | HSPI MISO                                               |
++---------+---------------------------------------------------------+
+| GPIO 13 | Secondary UART RX; DUT 0 GPIO 15, I/O exp B 7 via 4K7   |
+|         | Also used as HSPI MOSI for SPI tests                    |
++---------+---------------------------------------------------------+
+| GPIO 14 | HSPI CLK                                                |
++---------+---------------------------------------------------------+
+| GPIO 15 | Secondary UART TX; DUT 0 GPIO 13, I/O exp B 6 via 4K7   |
+|         | Also used as HSPI /CS for SPI tests                     |
++---------+---------------------------------------------------------+
+| GPIO 16 | I/O expander B 5 via 4K7 resistor, for deep-sleep tests |
++---------+---------------------------------------------------------+
+| ADC 0   |                                                         |
++---------+---------------------------------------------------------+
+
+