1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
-- functions to write registers over microwire interface
-- it resembles SPI but need exrta pin which sends Load Enable (LE) pulse
-- otherwise SPI sequence is sent into 24 bit FIFO buffer
-- Pins assignment
-- SPI Id selects which pins are used for CLK, MOSI, MISO, CS
microwire_sle = 4; -- microwire Load Enable pin. 2 --> GPIO2
-- lmx2487 can hadle up to 20 MHz but optocoupler is good for 240kHz
-- so let's aim to 100 kHz
maxMicrowireInterfaceSpeed = 100000; -- in Hz
spiID = 1; -- HSPI in nodemcu language
databits=24
-- default SPI clock is 80 MHz
fSPI = 80000000
clock_divider = math.floor(fSPI/maxMicrowireInterfaceSpeed)
function microwire_setup_interface ()
-- Load Enable pin settings
gpio.mode(microwire_sle, gpio.OUTPUT)
gpio.write(microwire_sle, gpio.LOW)
-- now microwire <--> SPI setup
-- microwire is SPI with CPOL=0 and CPHA=0 i.e. SPI mode 0 = 00 = CPOL.CPHA
-- see https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Mode_numbers
-- see https://www.totalphase.com/support/articles/200348506-Using-the-Aardvark-adapter-with-a-Microwire-device
-- we are setting SPI Id = 1, since Id = 0 used for communication with memory
spi.setup(spiID, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, databits, clock_divider)
-- SPI Id=1 uses following pins https://nodemcu.readthedocs.io/en/master/modules/spi
-- Signal | IO index | ESP8266 pin
-- HSPI CLK | 5 | GPIO14
-- HSPI /CS | 8 | GPIO15
-- HSPI MOSI | 7 | GPIO13
-- HSPI MISO | 6 | GPIO12
end
function microwire_send_data( data )
-- essentially send data via spi interface
-- and raise Load Enable pin for a bit (at least for25 nS) at the end of transmission
-- first low LE pin
gpio.write(microwire_sle, gpio.LOW)
-- second send the data
local nBytes = spi.send(spiID, data)
-- finally raise LE pin for at least 25 ns,
gpio.write(microwire_sle, gpio.HIGH)
-- but since optocoupler is limiting us we will do it for longer
local microwireLEonTime = 100; -- time is in uS
-- the easiest to use tmr.delay( timeIn_uS ) but this halts everything
-- tmr.delay( microwireLEonTime )
-- so we use timer but unfortunately the smallest time is 1ms
microwireLEonTime = 1; -- time is in mS for timers
microwire_tmr = tmr.create()
microwire_tmr:register(microwireLEonTime, tmr.ALARM_SINGLE, function() gpio.write(microwire_sle, gpio.LOW) end)
microwire_tmr:start()
end
microwire_setup_interface()
|