PageRenderTime 52ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/MSP-EXP430FR5969/MSP-EXP430FR5969_RC5_to_I2C_SoftMM.4th

https://gitlab.com/Jean-Michel/FastForthForMSP430fr5xxx
Forth | 501 lines | 468 code | 33 blank | 0 comment | 15 complexity | 3d5fed7bee542c1ee37ca04382667947 MD5 | raw file
Possible License(s): GPL-3.0
  1. ; --------------------------------------
  2. ; MSP-EXP430FR5969_RC5_to_I2C_SoftMM.4th
  3. ; --------------------------------------
  4. STOP ; to stop any interrupt in progress
  5. WIPE ;
  6. NOECHO ; comment to debug
  7. ; FORTH source file
  8. ; Copyright (C) <2016> <J.M. THOORENS>
  9. ;
  10. ; This program is free software: you can redistribute it and/or modify
  11. ; it under the terms of the GNU General Public License as published by
  12. ; the Free Software Foundation, either version 3 of the License, or
  13. ; (at your option) any later version.
  14. ;
  15. ; This program is distributed in the hope that it will be useful,
  16. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ; GNU General Public License for more details.
  19. ;
  20. ; You should have received a copy of the GNU General Public License
  21. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. ; ========================================
  23. ; DEMO : I2C_MULTI MASTER WRITE & I2C_SLAVE READ
  24. ; I2C_MULTI_MASTER PART
  25. ; ========================================
  26. ; load this EXP430FR5969_RC5_to_I2C_Soft_Master.4th file on the first LAUNCHPAD
  27. ; load EXP430FR5969_I2C_Slave_to_PJ_LCD_2x20 MSP-.4th on the other LAUNCHPAD
  28. ; target : MSP-EXP430fr5969 LAUNCHPAD @ 8MHz
  29. ; ===================================================================================
  30. ; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
  31. ; ===================================================================================
  32. ; -----------------------------------------------
  33. ; MSP - LAUNCHPAD <--> OUTPUT WORLD
  34. ; -----------------------------------------------
  35. ; P4.6 - J6 - LED1 red
  36. ; P1.0 - LED2 green
  37. ; P4.5 - Switch S1 \\\ <--- LCD contrast + (finger :-)
  38. ; P1.1 - Switch S2 \\\ <--- LCD contrast - (finger ;-)
  39. ; GND - J1.2 \\\ <-------+---0V0----------> 1 LCD_Vss
  40. ; VCC - J1.3 \\\ >------ | --3V6-----+----> 2 LCD_Vdd
  41. ; \\\ | |
  42. ; \\\ |___ 470n ---
  43. ; \\\ ^ | ---
  44. ; \\\ / \ BAT54 |
  45. ; \\\ --- |
  46. ; \\\ 100n | 2k2 |
  47. ; P2.2 - J4.7 UCB0 CLK TB0.2 \\\ >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
  48. ; P3.4 - J4.8 \\\ -------------------------> 4 LCD_RS
  49. ; P3.5 - J4.9 \\\ -------------------------> 5 LCD_R/W
  50. ; P3.6 - J4.10 \\\ -------------------------> 6 LCD_EN0
  51. ; PJ.0 - J3.1 \\\ <------------------------> 11 LCD_DB4
  52. ; PJ.1 - J3.3 \\\ <------------------------> 12 LCD_DB5
  53. ; PJ.2 - J3.5 \\\ <------------------------> 13 LCD_DB5
  54. ; PJ.3 - J3.7 \\\ <------------------------> 14 LCD_DB7
  55. ; P2.0 - J13.8 UCA0 TXD ---> RX UARTtoUSB bridge
  56. ; P2.1 - J13.10 UCA0 RXD <--- TX UARTtoUSB bridge
  57. ; P4.1 - J13.14 RTS ---> CTS UARTtoUSB bridge (optional hardware control flow)
  58. ; VCC - J13.16 <--- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
  59. ; GND - J13.20 <--> GND (optional supply from UARTtoUSB bridge)
  60. ; VCC - J11.1 ---> VCC SD_CardAdapter
  61. ; GND - J12.3 <--> GND SD_CardAdapter
  62. ; P2.4 - J4.6 UCA1 CLK ---> CLK SD_CardAdapter (SCK)
  63. ; P4.3 - J4.5 ---> CS SD_CardAdapter (Card Select)
  64. ; P2.5 - J4.4 UCA1 TXD/SIMO ---> SDI SD_CardAdapter (MOSI)
  65. ; P2.6 - J4.3 UCA1 RXD/SOMI <--- SDO SD_CardAdapter (MISO)
  66. ; P4.2 - J4.2 <--- CD SD_CardAdapter (Card Detect)
  67. ; P4.0 - J3.10 <--- OUT IR_Receiver (1 TSOP32236)
  68. ; VCC - J3.2 ---> VCC IR_Receiver (2 TSOP32236)
  69. ; GND - J3.9 <--> GND IR_Receiver (3 TSOP32236)
  70. ; PJ.4 - LFXI 32768Hz quartz
  71. ; PJ.5 - LFXO 32768Hz quartz
  72. ; PJ.6 - HFXI
  73. ; PJ.7 - HFXO
  74. ; P1.2 - J5.19 Soft I2C_Master <--> SDA <----------------------------------------------------> P1.6 other LAUNCHPAD
  75. ; P1.3 - J5.11 Soft I2C_Master ---> SCL -----------------------------------------------------> P1.7 other LAUNCHPAD
  76. ; P1.4 - J5.12 TB0.1 <--> free
  77. ; P1.5 - J5.13 UCA0 CLK TB0.2 <--> free
  78. ; P1.6 - J5.15 UCB0 SDA/SIMO <--> SDA
  79. ; P1.7 - J5.14 UCB0 SCL/SOMI <--- SCL
  80. ; P3.0 - J5.7 <--> free
  81. ; P2.3 - NC
  82. ; P2.7 - NC
  83. ; P3.1 - NC
  84. ; P3.2 - NC
  85. ; P3.3 - NC
  86. ; P3.7 - NC
  87. ; P4.4 - NC
  88. ; P4.7 - NC
  89. ; HERE ; general minidump, part 1
  90. ; P1.3 MSCL
  91. ; P1.2 MSDA
  92. ; ==========================================================;
  93. ; I2C Standard mode (100kHz) ;
  94. ; ==========================================================;
  95. VARIABLE I2CSLV_ADR ; contents slave address & R/W
  96. VARIABLE I2CM_OUT ; buffer output, lentgh,DATA (low,HIGH)
  97. VARIABLE I2CM_IN ; buffer input, lentgh,DATA (low,HIGH)
  98. 2 ALLOT
  99. ; ------------------------------;
  100. CODE MM_TI2C ; 4 init first once !!! 3(IP+3)~
  101. ; ------------------------------;
  102. BEGIN ;
  103. SUB #1,IP ; 1
  104. 0= UNTIL ; 2
  105. MOV #4,IP ; 1 preset I2C tHIGH=4us complement @ 8MHz ==> 12~(M_SCL delay) + 21~ = 33~
  106. ; MOV #13,IP ; 2 preset I2C tHIGH=4us complement @ 16MHz ==> 12~(M_SCL delay) + 51~ = 63~
  107. ; MOV #25,IP ; 2 preset I2C tHIGH=4us complement @ 24MHz ==> 12~(M_SCL delay) + 84~ = 96~
  108. MOV @RSP+,PC ; 4 ret
  109. ENDCODE ;
  110. ; ------------------------------;
  111. ; ------------------------------; _
  112. CODE MM_SCL ; SCL _| |_
  113. ; ------------------------------; _
  114. BIC.B #0x08,&0x204 ; 4 l _^ P1DIR.3 release SCL (high)
  115. BEGIN ;
  116. BIT.B #0x08,&0x200 ; 3 h test if SCL is released
  117. 0<> UNTIL ; 2 h
  118. CALL #MM_TI2C ; wait tHIGH (4us)
  119. BIT.B #0x04,&0x200 ; 3 h _ P1IN.2 : get SDA
  120. BIS.B #0x08,&0x204 ; 4 h v_ P1DIR.3as output : force SCL low
  121. MOV @RSP+,PC ; 4 l return : C = SDA pin, Z = /SDA pin
  122. ENDCODE ; SDA is released by Slave
  123. ; ------------------------------;
  124. ; P4.0 - J3.10 <--- OUT IR_Receiver (1 TSOP32236)
  125. ; VCC - J3.2 ---> VCC IR_Receiver (2 TSOP32236)
  126. ; GND - J3.9 <--> GND IR_Receiver (3 TSOP32236)
  127. ; ------------------------------;
  128. ; IR_RC5 driver ;
  129. ; ******************************;
  130. CODE IR_RC5 ; wake up on P4.0 change interrupt
  131. ; ******************************;
  132. BIC #0xF8,0(RSP) ; CPU on, GIE off in oldSR
  133. ; ------------------------------;
  134. ; in : SR(9)=old Toggle bit memory
  135. ; SMclock = 8 MHz or 16 MHz
  136. ; use : U,V,W,X,Y, TA0 timer, TA0R register
  137. ; out : U = 0 x T A4 A3 A2 A1 A0| 0 C6 C5 C4 C3 C2 C1 C0
  138. ; SR(9)=new Toggle bit memory
  139. ; ------------------------------;
  140. ; RC5_FirstStartBitHalfCycle: ;
  141. ; ------------------------------;
  142. MOV #0,&0x0360 ; predivide by 1 in TA0EX0 register ( 8 MHZ), reset value
  143. ; MOV #1,&0x0360 ; predivide by 2 in TA0EX0 register (16 MHZ)
  144. ; MOV #2,&0x0360 ; predivide by 3 in TA0EX0 register (24 MHZ)
  145. MOV #1778,X ; RC5_Period in us
  146. MOV #14,W ; count of loop
  147. BEGIN ;
  148. ; ------------------------------;
  149. ; RC5_TopSynchro: ; <--- loop back ---+ with readjusted RC5_Period
  150. ; ------------------------------; | here, we are just after 1/2 RC5_cycle
  151. MOV #0b1011100100,&0x0340 ; (re)start timer_A | SMCLK_pre/2 /8 : 2us time interval,free running,clear TA0_IFG and TA0R
  152. ; RC5_Compute_3_4Period: ; |
  153. RRUM #1,X ; X=1/2 cycle |
  154. MOV X,Y ; Y=1/2 ^
  155. RRUM #1,Y ; Y=1/4
  156. ADD X,Y ; Y=3/4
  157. ; RC5_Wait_1_4: ; wait 3/4 cycle after 1/2 cycle to sample RC5_Input at 1/4 cycle
  158. BEGIN CMP Y,&0x0350 ; CMP &TA0R with 3/4 cycle value
  159. = UNTIL ;
  160. ; ------------------------------;
  161. ; RC5_Sample: ; at 1/4 cycle, we can sample RC5_input, ST2/C6 bit first
  162. ; ------------------------------;
  163. BIT.B #0x01,&0x0221 ; C_flag = P4.0 = IR bit
  164. ADDC V,V ; C_flag <-- V(15):V(0) <-- C_flag
  165. MOV.B &0x0221,&0x0239 ; preset IES_4.0 state for next IFG
  166. BIC.B #0x01,&0x023D ; clear P4.0_IFG after full cycle pin change
  167. SUB #1,W ; decrement count loop
  168. ; count = 13 ==> V = x x x x x x x x |x x x x x x x /C6
  169. ; count = 0 ==> V = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
  170. 0<> WHILE ; ----> out of loop ----+
  171. ; RC5_compute_2_4_OverFlow: ; |
  172. ADD X,Y ; | out of bound = 5/4 period
  173. ; RC5_WaitHalfCycleP1.2_IFG: ; |
  174. BEGIN ; |
  175. CMP Y,&0x0350 ; | TA0R = 5/4 cycle test
  176. >= IF ; | if cycle time out of bound
  177. MOV #4,&0x0340 ; | stop timer_A and clear TA0R
  178. RETI ; | then quit to do nothing
  179. THEN ; |
  180. ; ------------------------------; |
  181. BIT.B #0x01,&0x023D ; ^ | test P4.0_IFG
  182. <> UNTIL ; | |
  183. MOV &0x0350,X ; | | get new RC5_period value
  184. REPEAT ; ----> loop back --+ |
  185. ; ------------------------------; |
  186. ; RC5_SampleEndOf: ; <---------------------+
  187. ; ------------------------------;
  188. MOV #4,&0x0340 ; stop timer_A
  189. RLAM #1,V ; V = x /C6 Tg A4 A3 A2 A1 A0|C5 C4 C3 C2 C1 C0 1 0
  190. ; ------------------------------;
  191. ; ------------------------------;
  192. ; Only New_RC5_Command ADD_ON ; use SR(9) bit as toggle bit
  193. ; ------------------------------;
  194. MOV @RSP,X ; retiSR(9) = old RC5 toggle bit
  195. RLAM #4,X ; retiSR(9) --> X(13)
  196. XOR V,X ; (new XOR old)(13) Toggle bit
  197. BIT #0x2000,X ; X(13) = New_RC5_command
  198. 0= IF ;
  199. RETI ; case of repeated RC5_command : RETI without SR(9) change
  200. THEN ;
  201. XOR #0x0200,0(RSP) ; change Toggle bit memory SR(9)
  202. ; ------------------------------;
  203. ; ------------------------------;
  204. ; RC5_ComputeNewRC5word ;
  205. ; ------------------------------;
  206. MOV.B V,U ; U= 0 0 0 0 0 0 0 0 C5 C4 C3 C2 C1 C0 0 0
  207. RRUM #2,U ; U= 0 0 0 0 0 0 0 0 0 0 C5 C4 C3 C2 C1 C0
  208. ; AND #0x7F00,V ; V= 0 /C6 Tg A4 A3 A2 A1 A0 0 0 0 0 0 0 0 0
  209. ; ADD V,U ; U= 0 /C6 Tg A4 A3 A2 A1 A0 0 0 C5 C4 C3 C2 C1 C0
  210. ; ------------------------------;
  211. ; RC5_ComputeC6bit ;
  212. ; ------------------------------;
  213. BIT #0x4000,V ; test /C6
  214. 0= IF BIS.B #0x40,U ; set C6 bit
  215. THEN ;
  216. ; ------------------------------;
  217. ; RC5_CommandByteIsDone: ; U= 0 0 0 0 0 0 0 0 0 C6 C5 C4 C3 C2 C1 C0
  218. ; ------------------------------;
  219. ; Prepare I2C_MASTER ;
  220. ; ------------------------------;
  221. SWPB U ; 1 high byte = data
  222. ADD #1,U ; 1 low byte = count
  223. MOV U,&I2CM_OUT ; 3
  224. ; ------------------------------;
  225. ; SUB #2,PSP
  226. ; MOV TOS,0(PSP)
  227. ; MOV.B U,TOS
  228. ; ASM>FORTH
  229. ; cr ." 0x" HEX 2 U.R
  230. ; FORTH>ASM
  231. ; ==============================;
  232. ; CODE I2C_MM ; soft I2C_MultiMaster driver
  233. ; ==============================;
  234. ; ; in : I2CSLV_ADR & (R/W)
  235. ; ; : I2CM_IN/I2CM_OUT as requested by I2C_SLA_ADR(0)
  236. ; ; : I2CM_IN/I2CM_OUT(0) = count of datas to be TX/RX
  237. ; ; : I2CM_IN/I2CM_OUT(0) = 0 ==> send only I2C address
  238. ; ; used: U BUF_PTR
  239. ; ; V count of I2C datas exchanged
  240. ; ; W count of bits
  241. ; ; X data
  242. ; ; Y BUF_ORG
  243. ; ; out : I2CSLV_ADR & (R/W) unchanged
  244. ; ; Y = BUF_ORG
  245. ; ; U = BUF_PTR pointing on first data not exchanged
  246. ; ; V = count of TX/RX datas exchanged (if ack on addr)
  247. ; ; I2CM_IN/OUT(0) = count of data not exchanged (normally = 0)
  248. ; ; I2CM_IN/OUT(0) = -1 <==> Nack on address
  249. ; ------------------------------;
  250. ; I2CMM_Stop_UCBxI2CSlave ; if SDA SCL of I2C_MultiMaster are hard wired onto SDA SCL of I2C_Slave under interrupt...
  251. ; ------------------------------;
  252. ; BIS #1,&0x640 ; set eUSCI_B0 in reset state, reset StartCond int in UCB0IFG
  253. ; ------------------------------;
  254. ; I2C_MR_DC_listenBeforeStart: ; test if SCL & SDA lines are idle (high)
  255. ; ------------------------------;
  256. BEGIN ; case of detection collision during send address
  257. BIC.B #0x0C,&0x204 ; release SCL & SDA pins
  258. MOV #7,V ; I2C_MR_DC_Wait_Start_Loop = 12 ľs @ 8 MHz
  259. ; MOV #14,V ; I2C_MR_DC_Wait_Start_Loop = 12 ľs @ 16 MHz
  260. ; MOV #21,V ; I2C_MR_DC_Wait_Start_Loop = 12 ľs @ 24 MHz
  261. BEGIN ; 13~loop
  262. BEGIN ;
  263. BEGIN ;
  264. BIT.B #0x08,&0x200 ; 3 P1IN.3 SCL high ?
  265. <> UNTIL ; 2
  266. BIT.B #0x04,&0x200 ; 3 P1IN.2 SDA high ?
  267. <> UNTIL ; 2
  268. SUB #1,V ; 1
  269. 0= UNTIL ; 2 here the I2C bus is idle
  270. ; --------------------------;
  271. ; I2C_Master_Start_Cond: ; here, SDA and SCL are in idle state
  272. ; --------------------------; _
  273. BIS.B #0x04,&0x204 ; 3 h |_ force P1DIR.2 (SDA) as output (low)
  274. MOV.B &I2CSLV_ADR,X ; 3 h @ in X
  275. MOV #I2CM_OUT,U ; 2 h buffer out by default
  276. BIT.B #1,X ; 1 h test I2C R/w flag
  277. 0<> IF MOV #I2CM_IN,U ; 5 h buffer in
  278. THEN ;
  279. MOV U,Y ; 1 h U=BUF_ptr Y=BUF_org
  280. ; --------------------------;
  281. ; Init MM_TI2C first ! ; IP must be initialized
  282. ; --------------------------;
  283. MOV #2,IP ; 1 h tHD:STA=4us, 15~ complement @ 8MHz
  284. ; MOV #13,IP ; 2 h tHD:STA=4us, 48~ complement @ 16MHz
  285. ; MOV #23,IP ; 2 h tHD:STA=4us, 78~ complement @ 24MHz
  286. ; --------------------------;
  287. CALL #MM_TI2C ; _ wait tHD;STA
  288. BIS.B #0x08,&0x204 ; 3 h |_ P1DIR.3 force SCL output (low)
  289. ; --------------------------;
  290. ; I2C_Master_Start_EndOf: ;
  291. ; --------------------------;
  292. ; I2C_Master_Send_address ; SCL is held low by slave
  293. ; --------------------------;
  294. MOV #8,W ; 1 l prepare 8 bit Master writing
  295. BIC #0x0400,SR ; 2 reset detection collision flag
  296. BEGIN ;
  297. ADD.B X,X ; 1 l shift one left
  298. U>= IF ; 2 l carry set ?
  299. BIC.B #0x04,&0x204 ; 5 l yes : P1DIR.2 as input ==> SDA high because pull up resistor
  300. ELSE ; 2 l
  301. BIS.B #0x04,&0x204 ; 5 l no : P1DIR.2 as output ==> SDA low
  302. THEN ; l
  303. ; ADD #0,IP ; 2 l tLOW=4,7us, 15~ complement @ 8MHz
  304. ; ADD #3,IP ; 2 l tLOW=4,7us, 54~ complement @ 16MHz
  305. ; ADD #4,IP ; 2 l tLOW=4,7us, 90~ complement @ 24MHz
  306. CALL #MM_TI2C ; l _
  307. BIC.B #0x08,&0x204 ; 5 l _^ P1DIR.3 release SCL (high)
  308. BEGIN
  309. BIT.B #0x08,&0x200 ; 4 h test if SCL is released
  310. 0<> UNTIL ; 2 h
  311. CALL #MM_TI2C ; h
  312. MOV.B &0x200,V ; 3 h _ V = IN1
  313. BIS.B #0x08,&0x204 ; 5 h v_ P1DIR.3 as output : force SCL low
  314. ; ----------------------; l
  315. ; collision detection ;
  316. ; ----------------------;
  317. XOR.B &0x204,V ; 3 l
  318. BIT.B #0x04,V ; 2 l (DIR1.2 xor IN1.2) = 1 if no collision
  319. 0= IF ; 2 l collision detected
  320. BIS #0x0400,SR ; 2 set collision detection SR(10) flag
  321. MOV #1,W ; 1 to abort count of bit loop
  322. THEN ;
  323. SUB #1,W ; 1 l dec count of bits
  324. 0= UNTIL ; 2 l
  325. BIT #0x0400,SR ; 2 l collision ?
  326. 0= UNTIL ; 2 loop if collision during send address
  327. BIC.B #0x04,&0x204 ; 5 l P1DIR.2 as input : release SDA high
  328. ; ------------------------------;
  329. MOV.B @U+,V ; 2 h V = count of datas
  330. ADD #1,V ; 1 l to add address in count
  331. BEGIN ;
  332. ; SUB #1,IP ; 2 l +15~ complement @ 8MHz
  333. ; SUB #5,IP ; 2 l +45~ complement @ 16MHz
  334. ; SUB #10,IP ; 2 l +78~ complement @ 24MHz
  335. CALL #MM_TI2C ; wait still tLOW=4,7us
  336. ; --------------------------; l
  337. ; Master TX/RX ACK/NACK ;
  338. ; --------------------------; l _
  339. CALL #MM_SCL ; SCL _| |_ C flag = NACK
  340. ; --------------------------; 4 l
  341. ; I2C_Master_Loop_Data ;
  342. ; --------------------------;
  343. 0<> IF BIS #2,SR ; l if Nack (TX), force Z+1 ==> StopCond
  344. ELSE SUB.B #1,V ; else dec count
  345. THEN ; l
  346. ; --------------------------;
  347. ; I2C_Master_CheckCountDown ; count=0 or Nack received
  348. ; --------------------------;
  349. 0= IF ; count reached or Nack
  350. ; ----------------------;
  351. ; I2C_Master_StopCond ;
  352. ; ----------------------; _
  353. BIS.B #0x04,&0x204 ; 4 l v_ P1DIR.2 as output ==> SDA low
  354. SUB.B V,0(Y) ; 4 l _ refresh buffer length
  355. BIC.B #0x08,&0x204 ; 4 l _^ P1DIR.3 release SCL (high)
  356. BEGIN ;
  357. BIT.B #0x08,&0x200 ; 3 h SCL released ?
  358. 0<> UNTIL ; 2 h
  359. CALL #MM_TI2C ; h _ wait tSU:STO
  360. BIC.B #0x04,&0x204 ; _| P1DIR.2 as input ==> SDA high with the hard wired pull up resistor
  361. ; ----------------------;
  362. ; I2C_Master_Endof ;
  363. ; ----------------------;
  364. ; Restart I2C_Slave_Int ; if any
  365. ; ----------------------;
  366. ; BIC #1,&0x640 ; restart eUSCI_B
  367. ; MOV #4,&0x66A ; reenable StartCond interrupt
  368. ; ----------------------;
  369. RETI ; ====> unique return
  370. ; ----------------------;
  371. THEN ;
  372. ; --------------------------;
  373. MOV.B #8,W ; 1 l prepare 8 bits transaction
  374. BIT #1,&I2CSLV_ADR ; 3 l I2C_Master Read/write bit test
  375. 0= IF ; 2 l write flag test
  376. ; ----------------------;
  377. ; I2C write ;
  378. ; ----------------------;
  379. MOV.B @U+,X ; 2 l next byte to transmit
  380. ; ADD #0,IP ; 2 l tLOW=4,7us, 15~ complement @ 8MHz
  381. ; SUB #3,IP ; 2 l tLOW=4,7us, 36~ complement @ 16MHz
  382. ; SUB #2,IP ; 2 l tLOW=4,7us, 72~ complement @ 24MHz
  383. ; ----------------------;
  384. ; CODE I2C_MTX ; MASTER TX
  385. ; ----------------------; 4 l
  386. BEGIN ;
  387. ADD.B X,X ; 1 l shift one left
  388. U>= IF ; 2 l carry set ?
  389. BIC.B #0x04,&0x204 ; 4 l yes : P1DIR.2 as input ==> SDA high because pull up resistor
  390. ELSE ; 2 l
  391. BIS.B #0x04,&0x204 ; 4 l no : P1DIR.2 as output ==> SDA low
  392. THEN ; l
  393. CALL #MM_TI2C ; l wait still tLOW with predefined complement
  394. ; --------------------; 7 l _
  395. CALL #MM_SCL ; SCL _| |_
  396. ; --------------------; 4 l
  397. SUB #1,W ; 1 l count of bits
  398. 0= UNTIL ; 2 l
  399. BIC.B #0x04,&0x204 ; 3 l P1DIR.2 as input : release SDA high
  400. ELSE ; l
  401. ; ----------------------;
  402. ; I2C read ;
  403. ; ======================;
  404. ; I2C_Master_RX: ; here, SDA is indetermined, SCL is strech low by master
  405. ; ======================;
  406. BEGIN ;
  407. BIC.B #0x04,&0x204 ; 4 l P1DIR.2 as input ==> SDA released high because pull up resistor
  408. ; ADD #0,IP ; 2 l tLOW=4,7us, 6~ complement @ 8MHz
  409. ; SUB #1,IP ; 2 l tLOW=4,7us, 42~ complement @ 16MHz
  410. ; ADD #1,IP ; 2 l tLOW=4,7us, 81~ complement @ 24MHz
  411. CALL #MM_TI2C ; wait still tLOW
  412. ; ------------------; 7 l _
  413. CALL #MM_SCL ; SCL _| |_
  414. ; ------------------; 4 l
  415. ADDC.B X,X ; 1 l C <-- X <--- C
  416. SUB #1,W ; 1 l count of bits
  417. 0= UNTIL ; 2 l
  418. MOV.B X,0(U) ; 3 l store byte @ BUF_PTR
  419. ADD #1,U ; 1 l
  420. ; ----------------------;
  421. ; I2C_MSendAckOrNack ; here, SDA is released by slave, SCL is strech low by master
  422. ; ----------------------;
  423. SUB.B #1,V ;
  424. 0<> IF ; 2
  425. BIS.B #0x04,&0x204 ; 4 l prepare send Ack if byte count <> 1
  426. THEN ;
  427. THEN ;
  428. AGAIN ; l
  429. ENDCODE ;
  430. ; ------------------------------;
  431. ; ------------------------------;
  432. CODE START ;
  433. ; ------------------------------;
  434. ; I2C_MASTER init part ;
  435. ; ------------------------------;
  436. MOV #0b0010100,&I2CSLV_ADR ; MSP-EXP430FR5969 slave address, not the tn2313_KPD12 one
  437. ; ------------------------------;
  438. ; init PORTB (P2:P1) (complement) default I/O are input with pullup resistors
  439. ; ------------------------------;
  440. BIC.B #0x0C,&0x206 ; P1REN.23 SDA, SCL internal pullup resistors disabled
  441. BIC.B #0x0C,&0x204 ; P1DIR.23 master SDA & SCL pins as input high
  442. BIC.B #0x0C,&0x202 ; P1OUT.23 preset SDA output low
  443. ; ------------------------------;
  444. ; init PORTB (P4:P3) (complement) default I/O are input with pullup resistors
  445. ; ------------------------------;
  446. BIC.B #0x01,&0x23D ; P4IFG.0 clear int flag for TSOP32236 (after IES select)
  447. BIS.B #0x01,&0x23B ; P4IE.0 enable interrupt for TSOP32236
  448. ; ------------------------------;
  449. ; init interrupt vectors ;
  450. ; ------------------------------;
  451. MOV #IR_RC5,&0xFFD0 ; init P4 vector interrupt
  452. ; ------------------------------;
  453. ASM>FORTH
  454. ." Type STOP to quit RC5_to_I2C_SoftMultiMaster"
  455. LIT RECURSE IS WARM \ ; insert this routine between COLD and WARM...
  456. (WARM) ; ; ...and continue with WARM
  457. CODE STOP
  458. BIC.B #0x01,&0x23B ; Clear P4IE.0 IR_RC5 interrupt from TSOP32236
  459. ASM>FORTH
  460. ['] (WARM) IS WARM \ ; reconnect WARM to (WARM)
  461. -1 ABORT"
  462. ; ; above, ABORT" followed by CRLF allows to compile an empty string...
  463. ; DUP HERE SWAP - DUMP ; general minidump, part 2
  464. FORGET MM_TI2C FORGET MM_SCL ; because not FORTH executable
  465. FORGET IR_RC5 ; because not FORTH executable
  466. ECHO
  467. RST_HERE
  468. START