No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PigpiodIf.cs 74KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net.Sockets;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. // Disable all XML Comment warnings in this file as copied from elsewhere //
  11. #pragma warning disable 1591
  12. namespace Iot.Device.Pigpio
  13. {
  14. /// <summary>
  15. /// Pigpiod C# Interface for debugging in Visual Studio using GPIO of Raspberry Pi
  16. /// </summary>
  17. /// <remarks>
  18. /// From here: https://github.com/Rapidnack/PigpiodIfTest
  19. /// </remarks>
  20. public class PigpiodIf : IDisposable
  21. {
  22. private class GpioExtent
  23. {
  24. public byte[] Contents { get; set; }
  25. }
  26. public class GpioReport
  27. {
  28. public UInt16 seqno { get; set; }
  29. public UInt16 flags { get; set; }
  30. public UInt32 tick { get; set; }
  31. public UInt32 level { get; set; }
  32. }
  33. public class Callback
  34. {
  35. public int gpio { get; set; }
  36. public int edge { get; set; }
  37. public Action<UInt32, UInt32, UInt32, object> f { get; set; }
  38. public object user { get; set; }
  39. public int ex { get; set; }
  40. }
  41. public class EvtCallback
  42. {
  43. public int evt { get; set; }
  44. public Action<UInt32, UInt32, object> f { get; set; }
  45. public object user { get; set; }
  46. public int ex { get; set; }
  47. }
  48. public class GpioPulse
  49. {
  50. public UInt32 gpioOn { get; set; }
  51. public UInt32 gpioOff { get; set; }
  52. public UInt32 usDelay { get; set; }
  53. }
  54. #region # public enum
  55. public enum EError
  56. {
  57. pigif_bad_send = -2000,
  58. pigif_bad_recv = -2001,
  59. pigif_bad_getaddrinfo = -2002,
  60. pigif_bad_connect = -2003,
  61. pigif_bad_socket = -2004,
  62. pigif_bad_noib = -2005,
  63. pigif_duplicate_callback = -2006,
  64. pigif_bad_malloc = -2007,
  65. pigif_bad_callback = -2008,
  66. pigif_notify_failed = -2009,
  67. pigif_callback_not_found = -2010,
  68. pigif_unconnected_pi = -2011,
  69. pigif_too_many_pis = -2012,
  70. }
  71. #endregion
  72. #region # event
  73. public event EventHandler CommandStreamChanged;
  74. public event EventHandler NotifyStreamChanged;
  75. public event EventHandler StreamChanged;
  76. public event EventHandler StreamConnected;
  77. #endregion
  78. #region # private const
  79. private const string PI_DEFAULT_SOCKET_PORT_STR = "8888";
  80. private const string PI_DEFAULT_SOCKET_ADDR_STR = "127.0.0.1";
  81. private const int PI_MAX_REPORTS_PER_READ = 4096;
  82. private const int PIGPIOD_IF2_VERSION = 13;
  83. /*DEF_S Socket Command Codes*/
  84. private const int PI_CMD_MODES = 0;
  85. private const int PI_CMD_MODEG = 1;
  86. private const int PI_CMD_PUD = 2;
  87. private const int PI_CMD_READ = 3;
  88. private const int PI_CMD_WRITE = 4;
  89. private const int PI_CMD_PWM = 5;
  90. private const int PI_CMD_PRS = 6;
  91. private const int PI_CMD_PFS = 7;
  92. private const int PI_CMD_SERVO = 8;
  93. private const int PI_CMD_WDOG = 9;
  94. private const int PI_CMD_BR1 = 10;
  95. private const int PI_CMD_BR2 = 11;
  96. private const int PI_CMD_BC1 = 12;
  97. private const int PI_CMD_BC2 = 13;
  98. private const int PI_CMD_BS1 = 14;
  99. private const int PI_CMD_BS2 = 15;
  100. private const int PI_CMD_TICK = 16;
  101. private const int PI_CMD_HWVER = 17;
  102. private const int PI_CMD_NO = 18;
  103. private const int PI_CMD_NB = 19;
  104. private const int PI_CMD_NP = 20;
  105. private const int PI_CMD_NC = 21;
  106. private const int PI_CMD_PRG = 22;
  107. private const int PI_CMD_PFG = 23;
  108. private const int PI_CMD_PRRG = 24;
  109. private const int PI_CMD_HELP = 25;
  110. private const int PI_CMD_PIGPV = 26;
  111. private const int PI_CMD_WVCLR = 27;
  112. private const int PI_CMD_WVAG = 28;
  113. private const int PI_CMD_WVAS = 29;
  114. private const int PI_CMD_WVGO = 30;
  115. private const int PI_CMD_WVGOR = 31;
  116. private const int PI_CMD_WVBSY = 32;
  117. private const int PI_CMD_WVHLT = 33;
  118. private const int PI_CMD_WVSM = 34;
  119. private const int PI_CMD_WVSP = 35;
  120. private const int PI_CMD_WVSC = 36;
  121. private const int PI_CMD_TRIG = 37;
  122. private const int PI_CMD_PROC = 38;
  123. private const int PI_CMD_PROCD = 39;
  124. private const int PI_CMD_PROCR = 40;
  125. private const int PI_CMD_PROCS = 41;
  126. private const int PI_CMD_SLRO = 42;
  127. private const int PI_CMD_SLR = 43;
  128. private const int PI_CMD_SLRC = 44;
  129. private const int PI_CMD_PROCP = 45;
  130. private const int PI_CMD_MICS = 46;
  131. private const int PI_CMD_MILS = 47;
  132. private const int PI_CMD_PARSE = 48;
  133. private const int PI_CMD_WVCRE = 49;
  134. private const int PI_CMD_WVDEL = 50;
  135. private const int PI_CMD_WVTX = 51;
  136. private const int PI_CMD_WVTXR = 52;
  137. private const int PI_CMD_WVNEW = 53;
  138. private const int PI_CMD_I2CO = 54;
  139. private const int PI_CMD_I2CC = 55;
  140. private const int PI_CMD_I2CRD = 56;
  141. private const int PI_CMD_I2CWD = 57;
  142. private const int PI_CMD_I2CWQ = 58;
  143. private const int PI_CMD_I2CRS = 59;
  144. private const int PI_CMD_I2CWS = 60;
  145. private const int PI_CMD_I2CRB = 61;
  146. private const int PI_CMD_I2CWB = 62;
  147. private const int PI_CMD_I2CRW = 63;
  148. private const int PI_CMD_I2CWW = 64;
  149. private const int PI_CMD_I2CRK = 65;
  150. private const int PI_CMD_I2CWK = 66;
  151. private const int PI_CMD_I2CRI = 67;
  152. private const int PI_CMD_I2CWI = 68;
  153. private const int PI_CMD_I2CPC = 69;
  154. private const int PI_CMD_I2CPK = 70;
  155. private const int PI_CMD_SPIO = 71;
  156. private const int PI_CMD_SPIC = 72;
  157. private const int PI_CMD_SPIR = 73;
  158. private const int PI_CMD_SPIW = 74;
  159. private const int PI_CMD_SPIX = 75;
  160. private const int PI_CMD_SERO = 76;
  161. private const int PI_CMD_SERC = 77;
  162. private const int PI_CMD_SERRB = 78;
  163. private const int PI_CMD_SERWB = 79;
  164. private const int PI_CMD_SERR = 80;
  165. private const int PI_CMD_SERW = 81;
  166. private const int PI_CMD_SERDA = 82;
  167. private const int PI_CMD_GDC = 83;
  168. private const int PI_CMD_GPW = 84;
  169. private const int PI_CMD_HC = 85;
  170. private const int PI_CMD_HP = 86;
  171. private const int PI_CMD_CF1 = 87;
  172. private const int PI_CMD_CF2 = 88;
  173. private const int PI_CMD_BI2CC = 89;
  174. private const int PI_CMD_BI2CO = 90;
  175. private const int PI_CMD_BI2CZ = 91;
  176. private const int PI_CMD_I2CZ = 92;
  177. private const int PI_CMD_WVCHA = 93;
  178. private const int PI_CMD_SLRI = 94;
  179. private const int PI_CMD_CGI = 95;
  180. private const int PI_CMD_CSI = 96;
  181. private const int PI_CMD_FG = 97;
  182. private const int PI_CMD_FN = 98;
  183. private const int PI_CMD_NOIB = 99;
  184. private const int PI_CMD_WVTXM = 100;
  185. private const int PI_CMD_WVTAT = 101;
  186. private const int PI_CMD_PADS = 102;
  187. private const int PI_CMD_PADG = 103;
  188. private const int PI_CMD_FO = 104;
  189. private const int PI_CMD_FC = 105;
  190. private const int PI_CMD_FR = 106;
  191. private const int PI_CMD_FW = 107;
  192. private const int PI_CMD_FS = 108;
  193. private const int PI_CMD_FL = 109;
  194. private const int PI_CMD_SHELL = 110;
  195. private const int PI_CMD_BSPIC = 111;
  196. private const int PI_CMD_BSPIO = 112;
  197. private const int PI_CMD_BSPIX = 113;
  198. private const int PI_CMD_BSCX = 114;
  199. private const int PI_CMD_EVM = 115;
  200. private const int PI_CMD_EVT = 116;
  201. private const int PI_CMD_PROCU = 117;
  202. /*DEF_E*/
  203. /* pseudo commands */
  204. private const int PI_CMD_SCRIPT = 800;
  205. private const int PI_CMD_ADD = 800;
  206. private const int PI_CMD_AND = 801;
  207. private const int PI_CMD_CALL = 802;
  208. private const int PI_CMD_CMDR = 803;
  209. private const int PI_CMD_CMDW = 804;
  210. private const int PI_CMD_CMP = 805;
  211. private const int PI_CMD_DCR = 806;
  212. private const int PI_CMD_DCRA = 807;
  213. private const int PI_CMD_DIV = 808;
  214. private const int PI_CMD_HALT = 809;
  215. private const int PI_CMD_INR = 810;
  216. private const int PI_CMD_INRA = 811;
  217. private const int PI_CMD_JM = 812;
  218. private const int PI_CMD_JMP = 813;
  219. private const int PI_CMD_JNZ = 814;
  220. private const int PI_CMD_JP = 815;
  221. private const int PI_CMD_JZ = 816;
  222. private const int PI_CMD_TAG = 817;
  223. private const int PI_CMD_LD = 818;
  224. private const int PI_CMD_LDA = 819;
  225. private const int PI_CMD_LDAB = 820;
  226. private const int PI_CMD_MLT = 821;
  227. private const int PI_CMD_MOD = 822;
  228. private const int PI_CMD_NOP = 823;
  229. private const int PI_CMD_OR = 824;
  230. private const int PI_CMD_POP = 825;
  231. private const int PI_CMD_POPA = 826;
  232. private const int PI_CMD_PUSH = 827;
  233. private const int PI_CMD_PUSHA = 828;
  234. private const int PI_CMD_RET = 829;
  235. private const int PI_CMD_RL = 830;
  236. private const int PI_CMD_RLA = 831;
  237. private const int PI_CMD_RR = 832;
  238. private const int PI_CMD_RRA = 833;
  239. private const int PI_CMD_STA = 834;
  240. private const int PI_CMD_STAB = 835;
  241. private const int PI_CMD_SUB = 836;
  242. private const int PI_CMD_SYS = 837;
  243. private const int PI_CMD_WAIT = 838;
  244. private const int PI_CMD_X = 839;
  245. private const int PI_CMD_XA = 840;
  246. private const int PI_CMD_XOR = 841;
  247. private const int PI_CMD_EVTWT = 842;
  248. #endregion
  249. #region # public const
  250. /* gpio: 0-53 */
  251. public const int PI_MIN_GPIO = 0;
  252. public const int PI_MAX_GPIO = 53;
  253. /* user_gpio: 0-31 */
  254. public const int PI_MAX_USER_GPIO = 31;
  255. /* level: 0-1 */
  256. public const int PI_OFF = 0;
  257. public const int PI_ON = 1;
  258. public const int PI_CLEAR = 0;
  259. public const int PI_SET = 1;
  260. public const int PI_LOW = 0;
  261. public const int PI_HIGH = 1;
  262. /* level: only reported for GPIO time-out, see gpioSetWatchdog */
  263. public const int PI_TIMEOUT = 2;
  264. /* mode: 0-7 */
  265. public const int PI_INPUT = 0;
  266. public const int PI_OUTPUT = 1;
  267. public const int PI_ALT0 = 4;
  268. public const int PI_ALT1 = 5;
  269. public const int PI_ALT2 = 6;
  270. public const int PI_ALT3 = 7;
  271. public const int PI_ALT4 = 3;
  272. public const int PI_ALT5 = 2;
  273. /* pud: 0-2 */
  274. public const int PI_PUD_OFF = 0;
  275. public const int PI_PUD_DOWN = 1;
  276. public const int PI_PUD_UP = 2;
  277. /* dutycycle: 0-range */
  278. public const int PI_DEFAULT_DUTYCYCLE_RANGE = 255;
  279. /* range: 25-40000 */
  280. public const int PI_MIN_DUTYCYCLE_RANGE = 25;
  281. public const int PI_MAX_DUTYCYCLE_RANGE = 40000;
  282. /* pulsewidth: 0, 500-2500 */
  283. public const int PI_SERVO_OFF = 0;
  284. public const int PI_MIN_SERVO_PULSEWIDTH = 500;
  285. public const int PI_MAX_SERVO_PULSEWIDTH = 2500;
  286. /* hardware PWM */
  287. public const int PI_HW_PWM_MIN_FREQ = 1;
  288. public const int PI_HW_PWM_MAX_FREQ = 125000000;
  289. public const int PI_HW_PWM_RANGE = 1000000;
  290. /* hardware clock */
  291. public const int PI_HW_CLK_MIN_FREQ = 4689;
  292. public const int PI_HW_CLK_MAX_FREQ = 250000000;
  293. public const int PI_NOTIFY_SLOTS = 32;
  294. public const int PI_NTFY_FLAGS_EVENT = (1 << 7);
  295. public const int PI_NTFY_FLAGS_ALIVE = (1 << 6);
  296. public const int PI_NTFY_FLAGS_WDOG = (1 << 5);
  297. public static int PI_NTFY_FLAGS_BIT(int x) { return (((x) << 0) & 31); }
  298. public const int PI_WAVE_BLOCKS = 4;
  299. public const int PI_WAVE_MAX_PULSES = (PI_WAVE_BLOCKS * 3000);
  300. public const int PI_WAVE_MAX_CHARS = (PI_WAVE_BLOCKS * 300);
  301. public const int PI_BB_I2C_MIN_BAUD = 50;
  302. public const int PI_BB_I2C_MAX_BAUD = 500000;
  303. public const int PI_BB_SPI_MIN_BAUD = 50;
  304. public const int PI_BB_SPI_MAX_BAUD = 250000;
  305. public const int PI_BB_SER_MIN_BAUD = 50;
  306. public const int PI_BB_SER_MAX_BAUD = 250000;
  307. public const int PI_BB_SER_NORMAL = 0;
  308. public const int PI_BB_SER_INVERT = 1;
  309. public const int PI_WAVE_MIN_BAUD = 50;
  310. public const int PI_WAVE_MAX_BAUD = 1000000;
  311. public const int PI_SPI_MIN_BAUD = 32000;
  312. public const int PI_SPI_MAX_BAUD = 125000000;
  313. public const int PI_MIN_WAVE_DATABITS = 1;
  314. public const int PI_MAX_WAVE_DATABITS = 32;
  315. public const int PI_MIN_WAVE_HALFSTOPBITS = 2;
  316. public const int PI_MAX_WAVE_HALFSTOPBITS = 8;
  317. public const int PI_WAVE_MAX_MICROS = (30 * 60 * 1000000); /* half an hour */
  318. public const int PI_MAX_WAVES = 250;
  319. public const int PI_MAX_WAVE_CYCLES = 65535;
  320. public const int PI_MAX_WAVE_DELAY = 65535;
  321. public const int PI_WAVE_COUNT_PAGES = 10;
  322. /* wave tx mode */
  323. public const int PI_WAVE_MODE_ONE_SHOT = 0;
  324. public const int PI_WAVE_MODE_REPEAT = 1;
  325. public const int PI_WAVE_MODE_ONE_SHOT_SYNC = 2;
  326. public const int PI_WAVE_MODE_REPEAT_SYNC = 3;
  327. /* special wave at return values */
  328. public const int PI_WAVE_NOT_FOUND = 9998; /* Transmitted wave not found. */
  329. public const int PI_NO_TX_WAVE = 9999; /* No wave being transmitted. */
  330. /* Files, I2C, SPI, SER */
  331. public const int PI_FILE_SLOTS = 16;
  332. public const int PI_I2C_SLOTS = 64;
  333. public const int PI_SPI_SLOTS = 32;
  334. public const int PI_SER_SLOTS = 16;
  335. public const int PI_MAX_I2C_ADDR = 0x7F;
  336. public const int PI_NUM_AUX_SPI_CHANNEL = 3;
  337. public const int PI_NUM_STD_SPI_CHANNEL = 2;
  338. public const int PI_MAX_I2C_DEVICE_COUNT = (1 << 16);
  339. public const int PI_MAX_SPI_DEVICE_COUNT = (1 << 16);
  340. /* max pi_i2c_msg_t per transaction */
  341. public const int PI_I2C_RDRW_IOCTL_MAX_MSGS = 42;
  342. /* flags for i2cTransaction, pi_i2c_msg_t */
  343. public const int PI_I2C_M_WR = 0x0000; /* write data */
  344. public const int PI_I2C_M_RD = 0x0001; /* read data */
  345. public const int PI_I2C_M_TEN = 0x0010; /* ten bit chip address */
  346. public const int PI_I2C_M_RECV_LEN = 0x0400; /* length will be first received byte */
  347. public const int PI_I2C_M_NO_RD_ACK = 0x0800; /* if I2C_FUNC_PROTOCOL_MANGLING */
  348. public const int PI_I2C_M_IGNORE_NAK = 0x1000; /* if I2C_FUNC_PROTOCOL_MANGLING */
  349. public const int PI_I2C_M_REV_DIR_ADDR = 0x2000; /* if I2C_FUNC_PROTOCOL_MANGLING */
  350. public const int PI_I2C_M_NOSTART = 0x4000; /* if I2C_FUNC_PROTOCOL_MANGLING */
  351. /* bbI2CZip and i2cZip commands */
  352. public const int PI_I2C_END = 0;
  353. public const int PI_I2C_ESC = 1;
  354. public const int PI_I2C_START = 2;
  355. public const int PI_I2C_COMBINED_ON = 2;
  356. public const int PI_I2C_STOP = 3;
  357. public const int PI_I2C_COMBINED_OFF = 3;
  358. public const int PI_I2C_ADDR = 4;
  359. public const int PI_I2C_FLAGS = 5;
  360. public const int PI_I2C_READ = 6;
  361. public const int PI_I2C_WRITE = 7;
  362. /* SPI */
  363. public static int PI_SPI_FLAGS_BITLEN(int x) { return ((x & 63) << 16); }
  364. public static int PI_SPI_FLAGS_RX_LSB(int x) { return ((x & 1) << 15); }
  365. public static int PI_SPI_FLAGS_TX_LSB(int x) { return ((x & 1) << 14); }
  366. public static int PI_SPI_FLAGS_3WREN(int x) { return ((x & 15) << 10); }
  367. public static int PI_SPI_FLAGS_3WIRE(int x) { return ((x & 1) << 9); }
  368. public static int PI_SPI_FLAGS_AUX_SPI(int x) { return ((x & 1) << 8); }
  369. public static int PI_SPI_FLAGS_RESVD(int x) { return ((x & 7) << 5); }
  370. public static int PI_SPI_FLAGS_CSPOLS(int x) { return ((x & 7) << 2); }
  371. public static int PI_SPI_FLAGS_MODE(int x) { return ((x & 3)); }
  372. /* Longest busy delay */
  373. public const int PI_MAX_BUSY_DELAY = 100;
  374. /* timeout: 0-60000 */
  375. public const int PI_MIN_WDOG_TIMEOUT = 0;
  376. public const int PI_MAX_WDOG_TIMEOUT = 60000;
  377. /* timer: 0-9 */
  378. public const int PI_MIN_TIMER = 0;
  379. public const int PI_MAX_TIMER = 9;
  380. /* millis: 10-60000 */
  381. public const int PI_MIN_MS = 10;
  382. public const int PI_MAX_MS = 60000;
  383. public const int PI_MAX_SCRIPTS = 32;
  384. public const int PI_MAX_SCRIPT_TAGS = 50;
  385. public const int PI_MAX_SCRIPT_VARS = 150;
  386. public const int PI_MAX_SCRIPT_PARAMS = 10;
  387. /* script status */
  388. public const int PI_SCRIPT_INITING = 0;
  389. public const int PI_SCRIPT_HALTED = 1;
  390. public const int PI_SCRIPT_RUNNING = 2;
  391. public const int PI_SCRIPT_WAITING = 3;
  392. public const int PI_SCRIPT_FAILED = 4;
  393. /* signum: 0-63 */
  394. public const int PI_MIN_SIGNUM = 0;
  395. public const int PI_MAX_SIGNUM = 63;
  396. /* timetype: 0-1 */
  397. public const int PI_TIME_RELATIVE = 0;
  398. public const int PI_TIME_ABSOLUTE = 1;
  399. public const int PI_MAX_MICS_DELAY = 1000000; /* 1 second */
  400. public const int PI_MAX_MILS_DELAY = 60000; /* 60 seconds */
  401. /* cfgMillis */
  402. public const int PI_BUF_MILLIS_MIN = 100;
  403. public const int PI_BUF_MILLIS_MAX = 10000;
  404. /* cfgMicros: 1, 2, 4, 5, 8, or 10 */
  405. /* cfgPeripheral: 0-1 */
  406. public const int PI_CLOCK_PWM = 0;
  407. public const int PI_CLOCK_PCM = 1;
  408. /* DMA channel: 0-14 */
  409. public const int PI_MIN_DMA_CHANNEL = 0;
  410. public const int PI_MAX_DMA_CHANNEL = 14;
  411. /* port */
  412. public const int PI_MIN_SOCKET_PORT = 1024;
  413. public const int PI_MAX_SOCKET_PORT = 32000;
  414. /* ifFlags: */
  415. public const int PI_DISABLE_FIFO_IF = 1;
  416. public const int PI_DISABLE_SOCK_IF = 2;
  417. public const int PI_LOCALHOST_SOCK_IF = 4;
  418. public const int PI_DISABLE_ALERT = 8;
  419. /* memAllocMode */
  420. public const int PI_MEM_ALLOC_AUTO = 0;
  421. public const int PI_MEM_ALLOC_PAGEMAP = 1;
  422. public const int PI_MEM_ALLOC_MAILBOX = 2;
  423. /* filters */
  424. public const int PI_MAX_STEADY = 300000;
  425. public const int PI_MAX_ACTIVE = 1000000;
  426. /* gpioCfgInternals */
  427. public const int PI_CFG_DBG_LEVEL = 0; /* bits 0-3 */
  428. public const int PI_CFG_ALERT_FREQ = 4; /* bits 4-7 */
  429. public const int PI_CFG_RT_PRIORITY = (1 << 8);
  430. public const int PI_CFG_STATS = (1 << 9);
  431. public const int PI_CFG_NOSIGHANDLER = (1 << 10);
  432. public const int PI_CFG_ILLEGAL_VAL = (1 << 11);
  433. /* gpioISR */
  434. public const int RISING_EDGE = 0;
  435. public const int FALLING_EDGE = 1;
  436. public const int EITHER_EDGE = 2;
  437. /* pads */
  438. public const int PI_MAX_PAD = 2;
  439. public const int PI_MIN_PAD_STRENGTH = 1;
  440. public const int PI_MAX_PAD_STRENGTH = 16;
  441. /* files */
  442. public const int PI_FILE_NONE = 0;
  443. public const int PI_FILE_MIN = 1;
  444. public const int PI_FILE_READ = 1;
  445. public const int PI_FILE_WRITE = 2;
  446. public const int PI_FILE_RW = 3;
  447. public const int PI_FILE_APPEND = 4;
  448. public const int PI_FILE_CREATE = 8;
  449. public const int PI_FILE_TRUNC = 16;
  450. public const int PI_FILE_MAX = 31;
  451. public const int PI_FROM_START = 0;
  452. public const int PI_FROM_CURRENT = 1;
  453. public const int PI_FROM_END = 2;
  454. /* Allowed socket connect addresses */
  455. public const int MAX_CONNECT_ADDRESSES = 256;
  456. /* events */
  457. public const int PI_MAX_EVENT = 31;
  458. /* Event auto generated on BSC slave activity */
  459. public const int PI_EVENT_BSC = 31;
  460. /*DEF_S Error Codes*/
  461. public const int PI_INIT_FAILED = -1; // gpioInitialise failed
  462. public const int PI_BAD_USER_GPIO = -2; // GPIO not 0-31
  463. public const int PI_BAD_GPIO = -3; // GPIO not 0-53
  464. public const int PI_BAD_MODE = -4; // mode not 0-7
  465. public const int PI_BAD_LEVEL = -5; // level not 0-1
  466. public const int PI_BAD_PUD = -6; // pud not 0-2
  467. public const int PI_BAD_PULSEWIDTH = -7; // pulsewidth not 0 or 500-2500
  468. public const int PI_BAD_DUTYCYCLE = -8; // dutycycle outside set range
  469. public const int PI_BAD_TIMER = -9; // timer not 0-9
  470. public const int PI_BAD_MS = -10; // ms not 10-60000
  471. public const int PI_BAD_TIMETYPE = -11; // timetype not 0-1
  472. public const int PI_BAD_SECONDS = -12; // seconds < 0
  473. public const int PI_BAD_MICROS = -13; // micros not 0-999999
  474. public const int PI_TIMER_FAILED = -14; // gpioSetTimerFunc failed
  475. public const int PI_BAD_WDOG_TIMEOUT = -15; // timeout not 0-60000
  476. public const int PI_NO_ALERT_FUNC = -16; // DEPRECATED
  477. public const int PI_BAD_CLK_PERIPH = -17; // clock peripheral not 0-1
  478. public const int PI_BAD_CLK_SOURCE = -18; // DEPRECATED
  479. public const int PI_BAD_CLK_MICROS = -19; // clock micros not 1, 2, 4, 5, 8, or 10
  480. public const int PI_BAD_BUF_MILLIS = -20; // buf millis not 100-10000
  481. public const int PI_BAD_DUTYRANGE = -21; // dutycycle range not 25-40000
  482. public const int PI_BAD_DUTY_RANGE = -21; // DEPRECATED (use PI_BAD_DUTYRANGE)
  483. public const int PI_BAD_SIGNUM = -22; // signum not 0-63
  484. public const int PI_BAD_PATHNAME = -23; // can't open pathname
  485. public const int PI_NO_HANDLE = -24; // no handle available
  486. public const int PI_BAD_HANDLE = -25; // unknown handle
  487. public const int PI_BAD_IF_FLAGS = -26; // ifFlags > 4
  488. public const int PI_BAD_CHANNEL = -27; // DMA channel not 0-14
  489. public const int PI_BAD_PRIM_CHANNEL = -27; // DMA primary channel not 0-14
  490. public const int PI_BAD_SOCKET_PORT = -28; // socket port not 1024-32000
  491. public const int PI_BAD_FIFO_COMMAND = -29; // unrecognized fifo command
  492. public const int PI_BAD_SECO_CHANNEL = -30; // DMA secondary channel not 0-6
  493. public const int PI_NOT_INITIALISED = -31; // function called before gpioInitialise
  494. public const int PI_INITIALISED = -32; // function called after gpioInitialise
  495. public const int PI_BAD_WAVE_MODE = -33; // waveform mode not 0-3
  496. public const int PI_BAD_CFG_INTERNAL = -34; // bad parameter in gpioCfgInternals call
  497. public const int PI_BAD_WAVE_BAUD = -35; // baud rate not 50-250K(RX)/50-1M(TX)
  498. public const int PI_TOO_MANY_PULSES = -36; // waveform has too many pulses
  499. public const int PI_TOO_MANY_CHARS = -37; // waveform has too many chars
  500. public const int PI_NOT_SERIAL_GPIO = -38; // no bit bang serial read on GPIO
  501. public const int PI_BAD_SERIAL_STRUC = -39; // bad (null) serial structure parameter
  502. public const int PI_BAD_SERIAL_BUF = -40; // bad (null) serial buf parameter
  503. public const int PI_NOT_PERMITTED = -41; // GPIO operation not permitted
  504. public const int PI_SOME_PERMITTED = -42; // one or more GPIO not permitted
  505. public const int PI_BAD_WVSC_COMMND = -43; // bad WVSC subcommand
  506. public const int PI_BAD_WVSM_COMMND = -44; // bad WVSM subcommand
  507. public const int PI_BAD_WVSP_COMMND = -45; // bad WVSP subcommand
  508. public const int PI_BAD_PULSELEN = -46; // trigger pulse length not 1-100
  509. public const int PI_BAD_SCRIPT = -47; // invalid script
  510. public const int PI_BAD_SCRIPT_ID = -48; // unknown script id
  511. public const int PI_BAD_SER_OFFSET = -49; // add serial data offset > 30 minutes
  512. public const int PI_GPIO_IN_USE = -50; // GPIO already in use
  513. public const int PI_BAD_SERIAL_COUNT = -51; // must read at least a byte at a time
  514. public const int PI_BAD_PARAM_NUM = -52; // script parameter id not 0-9
  515. public const int PI_DUP_TAG = -53; // script has duplicate tag
  516. public const int PI_TOO_MANY_TAGS = -54; // script has too many tags
  517. public const int PI_BAD_SCRIPT_CMD = -55; // illegal script command
  518. public const int PI_BAD_VAR_NUM = -56; // script variable id not 0-149
  519. public const int PI_NO_SCRIPT_ROOM = -57; // no more room for scripts
  520. public const int PI_NO_MEMORY = -58; // can't allocate temporary memory
  521. public const int PI_SOCK_READ_FAILED = -59; // socket read failed
  522. public const int PI_SOCK_WRIT_FAILED = -60; // socket write failed
  523. public const int PI_TOO_MANY_PARAM = -61; // too many script parameters (> 10)
  524. public const int PI_NOT_HALTED = -62; // DEPRECATED
  525. public const int PI_SCRIPT_NOT_READY = -62; // script initialising
  526. public const int PI_BAD_TAG = -63; // script has unresolved tag
  527. public const int PI_BAD_MICS_DELAY = -64; // bad MICS delay (too large)
  528. public const int PI_BAD_MILS_DELAY = -65; // bad MILS delay (too large)
  529. public const int PI_BAD_WAVE_ID = -66; // non existent wave id
  530. public const int PI_TOO_MANY_CBS = -67; // No more CBs for waveform
  531. public const int PI_TOO_MANY_OOL = -68; // No more OOL for waveform
  532. public const int PI_EMPTY_WAVEFORM = -69; // attempt to create an empty waveform
  533. public const int PI_NO_WAVEFORM_ID = -70; // no more waveforms
  534. public const int PI_I2C_OPEN_FAILED = -71; // can't open I2C device
  535. public const int PI_SER_OPEN_FAILED = -72; // can't open serial device
  536. public const int PI_SPI_OPEN_FAILED = -73; // can't open SPI device
  537. public const int PI_BAD_I2C_BUS = -74; // bad I2C bus
  538. public const int PI_BAD_I2C_ADDR = -75; // bad I2C address
  539. public const int PI_BAD_SPI_CHANNEL = -76; // bad SPI channel
  540. public const int PI_BAD_FLAGS = -77; // bad i2c/spi/ser open flags
  541. public const int PI_BAD_SPI_SPEED = -78; // bad SPI speed
  542. public const int PI_BAD_SER_DEVICE = -79; // bad serial device name
  543. public const int PI_BAD_SER_SPEED = -80; // bad serial baud rate
  544. public const int PI_BAD_PARAM = -81; // bad i2c/spi/ser parameter
  545. public const int PI_I2C_WRITE_FAILED = -82; // i2c write failed
  546. public const int PI_I2C_READ_FAILED = -83; // i2c read failed
  547. public const int PI_BAD_SPI_COUNT = -84; // bad SPI count
  548. public const int PI_SER_WRITE_FAILED = -85; // ser write failed
  549. public const int PI_SER_READ_FAILED = -86; // ser read failed
  550. public const int PI_SER_READ_NO_DATA = -87; // ser read no data available
  551. public const int PI_UNKNOWN_COMMAND = -88; // unknown command
  552. public const int PI_SPI_XFER_FAILED = -89; // spi xfer/read/write failed
  553. public const int PI_BAD_POINTER = -90; // bad (NULL) pointer
  554. public const int PI_NO_AUX_SPI = -91; // no auxiliary SPI on Pi A or B
  555. public const int PI_NOT_PWM_GPIO = -92; // GPIO is not in use for PWM
  556. public const int PI_NOT_SERVO_GPIO = -93; // GPIO is not in use for servo pulses
  557. public const int PI_NOT_HCLK_GPIO = -94; // GPIO has no hardware clock
  558. public const int PI_NOT_HPWM_GPIO = -95; // GPIO has no hardware PWM
  559. public const int PI_BAD_HPWM_FREQ = -96; // hardware PWM frequency not 1-125M
  560. public const int PI_BAD_HPWM_DUTY = -97; // hardware PWM dutycycle not 0-1M
  561. public const int PI_BAD_HCLK_FREQ = -98; // hardware clock frequency not 4689-250M
  562. public const int PI_BAD_HCLK_PASS = -99; // need password to use hardware clock 1
  563. public const int PI_HPWM_ILLEGAL = -100; // illegal, PWM in use for main clock
  564. public const int PI_BAD_DATABITS = -101; // serial data bits not 1-32
  565. public const int PI_BAD_STOPBITS = -102; // serial (half) stop bits not 2-8
  566. public const int PI_MSG_TOOBIG = -103; // socket/pipe message too big
  567. public const int PI_BAD_MALLOC_MODE = -104; // bad memory allocation mode
  568. public const int PI_TOO_MANY_SEGS = -105; // too many I2C transaction segments
  569. public const int PI_BAD_I2C_SEG = -106; // an I2C transaction segment failed
  570. public const int PI_BAD_SMBUS_CMD = -107; // SMBus command not supported by driver
  571. public const int PI_NOT_I2C_GPIO = -108; // no bit bang I2C in progress on GPIO
  572. public const int PI_BAD_I2C_WLEN = -109; // bad I2C write length
  573. public const int PI_BAD_I2C_RLEN = -110; // bad I2C read length
  574. public const int PI_BAD_I2C_CMD = -111; // bad I2C command
  575. public const int PI_BAD_I2C_BAUD = -112; // bad I2C baud rate, not 50-500k
  576. public const int PI_CHAIN_LOOP_CNT = -113; // bad chain loop count
  577. public const int PI_BAD_CHAIN_LOOP = -114; // empty chain loop
  578. public const int PI_CHAIN_COUNTER = -115; // too many chain counters
  579. public const int PI_BAD_CHAIN_CMD = -116; // bad chain command
  580. public const int PI_BAD_CHAIN_DELAY = -117; // bad chain delay micros
  581. public const int PI_CHAIN_NESTING = -118; // chain counters nested too deeply
  582. public const int PI_CHAIN_TOO_BIG = -119; // chain is too long
  583. public const int PI_DEPRECATED = -120; // deprecated function removed
  584. public const int PI_BAD_SER_INVERT = -121; // bit bang serial invert not 0 or 1
  585. public const int PI_BAD_EDGE = -122; // bad ISR edge value, not 0-2
  586. public const int PI_BAD_ISR_INIT = -123; // bad ISR initialisation
  587. public const int PI_BAD_FOREVER = -124; // loop forever must be last command
  588. public const int PI_BAD_FILTER = -125; // bad filter parameter
  589. public const int PI_BAD_PAD = -126; // bad pad number
  590. public const int PI_BAD_STRENGTH = -127; // bad pad drive strength
  591. public const int PI_FIL_OPEN_FAILED = -128; // file open failed
  592. public const int PI_BAD_FILE_MODE = -129; // bad file mode
  593. public const int PI_BAD_FILE_FLAG = -130; // bad file flag
  594. public const int PI_BAD_FILE_READ = -131; // bad file read
  595. public const int PI_BAD_FILE_WRITE = -132; // bad file write
  596. public const int PI_FILE_NOT_ROPEN = -133; // file not open for read
  597. public const int PI_FILE_NOT_WOPEN = -134; // file not open for write
  598. public const int PI_BAD_FILE_SEEK = -135; // bad file seek
  599. public const int PI_NO_FILE_MATCH = -136; // no files match pattern
  600. public const int PI_NO_FILE_ACCESS = -137; // no permission to access file
  601. public const int PI_FILE_IS_A_DIR = -138; // file is a directory
  602. public const int PI_BAD_SHELL_STATUS = -139; // bad shell return status
  603. public const int PI_BAD_SCRIPT_NAME = -140; // bad script name
  604. public const int PI_BAD_SPI_BAUD = -141; // bad SPI baud rate, not 50-500k
  605. public const int PI_NOT_SPI_GPIO = -142; // no bit bang SPI in progress on GPIO
  606. public const int PI_BAD_EVENT_ID = -143; // bad event id
  607. public const int PI_CMD_INTERRUPTED = -144; // Used by Python
  608. public const int PI_PIGIF_ERR_0 = -2000;
  609. public const int PI_PIGIF_ERR_99 = -2099;
  610. public const int PI_CUSTOM_ERR_0 = -3000;
  611. public const int PI_CUSTOM_ERR_999 = -3999;
  612. /*DEF_E*/
  613. #endregion
  614. #region # private field
  615. private bool isConnecting = false;
  616. private int gPigHandle;
  617. private UInt32 gLastLevel;
  618. private UInt32 gNotifyBits;
  619. private CancellationTokenSource cts;
  620. private Stopwatch sw = new Stopwatch();
  621. private List<Callback> gCallBackList = new List<Callback>();
  622. private List<EvtCallback> geCallBackList = new List<EvtCallback>();
  623. private Dictionary<int, string> errInfo = new Dictionary<int, string>() {
  624. {PI_INIT_FAILED , "pigpio initialisation failed"},
  625. {PI_BAD_USER_GPIO , "GPIO not 0-31"},
  626. {PI_BAD_GPIO , "GPIO not 0-53"},
  627. {PI_BAD_MODE , "mode not 0-7"},
  628. {PI_BAD_LEVEL , "level not 0-1"},
  629. {PI_BAD_PUD , "pud not 0-2"},
  630. {PI_BAD_PULSEWIDTH , "pulsewidth not 0 or 500-2500"},
  631. {PI_BAD_DUTYCYCLE , "dutycycle not 0-range (default 255)"},
  632. {PI_BAD_TIMER , "timer not 0-9"},
  633. {PI_BAD_MS , "ms not 10-60000"},
  634. {PI_BAD_TIMETYPE , "timetype not 0-1"},
  635. {PI_BAD_SECONDS , "seconds < 0"},
  636. {PI_BAD_MICROS , "micros not 0-999999"},
  637. {PI_TIMER_FAILED , "gpioSetTimerFunc failed"},
  638. {PI_BAD_WDOG_TIMEOUT , "timeout not 0-60000"},
  639. {PI_NO_ALERT_FUNC , "DEPRECATED"},
  640. {PI_BAD_CLK_PERIPH , "clock peripheral not 0-1"},
  641. {PI_BAD_CLK_SOURCE , "DEPRECATED"},
  642. {PI_BAD_CLK_MICROS , "clock micros not 1, 2, 4, 5, 8, or 10"},
  643. {PI_BAD_BUF_MILLIS , "buf millis not 100-10000"},
  644. {PI_BAD_DUTYRANGE , "dutycycle range not 25-40000"},
  645. {PI_BAD_SIGNUM , "signum not 0-63"},
  646. {PI_BAD_PATHNAME , "can't open pathname"},
  647. {PI_NO_HANDLE , "no handle available"},
  648. {PI_BAD_HANDLE , "unknown handle"},
  649. {PI_BAD_IF_FLAGS , "ifFlags > 4"},
  650. {PI_BAD_CHANNEL , "DMA channel not 0-14"},
  651. {PI_BAD_SOCKET_PORT , "socket port not 1024-30000"},
  652. {PI_BAD_FIFO_COMMAND , "unknown fifo command"},
  653. {PI_BAD_SECO_CHANNEL , "DMA secondary channel not 0-14"},
  654. {PI_NOT_INITIALISED , "function called before gpioInitialise"},
  655. {PI_INITIALISED , "function called after gpioInitialise"},
  656. {PI_BAD_WAVE_MODE , "waveform mode not 0-1"},
  657. {PI_BAD_CFG_INTERNAL , "bad parameter in gpioCfgInternals call"},
  658. {PI_BAD_WAVE_BAUD , "baud rate not 50-250K(RX)/50-1M(TX)"},
  659. {PI_TOO_MANY_PULSES , "waveform has too many pulses"},
  660. {PI_TOO_MANY_CHARS , "waveform has too many chars"},
  661. {PI_NOT_SERIAL_GPIO , "no bit bang serial read in progress on GPIO"},
  662. {PI_BAD_SERIAL_STRUC , "bad (null) serial structure parameter"},
  663. {PI_BAD_SERIAL_BUF , "bad (null) serial buf parameter"},
  664. {PI_NOT_PERMITTED , "no permission to update GPIO"},
  665. {PI_SOME_PERMITTED , "no permission to update one or more GPIO"},
  666. {PI_BAD_WVSC_COMMND , "bad WVSC subcommand"},
  667. {PI_BAD_WVSM_COMMND , "bad WVSM subcommand"},
  668. {PI_BAD_WVSP_COMMND , "bad WVSP subcommand"},
  669. {PI_BAD_PULSELEN , "trigger pulse length not 1-100"},
  670. {PI_BAD_SCRIPT , "invalid script"},
  671. {PI_BAD_SCRIPT_ID , "unknown script id"},
  672. {PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
  673. {PI_GPIO_IN_USE , "GPIO already in use"},
  674. {PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"},
  675. {PI_BAD_PARAM_NUM , "script parameter id not 0-9"},
  676. {PI_DUP_TAG , "script has duplicate tag"},
  677. {PI_TOO_MANY_TAGS , "script has too many tags"},
  678. {PI_BAD_SCRIPT_CMD , "illegal script command"},
  679. {PI_BAD_VAR_NUM , "script variable id not 0-149"},
  680. {PI_NO_SCRIPT_ROOM , "no more room for scripts"},
  681. {PI_NO_MEMORY , "can't allocate temporary memory"},
  682. {PI_SOCK_READ_FAILED , "socket read failed"},
  683. {PI_SOCK_WRIT_FAILED , "socket write failed"},
  684. {PI_TOO_MANY_PARAM , "too many script parameters (> 10)"},
  685. {PI_SCRIPT_NOT_READY , "script initialising"},
  686. {PI_BAD_TAG , "script has unresolved tag"},
  687. {PI_BAD_MICS_DELAY , "bad MICS delay (too large)"},
  688. {PI_BAD_MILS_DELAY , "bad MILS delay (too large)"},
  689. {PI_BAD_WAVE_ID , "non existent wave id"},
  690. {PI_TOO_MANY_CBS , "No more CBs for waveform"},
  691. {PI_TOO_MANY_OOL , "No more OOL for waveform"},
  692. {PI_EMPTY_WAVEFORM , "attempt to create an empty waveform"},
  693. {PI_NO_WAVEFORM_ID , "no more waveform ids"},
  694. {PI_I2C_OPEN_FAILED , "can't open I2C device"},
  695. {PI_SER_OPEN_FAILED , "can't open serial device"},
  696. {PI_SPI_OPEN_FAILED , "can't open SPI device"},
  697. {PI_BAD_I2C_BUS , "bad I2C bus"},
  698. {PI_BAD_I2C_ADDR , "bad I2C address"},
  699. {PI_BAD_SPI_CHANNEL , "bad SPI channel"},
  700. {PI_BAD_FLAGS , "bad i2c/spi/ser open flags"},
  701. {PI_BAD_SPI_SPEED , "bad SPI speed"},
  702. {PI_BAD_SER_DEVICE , "bad serial device name"},
  703. {PI_BAD_SER_SPEED , "bad serial baud rate"},
  704. {PI_BAD_PARAM , "bad i2c/spi/ser parameter"},
  705. {PI_I2C_WRITE_FAILED , "I2C write failed"},
  706. {PI_I2C_READ_FAILED , "I2C read failed"},
  707. {PI_BAD_SPI_COUNT , "bad SPI count"},
  708. {PI_SER_WRITE_FAILED , "ser write failed"},
  709. {PI_SER_READ_FAILED , "ser read failed"},
  710. {PI_SER_READ_NO_DATA , "ser read no data available"},
  711. {PI_UNKNOWN_COMMAND , "unknown command"},
  712. {PI_SPI_XFER_FAILED , "spi xfer/read/write failed"},
  713. {PI_BAD_POINTER , "bad (NULL) pointer"},
  714. {PI_NO_AUX_SPI , "no auxiliary SPI on Pi A or B"},
  715. {PI_NOT_PWM_GPIO , "GPIO is not in use for PWM"},
  716. {PI_NOT_SERVO_GPIO , "GPIO is not in use for servo pulses"},
  717. {PI_NOT_HCLK_GPIO , "GPIO has no hardware clock"},
  718. {PI_NOT_HPWM_GPIO , "GPIO has no hardware PWM"},
  719. {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 1-125M"},
  720. {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1M"},
  721. {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-250M"},
  722. {PI_BAD_HCLK_PASS , "need password to use hardware clock 1"},
  723. {PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"},
  724. {PI_BAD_DATABITS , "serial data bits not 1-32"},
  725. {PI_BAD_STOPBITS , "serial (half) stop bits not 2-8"},
  726. {PI_MSG_TOOBIG , "socket/pipe message too big"},
  727. {PI_BAD_MALLOC_MODE , "bad memory allocation mode"},
  728. {PI_TOO_MANY_SEGS , "too many I2C transaction segments"},
  729. {PI_BAD_I2C_SEG , "an I2C transaction segment failed"},
  730. {PI_BAD_SMBUS_CMD , "SMBus command not supported by driver"},
  731. {PI_NOT_I2C_GPIO , "no bit bang I2C in progress on GPIO"},
  732. {PI_BAD_I2C_WLEN , "bad I2C write length"},
  733. {PI_BAD_I2C_RLEN , "bad I2C read length"},
  734. {PI_BAD_I2C_CMD , "bad I2C command"},
  735. {PI_BAD_I2C_BAUD , "bad I2C baud rate, not 50-500k"},
  736. {PI_CHAIN_LOOP_CNT , "bad chain loop count"},
  737. {PI_BAD_CHAIN_LOOP , "empty chain loop"},
  738. {PI_CHAIN_COUNTER , "too many chain counters"},
  739. {PI_BAD_CHAIN_CMD , "bad chain command"},
  740. {PI_BAD_CHAIN_DELAY , "bad chain delay micros"},
  741. {PI_CHAIN_NESTING , "chain counters nested too deeply"},
  742. {PI_CHAIN_TOO_BIG , "chain is too long"},
  743. {PI_DEPRECATED , "deprecated function removed"},
  744. {PI_BAD_SER_INVERT , "bit bang serial invert not 0 or 1"},
  745. {PI_BAD_EDGE , "bad ISR edge, not 1, 1, or 2"},
  746. {PI_BAD_ISR_INIT , "bad ISR initialisation"},
  747. {PI_BAD_FOREVER , "loop forever must be last chain command"},
  748. {PI_BAD_FILTER , "bad filter parameter"},
  749. {PI_BAD_PAD , "bad pad number"},
  750. {PI_BAD_STRENGTH , "bad pad drive strength"},
  751. {PI_FIL_OPEN_FAILED , "file open failed"},
  752. {PI_BAD_FILE_MODE , "bad file mode"},
  753. {PI_BAD_FILE_FLAG , "bad file flag"},
  754. {PI_BAD_FILE_READ , "bad file read"},
  755. {PI_BAD_FILE_WRITE , "bad file write"},
  756. {PI_FILE_NOT_ROPEN , "file not open for read"},
  757. {PI_FILE_NOT_WOPEN , "file not open for write"},
  758. {PI_BAD_FILE_SEEK , "bad file seek"},
  759. {PI_NO_FILE_MATCH , "no files match pattern"},
  760. {PI_NO_FILE_ACCESS , "no permission to access file"},
  761. {PI_FILE_IS_A_DIR , "file is a directory"},
  762. {PI_BAD_SHELL_STATUS , "bad shell return status"},
  763. {PI_BAD_SCRIPT_NAME , "bad script name"},
  764. {PI_BAD_SPI_BAUD , "bad SPI baud rate, not 50-500k"},
  765. {PI_NOT_SPI_GPIO , "no bit bang SPI in progress on GPIO"},
  766. {PI_BAD_EVENT_ID , "bad event id"},
  767. {PI_CMD_INTERRUPTED , "command interrupted, Python"},
  768. };
  769. #endregion
  770. #region # private property
  771. private TcpConnection TcpConnection { get; set; }
  772. private TcpConnection NotifyTcpConnection { get; set; }
  773. #endregion
  774. #region # public property
  775. private object _lockObject = new object();
  776. public object LockObject
  777. {
  778. get
  779. {
  780. return _lockObject;
  781. }
  782. }
  783. private NetworkStream _commandStream = null;
  784. public NetworkStream CommandStream
  785. {
  786. get
  787. {
  788. return _commandStream;
  789. }
  790. private set
  791. {
  792. _commandStream = value;
  793. if (CommandStreamChanged != null)
  794. {
  795. CommandStreamChanged.Invoke(this, new EventArgs());
  796. }
  797. if (StreamChanged != null)
  798. {
  799. StreamChanged.Invoke(this, new EventArgs());
  800. }
  801. if (CommandStream != null && NotifyStream != null && !isConnecting)
  802. {
  803. isConnecting = true;
  804. if (StreamConnected != null)
  805. {
  806. StreamConnected.Invoke(this, new EventArgs());
  807. }
  808. }
  809. }
  810. }
  811. private NetworkStream _notifyStream = null;
  812. public NetworkStream NotifyStream
  813. {
  814. get
  815. {
  816. return _notifyStream;
  817. }
  818. private set
  819. {
  820. _notifyStream = value;
  821. if (NotifyStreamChanged != null)
  822. {
  823. NotifyStreamChanged.Invoke(this, new EventArgs());
  824. }
  825. if (StreamChanged != null)
  826. {
  827. StreamChanged.Invoke(this, new EventArgs());
  828. }
  829. if (CommandStream != null && NotifyStream != null && !isConnecting)
  830. {
  831. isConnecting = true;
  832. if (StreamConnected != null)
  833. {
  834. StreamConnected.Invoke(this, new EventArgs());
  835. }
  836. }
  837. }
  838. }
  839. public bool IsOpened
  840. {
  841. get
  842. {
  843. if (this.TcpConnection == null || NotifyTcpConnection == null)
  844. return false;
  845. return this.TcpConnection.IsOpened && NotifyTcpConnection.IsOpened;
  846. }
  847. }
  848. public bool CanRead
  849. {
  850. get
  851. {
  852. if (this.TcpConnection.Stream == null || NotifyTcpConnection.Stream == null)
  853. return false;
  854. return this.TcpConnection.Stream.CanRead && NotifyTcpConnection.Stream.CanRead;
  855. }
  856. }
  857. public bool CanWrite
  858. {
  859. get
  860. {
  861. if (this.TcpConnection.Stream == null || NotifyTcpConnection.Stream == null)
  862. return false;
  863. return this.TcpConnection.Stream.CanWrite && NotifyTcpConnection.Stream.CanWrite;
  864. }
  865. }
  866. #endregion
  867. #region # constructor
  868. public PigpiodIf()
  869. {
  870. this.TcpConnection = new TcpConnection();
  871. this.TcpConnection.StreamChanged += (s, evt) =>
  872. {
  873. this.CommandStream = this.TcpConnection.Stream;
  874. };
  875. NotifyTcpConnection = new TcpConnection();
  876. NotifyTcpConnection.StreamChanged += (s, evt) =>
  877. {
  878. NotifyStream = NotifyTcpConnection.Stream;
  879. if (NotifyTcpConnection.Stream != null)
  880. {
  881. NotifyStream.ReadTimeout = Timeout.Infinite;
  882. gPigHandle = pigpio_notify();
  883. if (gPigHandle >= 0)
  884. {
  885. gLastLevel = read_bank_1();
  886. cts = new CancellationTokenSource();
  887. Task.Run(() => NotifyThread(cts.Token));
  888. }
  889. }
  890. };
  891. }
  892. #endregion
  893. #region # Implementation of IDisposable
  894. bool disposed = false;
  895. public void Dispose()
  896. {
  897. Dispose(true);
  898. GC.SuppressFinalize(this);
  899. }
  900. protected virtual void Dispose(bool disposing)
  901. {
  902. if (disposed)
  903. return;
  904. if (disposing)
  905. {
  906. // Release managed objects
  907. pigpio_stop();
  908. }
  909. // Release unmanaged objects
  910. disposed = true;
  911. }
  912. ~PigpiodIf()
  913. {
  914. Dispose(false);
  915. }
  916. #endregion
  917. #region # public method
  918. public double time_time()
  919. {
  920. DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, 0);
  921. DateTime targetTime = DateTime.Now.ToUniversalTime();
  922. TimeSpan elapsedTime = targetTime - UNIX_EPOCH;
  923. return elapsedTime.TotalSeconds;
  924. }
  925. public void time_sleep(double seconds)
  926. {
  927. Task.Run(async () =>
  928. {
  929. long milliseconds = (long)(seconds * 1000);
  930. sw.Restart();
  931. int rest = (int)(milliseconds - sw.ElapsedMilliseconds);
  932. if (rest > 200)
  933. {
  934. await Task.Delay(rest - 200);
  935. }
  936. while (sw.ElapsedMilliseconds < milliseconds)
  937. {
  938. }
  939. sw.Stop();
  940. }).Wait();
  941. }
  942. public string pigpio_error(int errnum)
  943. {
  944. if (errnum > -1000)
  945. {
  946. if (errInfo.ContainsKey(errnum))
  947. {
  948. return errInfo[errnum];
  949. }
  950. else
  951. {
  952. return "unknown error";
  953. }
  954. }
  955. else
  956. {
  957. switch ((EError)errnum)
  958. {
  959. case EError.pigif_bad_send:
  960. return "failed to send to pigpiod";
  961. case EError.pigif_bad_recv:
  962. return "failed to receive from pigpiod";
  963. case EError.pigif_bad_getaddrinfo:
  964. return "failed to find address of pigpiod";
  965. case EError.pigif_bad_connect:
  966. return "failed to connect to pigpiod";
  967. case EError.pigif_bad_socket:
  968. return "failed to create socket";
  969. case EError.pigif_bad_noib:
  970. return "failed to open notification in band";
  971. case EError.pigif_duplicate_callback:
  972. return "identical callback exists";
  973. case EError.pigif_bad_malloc:
  974. return "failed to malloc";
  975. case EError.pigif_bad_callback:
  976. return "bad callback parameter";
  977. case EError.pigif_notify_failed:
  978. return "failed to create notification thread";
  979. case EError.pigif_callback_not_found:
  980. return "callback not found";
  981. case EError.pigif_unconnected_pi:
  982. return "not connected to Pi";
  983. case EError.pigif_too_many_pis:
  984. return "too many connected Pis";
  985. default:
  986. return "unknown error";
  987. }
  988. }
  989. }
  990. public UInt32 pigpiod_if_version()
  991. {
  992. return PIGPIOD_IF2_VERSION;
  993. }
  994. // Do not implement
  995. // start_thread() and
  996. // stop_thread().
  997. public int pigpio_start(string addrStr, string portStr)
  998. {
  999. if (string.IsNullOrWhiteSpace(addrStr))
  1000. {
  1001. addrStr = PI_DEFAULT_SOCKET_ADDR_STR;
  1002. }
  1003. if (string.IsNullOrWhiteSpace(portStr))
  1004. {
  1005. portStr = PI_DEFAULT_SOCKET_PORT_STR;
  1006. }
  1007. int port;
  1008. if (int.TryParse(portStr, out port) == false)
  1009. {
  1010. return (int)EError.pigif_bad_getaddrinfo;
  1011. }
  1012. isConnecting = false;
  1013. this.TcpConnection.Open(addrStr, port);
  1014. NotifyTcpConnection.Open(addrStr, port);
  1015. return 0;
  1016. }
  1017. public void pigpio_stop()
  1018. {
  1019. if (cts != null)
  1020. {
  1021. cts.Cancel();
  1022. }
  1023. if (gPigHandle >= 0)
  1024. {
  1025. pigpio_command(PI_CMD_NC, gPigHandle, 0);
  1026. gPigHandle = -1;
  1027. }
  1028. if (this.TcpConnection != null)
  1029. {
  1030. // Execute handlers of StreamChanged event, and call Close()
  1031. this.CommandStream = null;
  1032. this.TcpConnection.Close();
  1033. }
  1034. if (NotifyTcpConnection != null)
  1035. {
  1036. // Execute handlers of NotifyStreamChanged event, and call Close()
  1037. NotifyStream = null;
  1038. NotifyTcpConnection.Close();
  1039. }
  1040. }
  1041. public int set_mode(UInt32 gpio, UInt32 mode)
  1042. { return pigpio_command(PI_CMD_MODES, (int)gpio, (int)mode); }
  1043. public int get_mode(UInt32 gpio)
  1044. { return pigpio_command(PI_CMD_MODEG, (int)gpio, 0); }
  1045. public int set_pull_up_down(UInt32 gpio, UInt32 pud)
  1046. { return pigpio_command(PI_CMD_PUD, (int)gpio, (int)pud); }
  1047. public int gpio_read(UInt32 gpio)
  1048. { return pigpio_command(PI_CMD_READ, (int)gpio, 0); }
  1049. public int gpio_write(UInt32 gpio, UInt32 level)
  1050. { return pigpio_command(PI_CMD_WRITE, (int)gpio, (int)level); }
  1051. public int set_PWM_dutycycle(UInt32 user_gpio, UInt32 dutycycle)
  1052. { return pigpio_command(PI_CMD_PWM, (int)user_gpio, (int)dutycycle); }
  1053. public int get_PWM_dutycycle(UInt32 user_gpio)
  1054. { return pigpio_command(PI_CMD_GDC, (int)user_gpio, 0); }
  1055. public int set_PWM_range(UInt32 user_gpio, UInt32 range)
  1056. { return pigpio_command(PI_CMD_PRS, (int)user_gpio, (int)range); }
  1057. public int get_PWM_range(UInt32 user_gpio)
  1058. { return pigpio_command(PI_CMD_PRG, (int)user_gpio, 0); }
  1059. public int get_PWM_real_range(UInt32 user_gpio)
  1060. { return pigpio_command(PI_CMD_PRRG, (int)user_gpio, 0); }
  1061. public int set_PWM_frequency(UInt32 user_gpio, UInt32 frequency)
  1062. { return pigpio_command(PI_CMD_PFS, (int)user_gpio, (int)frequency); }
  1063. public int get_PWM_frequency(UInt32 user_gpio)
  1064. { return pigpio_command(PI_CMD_PFG, (int)user_gpio, 0); }
  1065. public int set_servo_pulsewidth(UInt32 user_gpio, UInt32 pulsewidth)
  1066. { return pigpio_command(PI_CMD_SERVO, (int)user_gpio, (int)pulsewidth); }
  1067. public int get_servo_pulsewidth(UInt32 user_gpio)
  1068. { return pigpio_command(PI_CMD_GPW, (int)user_gpio, 0); }
  1069. public int notify_open()
  1070. { return pigpio_command(PI_CMD_NO, 0, 0); }
  1071. public int notify_begin(UInt32 handle, UInt32 bits)
  1072. { return pigpio_command(PI_CMD_NB, (int)handle, (int)bits); }
  1073. public int notify_pause(UInt32 handle)
  1074. { return pigpio_command(PI_CMD_NB, (int)handle, 0); }
  1075. public int notify_close(UInt32 handle)
  1076. { return pigpio_command(PI_CMD_NC, (int)handle, 0); }
  1077. public int set_watchdog(UInt32 user_gpio, UInt32 timeout)
  1078. { return pigpio_command(PI_CMD_WDOG, (int)user_gpio, (int)timeout); }
  1079. public UInt32 read_bank_1()
  1080. { return (UInt32)pigpio_command(PI_CMD_BR1, 0, 0); }
  1081. public UInt32 read_bank_2()
  1082. { return (UInt32)pigpio_command(PI_CMD_BR2, 0, 0); }
  1083. public int clear_bank_1(UInt32 levels)
  1084. { return pigpio_command(PI_CMD_BC1, (int)levels, 0); }
  1085. public int clear_bank_2(UInt32 levels)
  1086. { return pigpio_command(PI_CMD_BC2, (int)levels, 0); }
  1087. public int set_bank_1(UInt32 levels)
  1088. { return pigpio_command(PI_CMD_BS1, (int)levels, 0); }
  1089. public int set_bank_2(UInt32 levels)
  1090. { return pigpio_command(PI_CMD_BS2, (int)levels, 0); }
  1091. public int hardware_clock(UInt32 gpio, UInt32 frequency)
  1092. { return pigpio_command(PI_CMD_HC, (int)gpio, (int)frequency); }
  1093. public int hardware_PWM(UInt32 gpio, UInt32 frequency, UInt32 dutycycle)
  1094. {
  1095. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1096. /*
  1097. p1=gpio
  1098. p2=frequency
  1099. p3=4
  1100. ## extension ##
  1101. uint32_t dutycycle
  1102. */
  1103. exts[0].Contents = UInt32ToBytes(dutycycle);
  1104. return pigpio_command_ext(PI_CMD_HP, (int)gpio, (int)frequency, exts);
  1105. }
  1106. public UInt32 get_current_tick()
  1107. { return (UInt32)pigpio_command(PI_CMD_TICK, 0, 0); }
  1108. public UInt32 get_hardware_revision()
  1109. { return (UInt32)pigpio_command(PI_CMD_HWVER, 0, 0); }
  1110. public UInt32 get_pigpio_version()
  1111. { return (UInt32)pigpio_command(PI_CMD_PIGPV, 0, 0); }
  1112. public int wave_clear()
  1113. { return pigpio_command(PI_CMD_WVCLR, 0, 0); }
  1114. public int wave_add_new()
  1115. { return pigpio_command(PI_CMD_WVNEW, 0, 0); }
  1116. public int wave_add_generic(GpioPulse[] pulses)
  1117. {
  1118. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1119. /*
  1120. p1=0
  1121. p2=0
  1122. p3=pulses*sizeof(gpioPulse_t)
  1123. ## extension ##
  1124. gpioPulse_t[] pulses
  1125. */
  1126. if (pulses.Length == 0) return 0;
  1127. List<UInt32> list = new List<UInt32>();
  1128. foreach (var pulse in pulses)
  1129. {
  1130. list.Add(pulse.gpioOn);
  1131. list.Add(pulse.gpioOff);
  1132. list.Add(pulse.usDelay);
  1133. }
  1134. exts[0].Contents = UInt32ArrayToBytes(list.ToArray());
  1135. return pigpio_command_ext(PI_CMD_WVAG, 0, 0, exts);
  1136. }
  1137. public int wave_add_serial(
  1138. UInt32 user_gpio, UInt32 baud, UInt32 databits,
  1139. UInt32 stophalfbits, UInt32 offset, byte[] str)
  1140. {
  1141. GpioExtent[] exts = new GpioExtent[] {
  1142. new GpioExtent(),
  1143. new GpioExtent()
  1144. };
  1145. /*
  1146. p1=user_gpio
  1147. p2=baud
  1148. p3=len+12
  1149. ## extension ##
  1150. uint32_t databits
  1151. uint32_t stophalfbits
  1152. uint32_t offset
  1153. char[len] str
  1154. */
  1155. if (str.Length == 0)
  1156. return 0;
  1157. UInt32[] array = new UInt32[]
  1158. {
  1159. databits,
  1160. stophalfbits,
  1161. offset
  1162. };
  1163. exts[0].Contents = UInt32ArrayToBytes(array);
  1164. exts[1].Contents = str;
  1165. return pigpio_command_ext(PI_CMD_WVAS, (int)user_gpio, (int)baud, exts);
  1166. }
  1167. public int wave_create()
  1168. { return pigpio_command(PI_CMD_WVCRE, 0, 0); }
  1169. public int wave_delete(UInt32 wave_id)
  1170. { return pigpio_command(PI_CMD_WVDEL, (int)wave_id, 0); }
  1171. public int wave_tx_start() /* DEPRECATED */
  1172. { return pigpio_command(PI_CMD_WVGO, 0, 0); }
  1173. public int wave_tx_repeat() /* DEPRECATED */
  1174. { return pigpio_command(PI_CMD_WVGOR, 0, 0); }
  1175. public int wave_send_once(UInt32 wave_id)
  1176. { return pigpio_command(PI_CMD_WVTX, (int)wave_id, 0); }
  1177. public int wave_send_repeat(UInt32 wave_id)
  1178. { return pigpio_command(PI_CMD_WVTXR, (int)wave_id, 0); }
  1179. public int wave_send_using_mode(UInt32 wave_id, UInt32 mode)
  1180. { return pigpio_command(PI_CMD_WVTXM, (int)wave_id, (int)mode); }
  1181. public int wave_chain(byte[] buf)
  1182. {
  1183. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1184. /*
  1185. p1=0
  1186. p2=0
  1187. p3=bufSize
  1188. ## extension ##
  1189. char buf[bufSize]
  1190. */
  1191. exts[0].Contents = buf;
  1192. return pigpio_command_ext(PI_CMD_WVCHA, 0, 0, exts);
  1193. }
  1194. public int wave_tx_at()
  1195. { return pigpio_command(PI_CMD_WVTAT, 0, 0); }
  1196. public int wave_tx_busy()
  1197. { return pigpio_command(PI_CMD_WVBSY, 0, 0); }
  1198. public int wave_tx_stop()
  1199. { return pigpio_command(PI_CMD_WVHLT, 0, 0); }
  1200. public int wave_get_micros()
  1201. { return pigpio_command(PI_CMD_WVSM, 0, 0); }
  1202. public int wave_get_high_micros()
  1203. { return pigpio_command(PI_CMD_WVSM, 1, 0); }
  1204. public int wave_get_max_micros()
  1205. { return pigpio_command(PI_CMD_WVSM, 2, 0); }
  1206. public int wave_get_pulses()
  1207. { return pigpio_command(PI_CMD_WVSP, 0, 0); }
  1208. public int wave_get_high_pulses()
  1209. { return pigpio_command(PI_CMD_WVSP, 1, 0); }
  1210. public int wave_get_max_pulses()
  1211. { return pigpio_command(PI_CMD_WVSP, 2, 0); }
  1212. public int wave_get_cbs()
  1213. { return pigpio_command(PI_CMD_WVSC, 0, 0); }
  1214. public int wave_get_high_cbs()
  1215. { return pigpio_command(PI_CMD_WVSC, 1, 0); }
  1216. public int wave_get_max_cbs()
  1217. { return pigpio_command(PI_CMD_WVSC, 2, 0); }
  1218. public int gpio_trigger(UInt32 user_gpio, UInt32 pulseLen, UInt32 level)
  1219. {
  1220. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1221. /*
  1222. p1=user_gpio
  1223. p2=pulseLen
  1224. p3=4
  1225. ## extension ##
  1226. unsigned level
  1227. */
  1228. exts[0].Contents = UInt32ToBytes(level);
  1229. return pigpio_command_ext(PI_CMD_TRIG, (int)user_gpio, (int)pulseLen, exts);
  1230. }
  1231. public int set_glitch_filter(UInt32 user_gpio, UInt32 steady)
  1232. { return pigpio_command(PI_CMD_FG, (int)user_gpio, (int)steady); }
  1233. public int set_noise_filter(UInt32 user_gpio, UInt32 steady, UInt32 active)
  1234. {
  1235. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1236. /*
  1237. p1=user_gpio
  1238. p2=steady
  1239. p3=4
  1240. ## extension ##
  1241. unsigned active
  1242. */
  1243. exts[0].Contents = UInt32ToBytes(active);
  1244. return pigpio_command_ext(PI_CMD_FN, (int)user_gpio, (int)steady, exts);
  1245. }
  1246. public int store_script(byte[] script)
  1247. {
  1248. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1249. /*
  1250. p1=0
  1251. p2=0
  1252. p3=len
  1253. ## extension ##
  1254. char[len] script
  1255. */
  1256. if (script.Length == 0)
  1257. return 0;
  1258. exts[0].Contents = script;
  1259. return pigpio_command_ext(PI_CMD_PROC, 0, 0, exts);
  1260. }
  1261. public int run_script(UInt32 script_id, UInt32[] paramArray)
  1262. {
  1263. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1264. /*
  1265. p1=script id
  1266. p2=0
  1267. p3=numPar * 4
  1268. ## extension ##
  1269. uint32_t[numPar] pars
  1270. */
  1271. exts[0].Contents = UInt32ArrayToBytes(paramArray);
  1272. return pigpio_command_ext(PI_CMD_PROCR, (int)script_id, 0, exts);
  1273. }
  1274. public int update_script(UInt32 script_id, UInt32[] paramArray)
  1275. {
  1276. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1277. /*
  1278. p1=script id
  1279. p2=0
  1280. p3=numPar * 4
  1281. ## extension ##
  1282. uint32_t[numPar] pars
  1283. */
  1284. exts[0].Contents = UInt32ArrayToBytes(paramArray);
  1285. return pigpio_command_ext(PI_CMD_PROCU, (int)script_id, 0, exts);
  1286. }
  1287. public int script_status(UInt32 script_id, UInt32[] param)
  1288. {
  1289. int status;
  1290. byte[] bytes = new byte[4 * (PI_MAX_SCRIPT_PARAMS + 1)]; /* space for script status */
  1291. lock (LockObject)
  1292. {
  1293. status = pigpio_command(PI_CMD_PROCP, (int)script_id, 0);
  1294. if (status > 0)
  1295. {
  1296. recvMax(bytes, status);
  1297. // byte[] -> UInt32[]
  1298. var p = BytesToUInt32Array(bytes);
  1299. status = (int)p[0];
  1300. for (int i = 0; i < param.Length; i++)
  1301. {
  1302. param[i] = p[i + 1];
  1303. }
  1304. }
  1305. }
  1306. return status;
  1307. }
  1308. public int stop_script(UInt32 script_id)
  1309. { return pigpio_command(PI_CMD_PROCS, (int)script_id, 0); }
  1310. public int delete_script(UInt32 script_id)
  1311. { return pigpio_command(PI_CMD_PROCD, (int)script_id, 0); }
  1312. public int bb_serial_read_open(UInt32 user_gpio, UInt32 baud, UInt32 bbBits)
  1313. {
  1314. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1315. /*
  1316. p1=user_gpio
  1317. p2=baud
  1318. p3=4
  1319. ## extension ##
  1320. unsigned bbBits
  1321. */
  1322. exts[0].Contents = UInt32ToBytes(bbBits);
  1323. return pigpio_command_ext(PI_CMD_SLRO, (int)user_gpio, (int)baud, exts);
  1324. }
  1325. public int bb_serial_read(UInt32 user_gpio, byte[] buf)
  1326. {
  1327. int bytes;
  1328. lock (LockObject)
  1329. {
  1330. bytes = pigpio_command(PI_CMD_SLR, (int)user_gpio, buf.Length);
  1331. if (bytes > 0)
  1332. {
  1333. bytes = recvMax(buf, bytes);
  1334. }
  1335. }
  1336. return bytes;
  1337. }
  1338. public int bb_serial_read_close(UInt32 user_gpio)
  1339. { return pigpio_command(PI_CMD_SLRC, (int)user_gpio, 0); }
  1340. public int bb_serial_invert(UInt32 user_gpio, UInt32 invert)
  1341. { return pigpio_command(PI_CMD_SLRI, (int)user_gpio, (int)invert); }
  1342. public int i2c_open(UInt32 i2c_bus, UInt32 i2c_addr, UInt32 i2c_flags)
  1343. {
  1344. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1345. /*
  1346. p1=i2c_bus
  1347. p2=i2c_addr
  1348. p3=4
  1349. ## extension ##
  1350. uint32_t i2c_flags
  1351. */
  1352. exts[0].Contents = UInt32ToBytes(i2c_flags);
  1353. return pigpio_command_ext(PI_CMD_I2CO, (int)i2c_bus, (int)i2c_addr, exts);
  1354. }
  1355. public int i2c_close(UInt32 handle)
  1356. { return pigpio_command(PI_CMD_I2CC, (int)handle, 0); }
  1357. public int i2c_write_quick(UInt32 handle, UInt32 bit)
  1358. { return pigpio_command(PI_CMD_I2CWQ, (int)handle, (int)bit); }
  1359. public int i2c_write_byte(UInt32 handle, UInt32 val)
  1360. { return pigpio_command(PI_CMD_I2CWS, (int)handle, (int)val); }
  1361. public int i2c_read_byte(UInt32 handle)
  1362. { return pigpio_command(PI_CMD_I2CRS, (int)handle, 0); }
  1363. public int i2c_write_byte_data(UInt32 handle, UInt32 reg, UInt32 val)
  1364. {
  1365. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1366. /*
  1367. p1=handle
  1368. p2=reg
  1369. p3=4
  1370. ## extension ##
  1371. uint32_t val
  1372. */
  1373. exts[0].Contents = UInt32ToBytes(val);
  1374. return pigpio_command_ext(PI_CMD_I2CWB, (int)handle, (int)reg, exts);
  1375. }
  1376. public int i2c_write_word_data(UInt32 handle, UInt32 reg, UInt32 val)
  1377. {
  1378. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1379. /*
  1380. p1=handle
  1381. p2=reg
  1382. p3=4
  1383. ## extension ##
  1384. uint32_t val
  1385. */
  1386. exts[0].Contents = UInt32ToBytes(val);
  1387. return pigpio_command_ext(PI_CMD_I2CWW, (int)handle, (int)reg, exts);
  1388. }
  1389. public int i2c_read_byte_data(UInt32 handle, UInt32 reg)
  1390. { return pigpio_command(PI_CMD_I2CRB, (int)handle, (int)reg); }
  1391. public int i2c_read_word_data(UInt32 handle, UInt32 reg)
  1392. { return pigpio_command(PI_CMD_I2CRW, (int)handle, (int)reg); }
  1393. public int i2c_process_call(UInt32 handle, UInt32 reg, UInt32 val)
  1394. {
  1395. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1396. /*
  1397. p1=handle
  1398. p2=reg
  1399. p3=4
  1400. ## extension ##
  1401. uint32_t val
  1402. */
  1403. exts[0].Contents = UInt32ToBytes(val);
  1404. return pigpio_command_ext(PI_CMD_I2CPK, (int)handle, (int)reg, exts);
  1405. }
  1406. public int i2c_write_block_data(UInt32 handle, UInt32 reg, byte[] buf)
  1407. {
  1408. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1409. /*
  1410. p1=handle
  1411. p2=reg
  1412. p3=count
  1413. ## extension ##
  1414. char buf[count]
  1415. */
  1416. exts[0].Contents = buf;
  1417. return pigpio_command_ext(PI_CMD_I2CWK, (int)handle, (int)reg, exts);
  1418. }
  1419. public int i2c_read_block_data(UInt32 handle, UInt32 reg, byte[] buf)
  1420. {
  1421. int bytes;
  1422. lock (LockObject)
  1423. {
  1424. bytes = pigpio_command(PI_CMD_I2CRK, (int)handle, (int)reg);
  1425. if (bytes > 0)
  1426. {
  1427. // 32バイト固定になっていたが、不明
  1428. bytes = recvMax(buf, bytes);
  1429. }
  1430. }
  1431. return bytes;
  1432. }
  1433. public int i2c_block_process_call(UInt32 handle, UInt32 reg, byte[] buf)
  1434. {
  1435. int bytes;
  1436. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1437. /*
  1438. p1=handle
  1439. p2=reg
  1440. p3=count
  1441. ## extension ##
  1442. char buf[count]
  1443. */
  1444. exts[0].Contents = buf;
  1445. lock (LockObject)
  1446. {
  1447. bytes = pigpio_command_ext(PI_CMD_I2CPK, (int)handle, (int)reg, exts);
  1448. if (bytes > 0)
  1449. {
  1450. // 32バイト固定になっていたが、不明
  1451. bytes = recvMax(buf, bytes);
  1452. }
  1453. }
  1454. return bytes;
  1455. }
  1456. public int i2c_read_i2c_block_data(UInt32 handle, UInt32 reg, byte[] buf)
  1457. {
  1458. int bytes;
  1459. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1460. /*
  1461. p1=handle
  1462. p2=reg
  1463. p3=4
  1464. ## extension ##
  1465. uint32_t count
  1466. */
  1467. UInt32 count = (UInt32)buf.Length;
  1468. exts[0].Contents = UInt32ToBytes(count);
  1469. lock (LockObject)
  1470. {
  1471. bytes = pigpio_command_ext(PI_CMD_I2CRI, (int)handle, (int)reg, exts);
  1472. if (bytes > 0)
  1473. {
  1474. bytes = recvMax(buf, bytes);
  1475. }
  1476. }
  1477. return bytes;
  1478. }
  1479. public int i2c_write_i2c_block_data(UInt32 handle, UInt32 reg, byte[] buf)
  1480. {
  1481. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1482. /*
  1483. p1=handle
  1484. p2=reg
  1485. p3=count
  1486. ## extension ##
  1487. char buf[count]
  1488. */
  1489. exts[0].Contents = buf;
  1490. return pigpio_command_ext(PI_CMD_I2CWI, (int)handle, (int)reg, exts);
  1491. }
  1492. public int i2c_read_device(UInt32 handle, byte[] buf)
  1493. {
  1494. int bytes;
  1495. lock (LockObject)
  1496. {
  1497. bytes = pigpio_command(PI_CMD_I2CRD, (int)handle, buf.Length);
  1498. if (bytes > 0)
  1499. {
  1500. bytes = recvMax(buf, bytes);
  1501. }
  1502. }
  1503. return bytes;
  1504. }
  1505. public int i2c_write_device(UInt32 handle, byte[] buf)
  1506. {
  1507. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1508. /*
  1509. p1=handle
  1510. p2=0
  1511. p3=count
  1512. ## extension ##
  1513. char buf[count]
  1514. */
  1515. exts[0].Contents = buf;
  1516. return pigpio_command_ext(PI_CMD_I2CWD, (int)handle, 0, exts);
  1517. }
  1518. public int i2c_zip(UInt32 handle, byte[] inBuf, byte[] outBuf)
  1519. {
  1520. int bytes;
  1521. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1522. /*
  1523. p1=handle
  1524. p2=0
  1525. p3=inLen
  1526. ## extension ##
  1527. char inBuf[inLen]
  1528. */
  1529. exts[0].Contents = inBuf;
  1530. lock (LockObject)
  1531. {
  1532. bytes = pigpio_command_ext(PI_CMD_I2CZ, (int)handle, 0, exts);
  1533. if (bytes > 0)
  1534. {
  1535. bytes = recvMax(outBuf, bytes);
  1536. }
  1537. }
  1538. return bytes;
  1539. }
  1540. public int bb_i2c_open(UInt32 SDA, UInt32 SCL, UInt32 baud)
  1541. {
  1542. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1543. /*
  1544. p1=SDA
  1545. p2=SCL
  1546. p3=4
  1547. ## extension ##
  1548. uint32_t baud
  1549. */
  1550. exts[0].Contents = UInt32ToBytes(baud);
  1551. return pigpio_command_ext(PI_CMD_BI2CO, (int)SDA, (int)SCL, exts);
  1552. }
  1553. public int bb_i2c_close(UInt32 SDA)
  1554. { return pigpio_command(PI_CMD_BI2CC, (int)SDA, 0); }
  1555. public int bb_i2c_zip(UInt32 SDA, byte[] inBuf, byte[] outBuf)
  1556. {
  1557. int bytes;
  1558. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1559. /*
  1560. p1=SDA
  1561. p2=0
  1562. p3=inLen
  1563. ## extension ##
  1564. char inBuf[inLen]
  1565. */
  1566. exts[0].Contents = inBuf;
  1567. lock (LockObject)
  1568. {
  1569. bytes = pigpio_command_ext(PI_CMD_BI2CZ, (int)SDA, 0, exts);
  1570. if (bytes > 0)
  1571. {
  1572. bytes = recvMax(outBuf, bytes);
  1573. }
  1574. }
  1575. return bytes;
  1576. }
  1577. public int bb_spi_open(
  1578. UInt32 CS, UInt32 MISO, UInt32 MOSI, UInt32 SCLK,
  1579. UInt32 baud, UInt32 spiFlags)
  1580. {
  1581. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1582. /*
  1583. p1=CS
  1584. p2=0
  1585. p3=20
  1586. ## extension ##
  1587. uint32_t MISO
  1588. uint32_t MOSI
  1589. uint32_t SCLK
  1590. uint32_t baud
  1591. uint32_t spiFlags
  1592. */
  1593. exts[0].Contents = UInt32ArrayToBytes(new UInt32[] {
  1594. MISO, MOSI, SCLK, baud, spiFlags
  1595. });
  1596. return pigpio_command_ext(PI_CMD_BSPIO, (int)CS, 0, exts);
  1597. }
  1598. public int bb_spi_close(UInt32 CS)
  1599. { return pigpio_command(PI_CMD_BSPIC, (int)CS, 0); }
  1600. public int bb_spi_xfer(UInt32 CS, byte[] txBuf, byte[] rxBuf)
  1601. {
  1602. int bytes;
  1603. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1604. /*
  1605. p1=CS
  1606. p2=0
  1607. p3=count
  1608. ## extension ##
  1609. char txBuf[count]
  1610. */
  1611. exts[0].Contents = txBuf;
  1612. lock (LockObject)
  1613. {
  1614. bytes = pigpio_command_ext(PI_CMD_BSPIX, (int)CS, 0, exts);
  1615. if (bytes > 0)
  1616. {
  1617. bytes = recvMax(rxBuf, bytes);
  1618. }
  1619. }
  1620. return bytes;
  1621. }
  1622. public int spi_open(UInt32 channel, UInt32 speed, UInt32 flags)
  1623. {
  1624. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1625. /*
  1626. p1=channel
  1627. p2=speed
  1628. p3=4
  1629. ## extension ##
  1630. uint32_t flags
  1631. */
  1632. exts[0].Contents = UInt32ToBytes(flags);
  1633. return pigpio_command_ext(PI_CMD_SPIO, (int)channel, (int)speed, exts);
  1634. }
  1635. public int spi_close(UInt32 handle)
  1636. { return pigpio_command(PI_CMD_SPIC, (int)handle, 0); }
  1637. public int spi_read(UInt32 handle, byte[] buf)
  1638. {
  1639. int bytes;
  1640. lock (LockObject)
  1641. {
  1642. bytes = pigpio_command(PI_CMD_SPIR, (int)handle, buf.Length);
  1643. if (bytes > 0)
  1644. {
  1645. bytes = recvMax(buf, bytes);
  1646. }
  1647. }
  1648. return bytes;
  1649. }
  1650. public int spi_write(UInt32 handle, byte[] buf)
  1651. {
  1652. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1653. /*
  1654. p1=handle
  1655. p2=0
  1656. p3=count
  1657. ## extension ##
  1658. char buf[count]
  1659. */
  1660. exts[0].Contents = buf;
  1661. return pigpio_command_ext(PI_CMD_SPIW, (int)handle, 0, exts);
  1662. }
  1663. public int spi_xfer(UInt32 handle, byte[] txBuf, byte[] rxBuf)
  1664. {
  1665. int bytes;
  1666. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1667. /*
  1668. p1=handle
  1669. p2=0
  1670. p3=count
  1671. ## extension ##
  1672. char buf[count]
  1673. */
  1674. exts[0].Contents = txBuf;
  1675. lock (LockObject)
  1676. {
  1677. bytes = pigpio_command_ext(PI_CMD_SPIX, (int)handle, 0, exts);
  1678. if (bytes > 0)
  1679. {
  1680. bytes = recvMax(rxBuf, bytes);
  1681. }
  1682. }
  1683. return bytes;
  1684. }
  1685. public int serial_open(string dev, UInt32 baud, UInt32 flags)
  1686. {
  1687. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1688. /*
  1689. p1=baud
  1690. p2=flags
  1691. p3=len
  1692. ## extension ##
  1693. char dev[len]
  1694. */
  1695. var bytes = Encoding.UTF8.GetBytes(dev);
  1696. exts[0].Contents = bytes;
  1697. return pigpio_command_ext(PI_CMD_SERO, (int)baud, (int)flags, exts);
  1698. }
  1699. public int serial_close(UInt32 handle)
  1700. { return pigpio_command(PI_CMD_SERC, (int)handle, 0); }
  1701. public int serial_write_byte(UInt32 handle, UInt32 val)
  1702. { return pigpio_command(PI_CMD_SERWB, (int)handle, (int)val); }
  1703. public int serial_read_byte(UInt32 handle)
  1704. { return pigpio_command(PI_CMD_SERRB, (int)handle, 0); }
  1705. public int serial_write(UInt32 handle, byte[] buf)
  1706. {
  1707. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1708. /*
  1709. p1=handle
  1710. p2=0
  1711. p3=count
  1712. ## extension ##
  1713. char buf[count]
  1714. */
  1715. exts[0].Contents = buf;
  1716. return pigpio_command_ext(PI_CMD_SERW, (int)handle, 0, exts);
  1717. }
  1718. public int serial_read(UInt32 handle, byte[] buf)
  1719. {
  1720. int bytes;
  1721. lock (LockObject)
  1722. {
  1723. bytes = pigpio_command(PI_CMD_SERR, (int)handle, buf.Length);
  1724. if (bytes > 0)
  1725. {
  1726. bytes = recvMax(buf, bytes);
  1727. }
  1728. }
  1729. return bytes;
  1730. }
  1731. public int serial_data_available(UInt32 handle)
  1732. { return pigpio_command(PI_CMD_SERDA, (int)handle, 0); }
  1733. int custom_1(UInt32 arg1, UInt32 arg2, string argx, byte[] retBuf)
  1734. {
  1735. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1736. /*
  1737. p1=arg1
  1738. p2=arg2
  1739. p3=count
  1740. ## extension ##
  1741. char argx[count]
  1742. */
  1743. exts[0].Contents = Encoding.UTF8.GetBytes(argx);
  1744. return pigpio_command_ext
  1745. (PI_CMD_CF2, (int)arg1, (int)arg2, exts);
  1746. }
  1747. int custom_2(UInt32 arg1, string argx, byte[] retBuf)
  1748. {
  1749. int bytes;
  1750. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1751. /*
  1752. p1=arg1
  1753. p2=retMax
  1754. p3=count
  1755. ## extension ##
  1756. char argx[count]
  1757. */
  1758. exts[0].Contents = Encoding.UTF8.GetBytes(argx);
  1759. lock (LockObject)
  1760. {
  1761. bytes = pigpio_command_ext
  1762. (PI_CMD_CF2, (int)arg1, retBuf.Length, exts);
  1763. if (bytes > 0)
  1764. {
  1765. bytes = recvMax(retBuf, bytes);
  1766. }
  1767. }
  1768. return bytes;
  1769. }
  1770. int get_pad_strength(UInt32 pad)
  1771. { return pigpio_command(PI_CMD_PADG, (int)pad, 0); }
  1772. int set_pad_strength(UInt32 pad, UInt32 padStrength)
  1773. { return pigpio_command(PI_CMD_PADS, (int)pad, (int)padStrength); }
  1774. int shell_(string scriptName, string scriptString)
  1775. {
  1776. GpioExtent[] exts = new GpioExtent[] {
  1777. new GpioExtent(),
  1778. new GpioExtent()
  1779. };
  1780. /*
  1781. p1=len(scriptName)
  1782. p2=0
  1783. p3=len(scriptName) + len(scriptString) + 1
  1784. ## extension ##
  1785. char[]
  1786. */
  1787. exts[0].Contents = Encoding.UTF8.GetBytes(scriptName + "\0"); /* include null byte */
  1788. exts[1].Contents = Encoding.UTF8.GetBytes(scriptString);
  1789. return pigpio_command_ext
  1790. (PI_CMD_SHELL, scriptName.Length, 0, exts);
  1791. }
  1792. int file_open(string file, UInt32 mode)
  1793. {
  1794. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1795. /*
  1796. p1=mode
  1797. p2=0
  1798. p3=len
  1799. ## extension ##
  1800. char file[len]
  1801. */
  1802. exts[0].Contents = Encoding.UTF8.GetBytes(file);
  1803. return pigpio_command_ext
  1804. (PI_CMD_FO, (int)mode, 0, exts);
  1805. }
  1806. int file_close(UInt32 handle)
  1807. { return pigpio_command(PI_CMD_FC, (int)handle, 0); }
  1808. int file_write(UInt32 handle, byte[] buf)
  1809. {
  1810. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1811. /*
  1812. p1=handle
  1813. p2=0
  1814. p3=count
  1815. ## extension ##
  1816. char buf[count]
  1817. */
  1818. exts[0].Contents = buf;
  1819. return pigpio_command_ext
  1820. (PI_CMD_FW, (int)handle, 0, exts);
  1821. }
  1822. int file_read(UInt32 handle, byte[] buf)
  1823. {
  1824. int bytes;
  1825. lock (LockObject)
  1826. {
  1827. bytes = pigpio_command
  1828. (PI_CMD_FR, (int)handle, buf.Length);
  1829. if (bytes > 0)
  1830. {
  1831. bytes = recvMax(buf, bytes);
  1832. }
  1833. }
  1834. return bytes;
  1835. }
  1836. int file_seek(UInt32 handle, UInt32 seekOffset, int seekFrom)
  1837. {
  1838. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1839. /*
  1840. p1=handle
  1841. p2=seekOffset
  1842. p3=4
  1843. ## extension ##
  1844. uint32_t seekFrom
  1845. */
  1846. exts[0].Contents = UInt32ToBytes((UInt32)seekFrom);
  1847. return pigpio_command_ext
  1848. (PI_CMD_FS, (int)handle, (int)seekOffset, exts);
  1849. }
  1850. int file_list(string fpat, byte[] buf)
  1851. {
  1852. int bytes;
  1853. GpioExtent[] exts = new GpioExtent[] { new GpioExtent() };
  1854. /*
  1855. p1=60000
  1856. p2=0
  1857. p3=len
  1858. ## extension ##
  1859. char fpat[len]
  1860. */
  1861. exts[0].Contents = Encoding.UTF8.GetBytes(fpat);
  1862. lock (LockObject)
  1863. {
  1864. bytes = pigpio_command_ext(PI_CMD_FL, 60000, 0, exts);
  1865. if (bytes > 0)
  1866. {
  1867. bytes = recvMax(buf, bytes);
  1868. }
  1869. }
  1870. return bytes;
  1871. }
  1872. public Callback callback(UInt32 user_gpio, UInt32 edge, Action<UInt32, UInt32, UInt32, object> f)
  1873. { return intCallback(user_gpio, edge, f, null, 0); }
  1874. public Callback callback_ex(UInt32 user_gpio, UInt32 edge, Action<UInt32, UInt32, UInt32, object> f, object user)
  1875. { return intCallback(user_gpio, edge, f, user, 1); }
  1876. public int callback_cancel(Callback callback)
  1877. {
  1878. if (gCallBackList.Contains(callback))
  1879. {
  1880. gCallBackList.Remove(callback);
  1881. findNotifyBits();
  1882. return 0;
  1883. }
  1884. return (int)EError.pigif_callback_not_found;
  1885. }
  1886. int wait_for_edge(int pi, UInt32 user_gpio, UInt32 edge, double timeout)
  1887. {
  1888. int triggered = 0;
  1889. double due;
  1890. if (timeout <= 0.0) return 0;
  1891. due = time_time() + timeout;
  1892. var id = callback(user_gpio, edge, (gpio, level, tick, user) =>
  1893. {
  1894. triggered = 1;
  1895. });
  1896. while (triggered == 0 && (time_time() < due)) time_sleep(0.05);
  1897. callback_cancel(id);
  1898. return triggered;
  1899. }
  1900. // Do not implement
  1901. // event_callback(),
  1902. // event_callback_ex(),
  1903. // event_callback_cancel() and
  1904. // wait_for_event().
  1905. int event_trigger(UInt32 evt)
  1906. { return pigpio_command(PI_CMD_EVM, (int)evt, 0); }
  1907. #endregion
  1908. #region # private method
  1909. private byte[] UInt32ArrayToBytes(UInt32[] array)
  1910. {
  1911. int numBytes = 4;
  1912. byte[] bytes = new byte[numBytes * array.Length];
  1913. for (int i = 0; i < array.Length; i++)
  1914. {
  1915. byte[] tempBytes = BitConverter.GetBytes(array[i]);
  1916. tempBytes.CopyTo(bytes, numBytes * i);
  1917. }
  1918. return bytes;
  1919. }
  1920. private byte[] UInt32ToBytes(UInt32 data)
  1921. {
  1922. return UInt32ArrayToBytes(new UInt32[] { data });
  1923. }
  1924. private UInt32[] BytesToUInt32Array(byte[] bytes)
  1925. {
  1926. int numBytes = 4;
  1927. UInt32[] array = new UInt32[bytes.Length / numBytes];
  1928. byte[] dataBytes = new byte[numBytes];
  1929. for (int i = 0; i < array.Length; i++)
  1930. {
  1931. for (int b = 0; b < numBytes; b++)
  1932. {
  1933. dataBytes[b] = bytes[numBytes * i + b];
  1934. }
  1935. array[i] = BitConverter.ToUInt32(dataBytes, 0);
  1936. }
  1937. return array;
  1938. }
  1939. private int pigpio_command(int command, int p1, int p2)
  1940. {
  1941. if (CanWrite == false || CanRead == false)
  1942. {
  1943. return (int)EError.pigif_unconnected_pi;
  1944. }
  1945. UInt32[] cmd = new UInt32[4];
  1946. cmd[0] = (UInt32)command;
  1947. cmd[1] = (UInt32)p1;
  1948. cmd[2] = (UInt32)p2;
  1949. cmd[3] = 0;
  1950. // UInt32[] -> byte[]
  1951. byte[] bytes = UInt32ArrayToBytes(cmd);
  1952. lock (LockObject)
  1953. {
  1954. try
  1955. {
  1956. this.TcpConnection.Stream.Write(bytes, 0, bytes.Length);
  1957. }
  1958. catch (Exception)
  1959. {
  1960. return (int)EError.pigif_bad_send;
  1961. }
  1962. try
  1963. {
  1964. if (this.TcpConnection.Stream.Read(bytes, 0, bytes.Length) != bytes.Length)
  1965. {
  1966. return (int)EError.pigif_bad_recv;
  1967. }
  1968. }
  1969. catch (Exception)
  1970. {
  1971. return (int)EError.pigif_bad_recv;
  1972. }
  1973. }
  1974. // byte[] -> UInt32[]
  1975. cmd = BytesToUInt32Array(bytes);
  1976. return (int)cmd[3];
  1977. }
  1978. private int pigpio_notify()
  1979. {
  1980. if (NotifyTcpConnection == null || NotifyTcpConnection.Stream == null ||
  1981. NotifyTcpConnection.Stream.CanWrite == false || NotifyTcpConnection.Stream.CanRead == false)
  1982. {
  1983. return (int)EError.pigif_unconnected_pi;
  1984. }
  1985. UInt32[] cmd = new UInt32[4];
  1986. cmd[0] = PI_CMD_NOIB;
  1987. cmd[1] = 0;
  1988. cmd[2] = 0;
  1989. cmd[3] = 0;
  1990. // UInt32[] -> byte[]
  1991. byte[] bytes = UInt32ArrayToBytes(cmd);
  1992. lock (LockObject)
  1993. {
  1994. try
  1995. {
  1996. NotifyTcpConnection.Stream.Write(bytes, 0, bytes.Length);
  1997. }
  1998. catch (Exception)
  1999. {
  2000. return (int)EError.pigif_bad_send;
  2001. }
  2002. try
  2003. {
  2004. if (NotifyTcpConnection.Stream.Read(bytes, 0, bytes.Length) != bytes.Length)
  2005. {
  2006. return (int)EError.pigif_bad_recv;
  2007. }
  2008. }
  2009. catch (Exception)
  2010. {
  2011. return (int)EError.pigif_bad_recv;
  2012. }
  2013. }
  2014. // byte[] -> UInt32[]
  2015. cmd = BytesToUInt32Array(bytes);
  2016. return (int)cmd[3];
  2017. }
  2018. private int pigpio_command_ext(int command, int p1, int p2, GpioExtent[] exts)
  2019. {
  2020. if (CanWrite == false || CanRead == false)
  2021. {
  2022. return (int)EError.pigif_unconnected_pi;
  2023. }
  2024. int extsBytes = 0;
  2025. foreach (var ext in exts)
  2026. {
  2027. extsBytes += ext.Contents.Length;
  2028. }
  2029. UInt32[] cmd = new UInt32[4];
  2030. cmd[0] = (UInt32)command;
  2031. cmd[1] = (UInt32)p1;
  2032. cmd[2] = (UInt32)p2;
  2033. cmd[3] = (UInt32)extsBytes;
  2034. // UInt32[] -> byte[]
  2035. byte[] cmdBytes = UInt32ArrayToBytes(cmd);
  2036. byte[] bytes = new byte[cmdBytes.Length + extsBytes];
  2037. int index = 0;
  2038. cmdBytes.CopyTo(bytes, index); index += cmdBytes.Length;
  2039. foreach (var ext in exts)
  2040. {
  2041. ext.Contents.CopyTo(bytes, index); index += ext.Contents.Length;
  2042. }
  2043. lock (LockObject)
  2044. {
  2045. try
  2046. {
  2047. this.TcpConnection.Stream.Write(bytes, 0, bytes.Length);
  2048. }
  2049. catch (Exception)
  2050. {
  2051. return (int)EError.pigif_bad_send;
  2052. }
  2053. try
  2054. {
  2055. if (this.TcpConnection.Stream.Read(cmdBytes, 0, cmdBytes.Length) != cmdBytes.Length)
  2056. {
  2057. return (int)EError.pigif_bad_recv;
  2058. }
  2059. }
  2060. catch (Exception)
  2061. {
  2062. return (int)EError.pigif_bad_recv;
  2063. }
  2064. }
  2065. // byte[] -> UInt32[]
  2066. cmd = BytesToUInt32Array(cmdBytes);
  2067. return (int)cmd[3];
  2068. }
  2069. private void dispatch_notification(GpioReport r)
  2070. {
  2071. UInt32 changed;
  2072. int l, g;
  2073. //Console.WriteLine("s={0:X4} f={1:X4} t={2} l={3:X8}",
  2074. // r.seqno, r.flags, r.tick, r.level);
  2075. if (r.flags == 0)
  2076. {
  2077. changed = (r.level ^ gLastLevel) & gNotifyBits;
  2078. gLastLevel = r.level;
  2079. foreach (var p in gCallBackList)
  2080. {
  2081. if ((changed & (1 << (p.gpio))) != 0)
  2082. {
  2083. if (((r.level) & (1 << (p.gpio))) != 0) l = 1; else l = 0;
  2084. if (((p.edge) ^ l) != 0)
  2085. {
  2086. if (p.ex != 0) p.f((UInt32)p.gpio, (UInt32)l, r.tick, p.user);
  2087. else p.f((UInt32)p.gpio, (UInt32)l, r.tick, null);
  2088. }
  2089. }
  2090. }
  2091. }
  2092. else
  2093. {
  2094. if (((r.flags) & PI_NTFY_FLAGS_WDOG) != 0)
  2095. {
  2096. g = (r.flags) & 31;
  2097. foreach (var p in gCallBackList)
  2098. {
  2099. if ((p.gpio) == g)
  2100. {
  2101. if (p.ex != 0) p.f((UInt32)g, PI_TIMEOUT, r.tick, p.user);
  2102. else p.f((UInt32)g, PI_TIMEOUT, r.tick, null);
  2103. }
  2104. }
  2105. }
  2106. else if (((r.flags) & PI_NTFY_FLAGS_EVENT) != 0)
  2107. {
  2108. g = (r.flags) & 31;
  2109. foreach (var ep in geCallBackList)
  2110. {
  2111. if ((ep.evt) == g)
  2112. {
  2113. if (ep.ex != 0) ep.f((UInt32)g, r.tick, ep.user);
  2114. else ep.f((UInt32)g, r.tick, null);
  2115. }
  2116. }
  2117. }
  2118. }
  2119. }
  2120. private void NotifyThread(CancellationToken ct)
  2121. {
  2122. byte[] bytes = new byte[12 * PI_MAX_REPORTS_PER_READ];
  2123. int received = 0;
  2124. while (ct.IsCancellationRequested == false)
  2125. {
  2126. if (NotifyTcpConnection == null || NotifyTcpConnection.Stream == null || NotifyTcpConnection.Stream.CanRead == false)
  2127. break;
  2128. try
  2129. {
  2130. while (received < 12)
  2131. {
  2132. received += NotifyTcpConnection.Stream.Read(bytes, received, bytes.Length - received);
  2133. }
  2134. }
  2135. catch (IOException)
  2136. {
  2137. break;
  2138. }
  2139. int p = 0;
  2140. while (p + 12 <= received)
  2141. {
  2142. var report = new GpioReport()
  2143. {
  2144. seqno = BitConverter.ToUInt16(new byte[] { bytes[p + 0], bytes[p + 1] }, 0),
  2145. flags = BitConverter.ToUInt16(new byte[] { bytes[p + 2], bytes[p + 3] }, 0),
  2146. tick = BitConverter.ToUInt32(new byte[] { bytes[p + 4], bytes[p + 5], bytes[p + 6], bytes[p + 7] }, 0),
  2147. level = BitConverter.ToUInt32(new byte[] { bytes[p + 8], bytes[p + 9], bytes[p + 10], bytes[p + 11] }, 0)
  2148. };
  2149. dispatch_notification(report);
  2150. p += 12;
  2151. }
  2152. for (int i = p; i < received; i++)
  2153. {
  2154. bytes[i - p] = bytes[i];
  2155. }
  2156. received -= p;
  2157. }
  2158. }
  2159. private void findNotifyBits()
  2160. {
  2161. UInt32 bits = 0;
  2162. foreach (var callback in gCallBackList)
  2163. {
  2164. bits |= (1U << (callback.gpio));
  2165. }
  2166. if (bits != gNotifyBits)
  2167. {
  2168. gNotifyBits = bits;
  2169. pigpio_command(PI_CMD_NB, gPigHandle, (int)gNotifyBits);
  2170. }
  2171. }
  2172. private Callback intCallback(UInt32 user_gpio, UInt32 edge, Action<UInt32, UInt32, UInt32, object> f, object user, int ex)
  2173. {
  2174. if ((user_gpio >= 0) && (user_gpio < 32) && (edge >= 0) && (edge <= 2) && f != null)
  2175. {
  2176. /* prevent duplicates */
  2177. if (gCallBackList.Count(p => p.gpio == user_gpio && p.edge == edge && p.f == f) != 0)
  2178. {
  2179. return null;
  2180. }
  2181. var callback = new Callback()
  2182. {
  2183. gpio = (int)user_gpio,
  2184. edge = (int)edge,
  2185. f = f,
  2186. user = user,
  2187. ex = ex
  2188. };
  2189. gCallBackList.Add(callback);
  2190. findNotifyBits();
  2191. return callback;
  2192. }
  2193. return null;
  2194. }
  2195. private int recvMax(byte[] buf, int sent)
  2196. {
  2197. /*
  2198. Copy at most bufSize bytes from the receieved message to
  2199. buf. Discard the rest of the message.
  2200. */
  2201. byte[] scratch = new byte[4096];
  2202. int remaining, fetch, count;
  2203. if (sent < buf.Length) count = sent; else count = buf.Length;
  2204. if (count > 0)
  2205. {
  2206. int received = 0;
  2207. while (received < count)
  2208. {
  2209. received += this.TcpConnection.Stream.Read(buf, received, count - received);
  2210. }
  2211. }
  2212. remaining = sent - count;
  2213. while (remaining > 0)
  2214. {
  2215. fetch = remaining;
  2216. if (fetch > scratch.Length) fetch = scratch.Length;
  2217. remaining -= this.TcpConnection.Stream.Read(scratch, 0, fetch);
  2218. }
  2219. return count;
  2220. }
  2221. #endregion
  2222. }
  2223. }