PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/MSP-EXP430FR5969/MSP-EXP430FR5969_I2C_SoftMM_to_LCD_2x20.4th

https://gitlab.com/Jean-Michel/FastForthForMSP430fr5xxx
Forth | 719 lines | 662 code | 57 blank | 0 comment | 27 complexity | a8abd46b2c3d6ae70962ace60c3c1e1e MD5 | raw file
Possible License(s): GPL-3.0
  1. ; -------------------------------------------
  2. ; MSP-EXP430FR5969_I2C_SoftMM_to_LCD_2x20.4th
  3. ; -------------------------------------------
  4. STOP ; to stop any interrupt in progress
  5. WIPE ;
  6. NOECHO ; comment to debug
  7. ; FORTH source file
  8. ; Copyright (C) <2015> <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_SLAVE WRITE & I2C_MULTI_MASTER READ
  24. ; I2C_MULTI_MASTER PART
  25. ; ========================================
  26. ; load this MSP-EXP430FR5969_I2C_SoftMM_to_LCD_2x20.4th file on the first LAUNCHPAD
  27. ; load MSP-EXP430FR5969_RC5_to_I2C_Slave.4th on the other LAUNCHPAD
  28. ; target : MSP-EXP430fr5969 LAUNCHPAD
  29. ; ===================================================================================
  30. ; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
  31. ; ===================================================================================
  32. ; -----------------------------------------------
  33. ; MSP - MSP-EXP430fr5969 <--> 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 <--------------------------------------------------> SDA other LAUNCHPAD
  75. ; P1.3 - J5.11 Soft I2C_Master ---> SCL ---------------------------------------------------> SCL 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. ; ******************************;
  91. CODE INT_P1 ; PORT1 interrupt routine, warning : not FORTH executable !
  92. ; ******************************;
  93. BIC #0xF8,0(RSP) ; CPU on, GIE off in retSR
  94. ; ------------------------------;
  95. BIT.B #0x02,&0x200 ; test P1IN.1 = switch S2
  96. BIC.B #0x02,&0x21C ; P1IFG.1 clear
  97. 0= IF ; case of switch S2 pressed
  98. CMP #34,&0x3D6 ; TB0CCR2 ; maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
  99. U< IF
  100. ADD #1,&0x3D6 ; TB0CCR2 ; action for switch S2 (P1.1) : 78 mV / increment
  101. THEN
  102. THEN
  103. RETI ;
  104. ENDCODE
  105. ; ******************************;
  106. CODE INT_P4 ; PORT4 interrupt routine, warning : not FORTH executable !
  107. ; ******************************;
  108. BIC #0xF8,0(RSP) ; CPU on, GIE off in retSR
  109. ; ------------------------------;
  110. BIT.B #0x20,&0x220 ; test P4IN.5 = switch S1
  111. BIC.B #0x20,&0x23D ; P4IFG.5 clear
  112. 0= IF ; case of Switch S1 pressed
  113. CMP #7,&0x3D6 ; TB0CCR2 ; mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
  114. U>= IF ;
  115. SUB #1,&0x3D6 ; TB0CCR2 ; action for switch S1 (P4.5) : -78 mV / decrement
  116. THEN ;
  117. THEN ;
  118. RETI ;
  119. ENDCODE
  120. ; ------------------------------;
  121. CODE 20_us ; n -- n * 20 us
  122. ; ------------------------------;
  123. BEGIN ; 3 cycles loop + 6~
  124. ; MOV #5,W ; 3 MCLK = 1 MHz
  125. ; MOV #23,W ; 3 MCLK = 4 MHz
  126. MOV #51,W ; 3 MCLK = 8 MHz
  127. ; MOV #104,W ; 3 MCLK = 16 MHz
  128. ; MOV #158,W ; 3 MCLK = 24 MHz
  129. BEGIN ; 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
  130. SUB #1,W ; 1
  131. 0= UNTIL ; 2
  132. SUB #1,TOS ; 1
  133. 0= UNTIL ; 2
  134. MOV @PSP+,TOS ; 2
  135. MOV @IP+,PC ; 4
  136. ENDCODE
  137. ; ------------------------------;
  138. CODE TOP_LCD ; LCD Sample
  139. ; ------------------------------; if write : 0bxxxxWWWW --
  140. ; ; if read : -- 0b0000RRRR
  141. BIS.B #0x40,&0x222 ; P3OUT.6 LCD_EN 0-->1
  142. BIT.B #0x20,&0x220 ; P3IN.5 LCD_RW test
  143. 0= IF ; write LCD bits pattern
  144. AND #0x0F,TOS ;
  145. MOV.B TOS, &0x322 ; MOVE LCD_Data bits to PJ(0-3)
  146. BIC.B #0x40,&0x222 ; P3OUT.6 LCD_EN 1-->0 ==> strobe data
  147. MOV @PSP+,TOS ;
  148. MOV @IP+,PC
  149. THEN ; read LCD bits pattern
  150. SUB #2,PSP
  151. MOV TOS,0(PSP)
  152. BIC.B #0x40,&0x222 ; P3OUT.6 LCD_EN 1-->0 ==> strobe data
  153. MOV.B &0x320,TOS ; get LCD_Data from PJ(0-3)
  154. AND.B #0x0F,TOS
  155. MOV @IP+,PC
  156. ENDCODE
  157. ; ------------------------------;
  158. CODE LCD_W ; byte -- write byte
  159. ; ------------------------------;
  160. SUB #2,PSP ;
  161. MOV TOS,0(PSP) ; -- 0bxxxxLLLL 0bHHHHLLLL
  162. RRUM #4,TOS ; -- 0bxxxxLLLL 0bxxxxHHHH
  163. BIC.B #0x20,&0x222 ; P3OUT.5 LCD_RW=0
  164. BIS.B #0x0F,&0x324 ; PJDIR.(0-3) LCD_Data as output
  165. PUSH IP
  166. ASM>FORTH
  167. TOP_LCD 2 20_us \ write high nibble first
  168. TOP_LCD 2 20_us ;
  169. ; ------------------------------;
  170. CODE LCD_R ; -- byte read byte
  171. ; ------------------------------;
  172. BIC.B #0x0F,&0x324 ; PJ.(0-3) LCD_Data as intput
  173. BIS.B #0x20,&0x222 ; P3.5 LCD_RW=1
  174. PUSH IP
  175. ASM>FORTH
  176. TOP_LCD 2 20_us \ read high nibble first
  177. TOP_LCD 2 20_us
  178. FORTH>ASM ; -- 0b0000HHHH 0b0000LLLL
  179. MOV @RSP+,IP
  180. MOV @PSP+,W ; W = high nibble
  181. RLAM #4,W ; -- 0b0000LLLL W = 0bHHHH0000
  182. ADD.B W,TOS
  183. MOV @IP+,PC
  184. ENDCODE
  185. ; ------------------------------;
  186. CODE LCD_WrF ; func -- Write fonction
  187. ; ------------------------------;
  188. BIC.B #0x10,&0x222 ; P3OUT.4 LCD_RS=0
  189. JMP LCD_W
  190. ENDCODE
  191. ; ------------------------------;
  192. CODE LCD_RdS ; -- status Read Status
  193. ; ------------------------------;
  194. BIC.B #0x10,&0x222 ; P3OUT.4 LCD_RS=0
  195. JMP LCD_R
  196. ENDCODE
  197. ; ------------------------------;
  198. CODE LCD_WrC ; char -- Write char
  199. ; ------------------------------;
  200. BIS.B #0x10,&0x222 ; P3OUT.4 LCD_RS=1
  201. JMP LCD_W
  202. ENDCODE
  203. ; ------------------------------;
  204. CODE LCD_RdC ; -- char Read char
  205. ; ------------------------------;
  206. BIS.B #0x10,&0x222 ; P3OUT.4 LCD_RS=1
  207. JMP LCD_R
  208. ENDCODE
  209. ; ------------------------------;
  210. \ : LCD_Clear 0x01 LCD_WrF 80 20_us ; bad init !
  211. : LCD_Clear 0x01 LCD_WrF 100 20_us ;
  212. ; ------------------------------;
  213. : LCD_Home 0x02 LCD_WrF 80 20_us ;
  214. ; ------------------------------;
  215. ; : LCD_Entry_set 0x04 OR LCD_WrF ;
  216. ; : LCD_Display_Ctrl 0x08 OR LCD_WrF ;
  217. ; : LCD_Display_Shift 0x10 OR LCD_WrF ;
  218. ; : LCD_Fn_Set 0x20 OR LCD_WrF ;
  219. ; : LCD_CGRAM_Set 0x40 OR LCD_WrF ;
  220. ; : LCD_Goto 0x80 OR LCD_WrF ;
  221. ; ==========================================================;
  222. ; I2C Standard mode (100kHz) ;
  223. ; ==========================================================;
  224. VARIABLE I2CSLV_ADR ; contents slave address & R/W
  225. VARIABLE I2CM_OUT ; buffer output, lentgh,DATA (low,HIGH)
  226. VARIABLE I2CM_IN ; buffer input, lentgh,DATA (low,HIGH)
  227. 2 ALLOT
  228. ; ------------------------------;
  229. CODE MM_TI2C ; 4 init first once !!! 3(IP+3)~
  230. ; ------------------------------;
  231. BEGIN ;
  232. SUB #1,IP ; 1
  233. 0= UNTIL ; 2
  234. MOV #4,IP ; 1 preset I2C tHIGH=4us complement @ 8MHz ==> 18~ +12~ = 32~
  235. ; MOV #13,IP ; 2 preset I2C tHIGH=4us complement @ 16MHz ==> 51~ +12~ = 64~
  236. ; MOV #25,IP ; 2 preset I2C tHIGH=4us complement @ 24MHz ==> 84~ +12~ = 96~
  237. MOV @RSP+,PC ; 4 ret
  238. ENDCODE ;
  239. ; ------------------------------;
  240. ; ------------------------------; _
  241. CODE MM_SCL ; SCL _| |_
  242. ; ------------------------------; _
  243. BIC.B #0x08,&0x204 ; 4 l _^ P1DIR.3 release SCL (high)
  244. BEGIN ;
  245. BIT.B #0x08,&0x200 ; 3 h test if SCL is released
  246. 0<> UNTIL ; 2 h
  247. CALL #MM_TI2C ; wait tHIGH (4us)
  248. BIT.B #0x04,&0x200 ; 3 h _ P1IN.2 : get SDA
  249. BIS.B #0x08,&0x204 ; 4 h v_ P1DIR.3as output : force SCL low
  250. MOV @RSP+,PC ; 4 l return : C = SDA pin, Z = /SDA pin
  251. ENDCODE ; SDA is released by Slave
  252. ; ------------------------------;
  253. ; ******************************;
  254. CODE I2C_MM ; <-- WDT interval vector interrupt
  255. ; ******************************;
  256. BIC #0xF8,0(RSP) ; CPU on, GIE off in oldSR
  257. ; ------------------------------;
  258. ; ; in : I2CSLV_ADR & (R/W)
  259. ; ; : I2CM_IN/I2CM_OUT as requested by I2C_SLA_ADR(0)
  260. ; ; : I2CM_IN/I2CM_OUT(0) = count of datas to be TX/RX
  261. ; ; : I2CM_IN/I2CM_OUT(0) = 0 ==> send only I2C address
  262. ; ; used: U BUF_PTR
  263. ; ; V count of I2C datas exchanged
  264. ; ; W count of bits
  265. ; ; X data
  266. ; ; Y BUF_ORG
  267. ; ; out : I2CSLV_ADR & (R/W) unchanged
  268. ; ; Y = BUF_ORG
  269. ; ; U = BUF_PTR pointing on first data not exchanged
  270. ; ; V = count of TX/RX datas exchanged (if ack on addr)
  271. ; ; I2CM_IN/OUT(0) = count of data not exchanged (normally = 0)
  272. ; ; I2CM_IN/OUT(0) = -1 <==> Nack on address
  273. ; ------------------------------;
  274. ; I2CMM_Stop_UCBxI2CSlave ; if SDA SCL of I2C_MultiMaster are hard wired onto SDA SCL of I2C_Slave under interrupt...
  275. ; ------------------------------;
  276. ; BIS #1,&0x640 ; set eUSCI_B0 in reset state, reset UCB0IFG
  277. ; ------------------------------;
  278. ; I2C_MR_DC_listenBeforeStart: ; test if SCL & SDA lines are idle (high)
  279. ; ------------------------------;
  280. BEGIN ; case of detection collision during send address
  281. BIC.B #0x0C,&0x204 ; release SCL & SDA pins
  282. MOV #7,V ; I2C_MR_DC_Wait_Start_Loop = 12 ľs @ 8 MHz
  283. ; MOV #14,V ; I2C_MR_DC_Wait_Start_Loop = 12 ľs @ 16 MHz
  284. ; MOV #21,V ; I2C_MR_DC_Wait_Start_Loop = 12 ľs @ 24 MHz
  285. BEGIN ; 13~loop
  286. BEGIN ;
  287. BEGIN ;
  288. BIT.B #0x08,&0x200 ; 3 P1IN.3 SCL high ?
  289. <> UNTIL ; 2
  290. BIT.B #0x04,&0x200 ; 3 P1IN.2 SDA high ?
  291. <> UNTIL ; 2
  292. SUB #1,V ; 1
  293. 0= UNTIL ; 2 here the I2C bus is idle
  294. ; --------------------------;
  295. ; I2C_Master_Start_Cond: ; here, SDA and SCL are in idle state
  296. ; --------------------------; _
  297. BIS.B #0x04,&0x204 ; 3 h |_ force P1DIR.2 (SDA) as output (low)
  298. MOV.B &I2CSLV_ADR,X ; 3 h @ in X
  299. MOV #I2CM_OUT,U ; 2 h buffer out by default
  300. BIT.B #1,X ; 1 h test I2C R/w flag
  301. 0<> IF MOV #I2CM_IN,U ; 5 h buffer in
  302. THEN ;
  303. MOV U,Y ; 1 h U=BUF_ptr Y=BUF_org
  304. ; --------------------------;
  305. ; Init MM_TI2C first ! ; IP must be initialized
  306. ; --------------------------;
  307. MOV #2,IP ; 1 h tHD:STA=4us, 15~ complement @ 8MHz
  308. ; MOV #13,IP ; 2 h tHD:STA=4us, 48~ complement @ 16MHz
  309. ; MOV #23,IP ; 2 h tHD:STA=4us, 78~ complement @ 24MHz
  310. ; --------------------------;
  311. CALL #MM_TI2C ; _ wait tHD;STA
  312. BIS.B #0x08,&0x204 ; 3 h |_ P1DIR.3 force SCL output (low)
  313. ; --------------------------;
  314. ; I2C_Master_Start_EndOf: ;
  315. ; --------------------------;
  316. ; I2C_Master_Send_address ; SCL is held low by slave
  317. ; --------------------------;
  318. MOV #8,W ; 1 l prepare 8 bit Master writing
  319. BIC #0x0400,SR ; 2 reset detection collision flag
  320. BEGIN ;
  321. ADD.B X,X ; 1 l shift one left
  322. U>= IF ; 2 l carry set ?
  323. BIC.B #0x04,&0x204 ; 5 l yes : P1DIR.2 as input ==> SDA high because pull up resistor
  324. ELSE ; 2 l
  325. BIS.B #0x04,&0x204 ; 5 l no : P1DIR.2 as output ==> SDA low
  326. THEN ; l
  327. ; ADD #0,IP ; 2 l tLOW=4,7us, 15~ complement @ 8MHz
  328. ; ADD #3,IP ; 2 l tLOW=4,7us, 54~ complement @ 16MHz
  329. ; ADD #4,IP ; 2 l tLOW=4,7us, 90~ complement @ 24MHz
  330. CALL #MM_TI2C ; l _
  331. BIC.B #0x08,&0x204 ; 5 l _^ P1DIR.3 release SCL (high)
  332. BEGIN
  333. BIT.B #0x08,&0x200 ; 4 h test if SCL is released
  334. 0<> UNTIL ; 2 h
  335. CALL #MM_TI2C ; h
  336. MOV.B &0x200,V ; 3 h _ V = IN1
  337. BIS.B #0x08,&0x204 ; 5 h v_ P1DIR.3 as output : force SCL low
  338. ; ----------------------; l
  339. ; collision detection ;
  340. ; ----------------------;
  341. XOR.B &0x204,V ; 3 l
  342. BIT.B #0x04,V ; 2 l (DIR1.2 xor IN1.2) = 1 if no collision
  343. 0= IF ; 2 l collision detected
  344. BIS #0x0400,SR ; 2 set collision detection SR(10) flag
  345. MOV #1,W ; 1 to abort count of bit loop
  346. THEN ;
  347. SUB #1,W ; 1 l dec count of bits
  348. 0= UNTIL ; 2 l
  349. BIT #0x0400,SR ; 2 l collision ?
  350. 0= UNTIL ; 2 l loop if collision detection
  351. BIC.B #0x04,&0x204 ; 5 l P1DIR.2 as input : release SDA high
  352. ; ------------------------------;
  353. MOV.B @U+,V ; 2 h V = count of datas
  354. ADD #1,V ; 1 l to add address in count
  355. BEGIN ;
  356. ; SUB #1,IP ; 2 l +15~ complement @ 8MHz
  357. ; SUB #5,IP ; 2 l +45~ complement @ 16MHz
  358. ; SUB #10,IP ; 2 l +78~ complement @ 24MHz
  359. CALL #MM_TI2C ; wait still tLOW=4,7us
  360. ; --------------------------; l
  361. ; Master TX/RX ACK/NACK ;
  362. ; --------------------------; l _
  363. CALL #MM_SCL ; SCL _| |_ C flag = NACK
  364. ; --------------------------; 4 l
  365. ; I2C_Master_Loop_Data ;
  366. ; --------------------------;
  367. 0<> IF BIS #2,SR ; l if Nack (TX), force Z+1 ==> StopCond
  368. ELSE SUB.B #1,V ; else dec count
  369. THEN ; l
  370. ; --------------------------;
  371. ; I2C_Master_CheckCountDown ; count=0 or Nack received
  372. ; --------------------------;
  373. 0= IF ; count reached or Nack
  374. ; ----------------------;
  375. ; I2C_Master_StopCond ;
  376. ; ----------------------; _
  377. BIS.B #0x04,&0x204 ; 4 l v_ P1DIR.2 as output ==> SDA low
  378. SUB.B V,0(Y) ; 4 l _ refresh buffer length
  379. BIC.B #0x08,&0x204 ; 4 l _^ P1DIR.3 release SCL (high)
  380. BEGIN ;
  381. BIT.B #0x08,&0x200 ; 3 h SCL released ?
  382. 0<> UNTIL ; 2 h
  383. CALL #MM_TI2C ; h _ wait tSU:STO
  384. BIC.B #0x04,&0x204 ; _| P1DIR.2 as input ==> SDA high with the hard wired pull up resistor
  385. ; ----------------------;
  386. ; I2C_Master_Endof ;
  387. ; ----------------------;
  388. ; Restart I2C_Slave_Int ; if any
  389. ; ----------------------;
  390. ; BIC #1,&0x640 ; restart eUSCI_B
  391. ; MOV #4,&0x66A ; reenable StartCond interrupt
  392. ; ----------------------;
  393. CMP.B #0,V ; V = 0 <==> count of read bytes = as expected
  394. = IF ;
  395. ; BIS.B #0x40,&0x0223 ; P4.6 OUT high ==> switch ON LED1
  396. ; display IR_RC5 command
  397. PUSH &BASE ; save base
  398. SUB #2,PSP ;
  399. MOV TOS,0(PSP) ;
  400. MOV.B 1(Y),TOS ;
  401. ASM>FORTH \ ; IP is free
  402. ['] LCD_CLEAR IS CR
  403. ['] LCD_WrC IS EMIT
  404. CR ." 0x" HEX 2 U.R
  405. 0x4000 0x222 BSET! \ P4.6 OUT high ==> switch ON LED1
  406. SPACE
  407. 0x4000 0x222 BCLR! \ P4.6 OUT low ==> switch OFF LED1
  408. ." LPM = " LPM ? \ display LPM
  409. ['] (CR) IS CR
  410. ['] (EMIT) IS EMIT
  411. FORTH>ASM ; nice code, right ?
  412. MOV @RSP+,&BASE
  413. ; endof display
  414. ; BIC.B #0x40,&0x0223 ; P4.6 OUT low ==> switch OFF LED1
  415. THEN
  416. ; ----------------------;
  417. RETI ; ====> out of RC5_I2C interrupt toutine
  418. ; ----------------------;
  419. THEN ;
  420. ; --------------------------;
  421. MOV.B #8,W ; 1 l prepare 8 bits transaction
  422. BIT #1,&I2CSLV_ADR ; 3 l I2C_Master Read/write bit test
  423. 0= IF ; 2 l write flag test
  424. ; ----------------------;
  425. ; I2C write ;
  426. ; ----------------------;
  427. MOV.B @U+,X ; 2 l next byte to transmit
  428. ; ADD #0,IP ; 2 l tLOW=4,7us, 15~ complement @ 8MHz
  429. ; SUB #3,IP ; 2 l tLOW=4,7us, 36~ complement @ 16MHz
  430. ; SUB #2,IP ; 2 l tLOW=4,7us, 72~ complement @ 24MHz
  431. ; ----------------------;
  432. ; CODE I2C_MTX ; MASTER TX
  433. ; ----------------------; 4 l
  434. BEGIN ;
  435. ADD.B X,X ; 1 l shift one left
  436. U>= IF ; 2 l carry set ?
  437. BIC.B #0x04,&0x204 ; 4 l yes : P1DIR.2 as input ==> SDA high because pull up resistor
  438. ELSE ; 2 l
  439. BIS.B #0x04,&0x204 ; 4 l no : P1DIR.2 as output ==> SDA low
  440. THEN ; l
  441. CALL #MM_TI2C ; l wait still tLOW with predefined complement
  442. ; --------------------; 7 l _
  443. CALL #MM_SCL ; SCL _| |_
  444. ; --------------------; 4 l
  445. SUB #1,W ; 1 l count of bits
  446. 0= UNTIL ; 2 l
  447. BIC.B #0x04,&0x204 ; 3 l P1DIR.2 as input : release SDA high
  448. ELSE ; l
  449. ; ----------------------;
  450. ; I2C read ;
  451. ; ======================;
  452. ; I2C_Master_RX: ; here, SDA is indetermined, SCL is strech low by master
  453. ; ======================;
  454. BEGIN ;
  455. BIC.B #0x04,&0x204 ; 4 l P1DIR.2 as input ==> SDA released high because pull up resistor
  456. ; ADD #0,IP ; 2 l tLOW=4,7us, 6~ complement @ 8MHz
  457. ; SUB #1,IP ; 2 l tLOW=4,7us, 42~ complement @ 16MHz
  458. ; ADD #1,IP ; 2 l tLOW=4,7us, 81~ complement @ 24MHz
  459. CALL #MM_TI2C ; wait still tLOW
  460. ; ------------------; 7 l _
  461. CALL #MM_SCL ; SCL _| |_
  462. ; ------------------; 4 l
  463. ADDC.B X,X ; 1 l C <-- X <--- C
  464. SUB #1,W ; 1 l count of bits
  465. 0= UNTIL ; 2 l
  466. MOV.B X,0(U) ; 3 l store byte @ BUF_PTR
  467. ADD #1,U ; 1 l
  468. ; ----------------------;
  469. ; I2C_MSendAckOrNack ; here, SDA is released by slave, SCL is strech low by master
  470. ; ----------------------;
  471. SUB.B #1,V ;
  472. 0<> IF ; 2
  473. BIS.B #0x04,&0x204 ; 4 l prepare send Ack if byte count <> 1
  474. THEN ;
  475. THEN ;
  476. AGAIN ; l
  477. ENDCODE ;
  478. ; ------------------------------;
  479. ; PORTA (P2:P1) MSP-EXP430FR5969 default I/O state : input with pullup resistors
  480. ; init PORTA (P2:P1) usage
  481. ; P1.0 --> LED2
  482. ; P1.1 <-- Switch S2
  483. ; P1.2 <-- SCL Soft MASTER
  484. ; P1.3 <-- SDA Soft MASTER
  485. ; P1.4 <-- free
  486. ; P1.5 <-- free
  487. ; P1.6 <-> SLAVE SDA
  488. ; P1.7 --> SLAVE SCL
  489. ; P2.0 --> UART0 TX
  490. ; P2.1 <-- UART0 RX
  491. ; P2.2 --> LCD_Vo
  492. ; P2.3 NC
  493. ; P2.4 <->
  494. ; P2.5 -->
  495. ; P2.6 <--
  496. ; P2.7 NC
  497. ; PORTB (P3:P4) MSP-EXP430FR5969 default I/O state : input with pullup resistors
  498. ; P3.0 <-- ADC12
  499. ; P3.1 NC
  500. ; P3.2 NC
  501. ; P3.3 NC
  502. ; P3.4 --> LCD_RS
  503. ; P3.5 --> LCD_RW
  504. ; P3.6 --> LCD_EN
  505. ; P3.7 NC
  506. ; P4.0 <-- TSOP32236 (IR_RC5 receiver)
  507. ; P4.1 --> UART0 /RTS
  508. ; P4.2 <--
  509. ; P4.3 -->
  510. ; P4.5 <-- Switch S1
  511. ; P4.6 --> LED1
  512. ; P4.7 NC
  513. ; PJ.0 <-- LCD_DB4
  514. ; PJ.1 <-- LCD_DB5
  515. ; PJ.2 <-- LCD_DB6
  516. ; PJ.3 <-- LCD_DB7
  517. ; PJ.4 <-- LFXIN 32.7638kHz
  518. ; PJ.5 --> LFXOUT 32.7638kHz
  519. ; PJ.6 <-> LFXIN free
  520. ; PJ.7 <-> LFXOUT free
  521. ; ------------------------------;
  522. CODE START ; initialize I2C_Soft_Master_to_LCD_2x20
  523. ; ------------------------------;
  524. ; ; set TimerB to generate LCD_V0 via TB0.1 and P1.4/P2.6
  525. ; MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int (8MHZ)
  526. ; ; MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (8 MHZ)
  527. ; MOV #1,&0x03E0 ; predivide by 2 in TB0EX0 register (16 MHZ)
  528. ; ; MOV #2,&0x03E0 ; predivide by 3 in TB0EX0 register (24 MHZ)
  529. ; MOV #40,&0x3D2 ; TB0CCR0 = 40*0.5us=20us
  530. ; MOV #0b1100000,&0x3C4 ; TB0CCTL1 output mode = set/reset
  531. ; MOV #20,&0x3D4 ; TB0CCR1 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
  532. ; ; ------------------------------;
  533. ; set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
  534. MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int (8MHZ)
  535. MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (8 MHZ)
  536. ; MOV #1,&0x03E0 ; predivide by 2 in TB0EX0 register (16 MHZ)
  537. ; MOV #2,&0x03E0 ; predivide by 3 in TB0EX0 register (24 MHZ)
  538. MOV #40,&0x3D2 ; TB0CCR0 = 40*0.5us=20us
  539. MOV #0b1100000,&0x3C6 ; TB0CCTL2 output mode = set/reset
  540. MOV #20,&0x3D6 ; TB0CCR2 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
  541. ; set TimerB to make 50kHz PWM ;
  542. ; ------------------------------;
  543. ; MOV #0b1000010100,&0x3C0 ; TB0CTL = SMCLK/1, up mode, clear timer, no int
  544. ; MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
  545. ; ------------------------------;
  546. ; MOV #0b1000010100,&0x3C0 ; TB0CTL = SMCLK/1, up mode, clear timer, no int
  547. ; MOV #2,&0x03E0 ; predivide by 2 in TB0EX0 register (4 MHZ)
  548. ; ------------------------------;
  549. MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int
  550. MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (8 MHZ)
  551. ; ------------------------------;
  552. ; MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int
  553. ; MOV #1,&0x03E0 ; predivide by 2 in TB0EX0 register (16 MHZ)
  554. ; ------------------------------;
  555. ; MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int
  556. ; MOV #3,&0x03E0 ; predivide by 3 in TB0EX0 register (24 MHZ)
  557. ; ------------------------------;
  558. MOV #40,&0x3D2 ; TB0CCR0 = 40*0.5us=20us (40us @ 1MHz)
  559. ; ------------------------------;
  560. ; set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
  561. ; ------------------------------;
  562. MOV #0b1100000,&0x3C6 ; TB0CCTL2 output mode = set/reset ; clear CCIFG
  563. MOV #20,&0x3D6 ; TB0CCR2 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
  564. ; ------------------------------;
  565. ; set TimerB to generate LCD_V0 via TB0.1 and P1.4/P2.6
  566. ; ------------------------------;
  567. ; MOV #0b1100000,&0x3C4 ; TB0CCTL1 output mode = set/reset
  568. ; MOV #20,&0x3D4 ; TB0CCR1 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
  569. ; ------------------------------;
  570. ; I2C_MASTER init part ;
  571. ; ------------------------------;
  572. MOV #0b0010100,&I2CSLV_ADR ; MSP430FR5738 slave address
  573. ; MOV.B #0b010110,&I2CSLV_ADR ; other slave address
  574. BIS #1,&I2CSLV_ADR ; to read slave
  575. MOV #1,&I2CM_IN ; one data expected
  576. ; ------------------------------;
  577. ; WDT interval init part ;
  578. ; ------------------------------;
  579. ; MOV #0x5A5E,&0x15C ; init WDT Vloclk source 10kHz /2^9 (50 ms), interval mode
  580. ; MOV #0x5A5D,&0x15C ; init WDT Vloclk source 10kHz /2^13 (820 ms), interval mode
  581. ; ------------------------------;
  582. BIS.B #0x10,&0x32A ; PJSEL0.4 = 1 starts LFXT on ACLK
  583. MOV #0x5A3D,&0x15C ; init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
  584. ; ------------------------------;
  585. BIS #1,&0x100 ; enable WDT interval mode interrupt in SFRIE
  586. ; ------------------------------;
  587. ; init interrupt vectors
  588. MOV #I2C_MM,&0xFFF2 ; init WDT interval vector interrupt
  589. MOV #INT_P1,&0xFFDE ; init P1 interrupt vector
  590. MOV #INT_P4,&0xFFD0 ; init P4 interrupt vector
  591. ; ------------------------------;
  592. ; init PORTA (P2:P1) (complement) when reset occurs all I/O are set in input with resistors pullup
  593. BIC.B #0x0C,&0x202 ; P1OUT.23 preset SDA + SCL output low
  594. ; BIC.B #0x0C,&0x206 ; P1REN.23 SDA + SCL pullup/down disable
  595. BIS.B #0x02,&0x218 ; P1IES.1 high to low edge select (S2)
  596. BIC.B #0x02,&0x21C ; P1IFG.1 clear (after IES select) (S2)
  597. BIS.B #0x02,&0x21A ; P1IE.1 enable interrupt (S2)
  598. BIS.B #0x04,&0x205 ; P2DIR.2 TB0.2 output
  599. BIS.B #0x04,&0x20B ; P2SEL0.2 TB0.2
  600. ; ------------------------------;
  601. ; init PORTB (P4:P3) (complement) when reset occurs all I/O are set in input with resistors pullup
  602. BIS.B #0x70,&0x224 ; P3DIR.456 as outputs, wired to LCD_RS LCD_RW LCD_EN
  603. BIC.B #0x70,&0x226 ; P3REN.456 LCD_RS, LCD_RW, LCD_EN, pullup/down disable
  604. BIC.B #0x30,&0x222 ; P3OUT.45 LCD_RW = LCD_RS = 0
  605. BIS.B #0x20,&0x239 ; P4IES.5 high to low edge select
  606. BIC.B #0x20,&0x23D ; P4IFG.5 clear (after IES select)
  607. BIS.B #0x20,&0x23B ; P4IE.5 enable interrupt for S1
  608. ; ------------------------------;
  609. ; init PORTJ (PJ) (complement) when reset occurs all I/O are set in input with resistors pullup
  610. BIS.B #0x0F,&0x324 ; PJDIR.0123 as output, wired to DB.4567 LCD_Data
  611. BIC.B #0x0F,&0x326 ; PJREN.0123 LCD_Data pullup/down disable
  612. ; ------------------------------;
  613. ; MOV #0x58,&LPM ; enter in LPM1 mode (same as LPM0)
  614. ; MOV #0x98,&LPM ; enter in LPM2 mode
  615. MOV #0xD8,&LPM ; enter in LPM3 mode (to preserve RTC)
  616. ; MOV #0xF8,&LPM ; enter in LPM4 mode (no RTC)
  617. ; ------------------------------;
  618. ; Init LCD 2x20 ;
  619. ; ------------------------------;
  620. ASM>FORTH
  621. 0x03E8 20_us \ ; 1- wait 20 ms
  622. 0x03 TOP_LCD \ ; 2- send DB5=DB4=1
  623. 0xCD 20_us \ ; 3- wait 4,1 ms
  624. 0x03 TOP_LCD \ ; 4- send again DB5=DB4=1
  625. 5 20_us \ ; 5- wait 0,1 ms
  626. 0x03 TOP_LCD \ ; 6- send again again DB5=DB4=1
  627. 2 20_us \ ; wait 40 us = LCD cycle
  628. 0x02 TOP_LCD \ ; 7- send DB5=1 DB4=0
  629. 2 20_us \ ; wait 40 us = LCD cycle
  630. 0x28 LCD_WrF \ ; 8- 0b001DNFxx "FonctionSet" : D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
  631. 0x08 LCD_WrF \ ; 9- 0b1DCB "DisplayControl" : Display off, Cursor off, Blink off.
  632. LCD_Clear \ ; 10- "LCD_Clear"
  633. 0x06 LCD_WrF \ ; 11- 0b01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
  634. 0x0C LCD_WrF \ ; 12- 0b1DCB "DisplayControl" : Display on, Cursor off, Blink off.
  635. ['] LCD_WrC IS EMIT \ ;EMIT is redirected to LCD_WrC
  636. ." SYSRSTIV = " \ ;
  637. 0x1800 @ \ ; print SAVE_SYSRSTIV
  638. HEX 2 U.R \ ; (WARM) reinit decimal BASE and reset SAVE_SYSRSTIV
  639. ['] (EMIT) IS EMIT \ ;restore EMIT
  640. ." Type STOP to quit I2C_SoftMultiMaster_to_LCD"
  641. LIT RECURSE IS WARM \ ; redirect WARM to START...
  642. (WARM) ; ; ...and finish START with (WARM)
  643. CODE STOP
  644. BIC.B #0x0C,&0x204 ; P1DIR.23 release SDA + SCL output low
  645. MOV #0b1010000100,&0x3C0 ; TB0CTL = SMCLK/4, STOP mode, clear timer, no int
  646. BIC.B #0x02,&0x21A ; P1IE.1 disable interrupt for S2
  647. BIC.B #0x20,&0x23B ; P4IE.5 disable interrupt for S1
  648. BIC #1,&0x100 ; disable WDT interval mode interrupt in SFRIE
  649. ASM>FORTH
  650. ['] (WARM) IS WARM \ ; reconnect WARM to (WARM)
  651. -1 ABORT"
  652. ; ; above, ABORT" followed by CRLF allows to compile an empty string...
  653. ; DUP HERE SWAP - DUMP ; general minidump, part 2
  654. FORGET INT_P1 FORGET INT_P4 ; not FORTH executable
  655. FORGET MM_TI2C FORGET MM_SCL ; because not FORTH executable
  656. FORGET I2C_MM ; because not FORTH executable
  657. FORGET 20_us FORGET LCD_W ; because they are not necessary
  658. FORGET LCD_R FORGET TOP_LCD ; because they are not necessary
  659. ECHO
  660. ; compiling is done
  661. RST_HERE ; RST restart app ;
  662. START ;