DSPI.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //==============================================================================
  2. // Purpose: SPI Interface für das DSPI-Modul des MPC5646
  3. //
  4. // Created on: 20.04.2012 by IPE
  5. //
  6. // History
  7. // 20.04.2012 neu, T.Maurer
  8. //==============================================================================
  9. #include "BMS_Master.h"
  10. /*
  11. const DSPI_config_t SPI_1_Config = {
  12. &DSPI_1,
  13. DSPI_Slave,
  14. 16, //FrameSize
  15. DSPI_ClassicFormat,
  16. DSPI_Baud15MHz,
  17. 0,
  18. 0,
  19. 0,
  20. 1,
  21. DSPI1_PortE4
  22. };
  23. */
  24. const DSPI_config_t SPI_6_Config = {
  25. &DSPI_6,
  26. DSPI_Master,
  27. 16, //FrameSize
  28. DSPI_ClassicFormat,
  29. DSPI_Baud2MHz,
  30. 4,
  31. 4,
  32. 10,
  33. 1,
  34. CS_Cont_ON, //enum{CS_Cont_ON, CS_Cont_OFF};
  35. DSPI6_PortG14
  36. };
  37. // ----------------------------------------------------------------------------
  38. int8_t DSPI_init(DSPI_config_t *const Config)
  39. {
  40. volatile struct DSPI_tag *p_DSPI;
  41. p_DSPI = Config->p_Modul;
  42. // -------------------------------------------------------------------
  43. // DSPI_0.MCR.R = 0x80010001; // Configure DSPI_0 as master, and HALT the DSPI module für reg configuration //
  44. p_DSPI->MCR.B.MSTR = (Config->MaSlv_Mode==DSPI_Master) ? 1:0; // 1: Master Mode, 0:Slave Mode
  45. p_DSPI->MCR.B.CONT_SCKE = 0; // 0: Continuous serial clock: disabled
  46. p_DSPI->MCR.B.DCONF = 0b00; // 00: SPI Mode, 01 DSI Mode, 10:CSI Mode
  47. p_DSPI->MCR.B.FRZ = 0b0; // FREEZE: 0; if Freeze=1, tx will be stopped on next frame tx in DEBUG
  48. p_DSPI->MCR.B.MTFE = (Config->TimingFormat==DSPI_ModifiedFormat) ? 1:0; // Modified Timing Format Enable; 0: disabled
  49. p_DSPI->MCR.B.PCSSE = 0b0; // Peripheral chip select strobe enable; 0:0 CS5_x is used as the Peripheral chip select 5 signal
  50. p_DSPI->MCR.B.ROOE = 0b0; // Recieve FIFO Overflow Overwrite; 0: incoming data is ignored, 1: Incoming data is shifted in register
  51. p_DSPI->MCR.B.PCSIS5 = (Config->Std_CS_Mask & 32) ? 1:0; // Peripheral Chip Select 5 inactive state: 0: inactiv CS=low
  52. p_DSPI->MCR.B.PCSIS4 = (Config->Std_CS_Mask & 16) ? 1:0; // Peripheral Chip Select 4 inactive state: 0: inactiv CS=low
  53. p_DSPI->MCR.B.PCSIS3 = (Config->Std_CS_Mask & 8) ? 1:0; // Peripheral Chip Select 3 inactive state: 0: inactiv CS=low
  54. p_DSPI->MCR.B.PCSIS2 = (Config->Std_CS_Mask & 4) ? 1:0; // Peripheral Chip Select 2 inactive state: 0: inactiv CS=low
  55. p_DSPI->MCR.B.PCSIS1 = (Config->Std_CS_Mask & 2) ? 1:0; // Peripheral Chip Select 1 inactive state: 0: inactiv CS=low
  56. p_DSPI->MCR.B.PCSIS0 = (Config->Std_CS_Mask & 1) ? 1:0; // Peripheral Chip Select 0 inactive state: 1: inactiv CS=HIGH
  57. p_DSPI->MCR.B.MDIS = 0b0; // Module diable; 0:Enable DSPI CLKs; 1 Allow external logic to disable DSPI CLKs
  58. p_DSPI->MCR.B.DIS_TXF = 0b0; // Disable Receive FIFO; 0 TX FIFO enabled; 1: simplified double buffered SPI
  59. p_DSPI->MCR.B.DIS_RXF = 0b0; // Disable Receive FIFO; 0 RX FIFO enabled; 1: simplified double buffered SPI
  60. p_DSPI->MCR.B.CLR_TXF = 0b0; // Clear TX FIFO, used to flush TX_FIFO: writing a 1: Clear TX FIFO Counter
  61. p_DSPI->MCR.B.CLR_RXF = 0b0; // Clear RX FIFO, used to flush RX_FIFO: writing a 1: Clear RX FIFO Counter
  62. p_DSPI->MCR.B.SMPL_PT = 0b00; // Sample Point in modified transfers 00: rising SLK
  63. p_DSPI->MCR.B.PES = 0b0; // Parity Error Stop, 0: SPI transmission continues on error
  64. p_DSPI->MCR.B.HALT = 0b1; // 1: Stop Transfers, 0:start transfers
  65. // -------------------------------------------------------------------
  66. //DSPI_0.CTAR[0].R = 0x780A7727; // Configure CTAR0, Clock and Transfer Attributes //
  67. if (Config->FrameSize==0) return -1;
  68. p_DSPI->CTAR[0].B.FMSZ = Config->FrameSize-1; // FMSZ: 0b0111: 8Bit (7+1) werden übertragen Frame Size
  69. p_DSPI->CTAR[0].B.CPOL = 0b0; // CPOL: 0b0 Clock Polarity 0-SCK active High
  70. p_DSPI->CTAR[0].B.CPHA = 0b0; // CPHA: 0b0 Clock Phase 0 captue data on leading edge, change on following edge
  71. p_DSPI->CTAR[0].B.LSBFE = 0b0; // LSBFE: 0b0 LSB first enable: 0 MSB fisrt
  72. //Delays
  73. if (Config->AfterSCK_Delay_Cycles < 16) {
  74. p_DSPI->CTAR[0].B.PASC = 0; // PASC : 0b00 After SCK Delay Prescaler 00: value is 1
  75. p_DSPI->CTAR[0].B.ASC = Config->AfterSCK_Delay_Cycles; // ASC : 0b0111 After Serial Clock Scaler, is the delay between the last Clk on the negation of PCS
  76. }
  77. else return -1;
  78. if (Config->CStoSCK_Delay_Cycles < 16) {
  79. p_DSPI->CTAR[0].B.PCSSCK = 0; // PCSSCK: 0b00 PCS to SCK Delay: 00 value is 1
  80. p_DSPI->CTAR[0].B.CSSCK = Config->CStoSCK_Delay_Cycles; // CSSCK: 0b0111 CS to SCK Delay Scaler, The CS to SCK Delay is the delay between the assertion of PCS and the first edge of SCK
  81. }
  82. else return -1;
  83. if (Config->DelayAfterTransfer_Cycles < 16) {
  84. p_DSPI->CTAR[0].B.PDT = 0; // PDT : 0b10 Delay after transfer Prescaler, Delay between CS signal and PCS of next frame (prescaler) 10:value is 5
  85. p_DSPI->CTAR[0].B.DT = Config->DelayAfterTransfer_Cycles; // DT: 0b0010 Delay after transfer (time between CS at the end of the frame and the assertion of PCS of next frame)
  86. }
  87. else return -1;
  88. //BaudRate
  89. if (Config->Baud_Setting==DSPI_Baud15MHz) {
  90. p_DSPI->CTAR[0].B.DBR = 0b0; // DBR: 0b0: Double Baud Rate:0x0
  91. p_DSPI->CTAR[0].B.PBR = 0b00; // PBR : 0b01 BaudRatePrescaler: 00 -> 2, 01 -> 3
  92. p_DSPI->CTAR[0].B.BR = 0b0000; // BR: 0b0001 BaudRateScaler; SCK baud rate= f_sys/PBR*(1+DBR)/BR, 0001: value is 4
  93. // fsys=60MHZ Peripheral 2 Settings und PBR=3,BR=4: 5MHZ Serial Port Frequency
  94. }
  95. else if (Config->Baud_Setting==DSPI_Baud5MHz) {
  96. p_DSPI->CTAR[0].B.DBR = 0b0; // DBR: 0b0: Double Baud Rate:0x0
  97. p_DSPI->CTAR[0].B.PBR = 0b01; // PBR : 0b01 BaudRatePrescaler: 01 - value is 3
  98. p_DSPI->CTAR[0].B.BR = 0b0001; // BR: 0b0001 BaudRateScaler; 0000->2,0001->4; SCK baud rate= f_sys/PBR*(1+DBR)/BR, 0001: value is 4
  99. // fsys=60MHZ Peripheral 2 Settings und PBR=3,BR=4: 5MHZ Serial Port Frequency
  100. }
  101. else if (Config->Baud_Setting==DSPI_Baud2MHz) {
  102. p_DSPI->CTAR[0].B.DBR = 0b0; // DBR: 0b0: Double Baud Rate:0x0
  103. p_DSPI->CTAR[0].B.PBR = 0b10; // PBR : 0b01 BaudRatePrescaler: 01 - value is 3
  104. p_DSPI->CTAR[0].B.BR = 0b0010; // BR: 0b0001 BaudRateScaler; 0000->2,0001->4; SCK baud rate= f_sys/PBR*(1+DBR)/BR, 0001: value is 4
  105. // fsys=60MHZ Peripheral 2 Settings und PBR=3,BR=4: 5MHZ Serial Port Frequency
  106. }
  107. // -------------------------------------------------------------------
  108. p_DSPI->MCR.B.HALT = 0x0; // Exit HALT mode: go from STOPPED to RUNNING state, die Initialisierung nur im Halt Mode//
  109. // -------------------------------------------------------------------
  110. // configure port pins for DSPI
  111. if (p_DSPI==(&DSPI_0) && Config->Port==DSPI0_PortA12) {
  112. SIU.PCR[12].R = 0x0103; // Config pad as DSPI_0 SIN input, PA[12], FRAM DOUT
  113. SIU.PCR[13].R = 0x0604; // Config pad as DSPI_0 SOUT output, PA[13], FRAM DIN
  114. SIU.PCR[14].R = 0x0604; // Config pad as DSPI_0 SCK output, PA[14], FRAM SCLK
  115. SIU.PCR[15].R = 0x0604; // Config pad as DSPI_0 CS0 output, PA[15], FRAM CS
  116. SIU.PSMI[5].R = 0b000; // select PCR[14] as SCK0_0, Fehler in Registerbeschreibung und MPC5646 Reference Manual?
  117. SIU.PSMI[6].R = 0b001; // select PCR[15] as CS0_0
  118. }
  119. else if (p_DSPI==(&DSPI_1) && Config->Port==DSPI1_PortE4) {
  120. SIU.PCR[68].R = 0x0903; // MPC56xxB: Config pad as DSPI_1 SCK input, PE[4] //
  121. SIU.PSMI[7].R = 1; // MPC56xxB: Select PCR 68 for DSPI_1 SCK input //
  122. SIU.PCR[36].R = 0x0103; // MPC56xxB: Config pad as DSPI_1 SIN input, , PC[4] //
  123. SIU.PSMI[8].R = 0; // MPC56xxB: Select PCR 36 for DSPI_1 SIN input //
  124. SIU.PCR[37].R = 0x0604; // MPC56xxB: Config pad as DSPI_1 SOUT output, PC[5]//
  125. SIU.PCR[69].R = 0x0903; // MPC56xxB: Config pad as DSPI_1 PCS0/SS input, PE[5] //
  126. SIU.PSMI[9].R = 2; // MPC56xxB: Selec PCR 69 for DSPI_1 SS input //
  127. }
  128. else if (p_DSPI==(&DSPI_2) && Config->Port==DSPI2_PortC12) {
  129. SIU.PCR[44].R = 0x0103; // Config pad as DSPI_2 SIN input, PC[12], TEMP DOUT
  130. SIU.PCR[45].R = 0x0A04; // Config pad as DSPI_2 SOUT output, PC[13], n.u., AF2
  131. SIU.PCR[46].R = 0x0A04; // Config pad as DSPI_2 SCK output, PC[15], TEMP SCLK, AF2
  132. SIU.PSMI[10].R = 0b000; // select PCR[46] as SCK_2
  133. SIU.PCR[47].R = 0x0A04; // Config pad as DSPI_2 CS0 output, PA[14], TEMP CS, AF2
  134. SIU.PSMI[12].R = 0b000; // select PCR[47] as CS0_2
  135. }
  136. else if (p_DSPI==(&DSPI_3) && Config->Port==DSPI3_PortG2) {
  137. SIU.PCR[98].R = 0x0A04; // Config pad as DSPI_3 SOUT output, PG[2], AF2
  138. SIU.PCR[99].R = 0x0A04; // Config pad as DSPI_3 CS0 output, PG[3], AF2
  139. SIU.PCR[100].R = 0x0A04; // Config pad as DSPI_3 SCK output, PG[4] AF2
  140. SIU.PSMI[32].R = 0b0000; // select PCR[100] as SCK_3
  141. SIU.PSMI[34].R = 0b0000; // select PCR[99] as CS0_3
  142. }
  143. else if (p_DSPI==(&DSPI_4) && Config->Port==DSPI4_PortK9) {
  144. SIU.PCR[170].R = 0x0604; // Config pad as DSPI_4 SOUT output, AF1
  145. SIU.PCR[169].R = 0x0102; // Config pad as DSPI_4 SIN input,
  146. SIU.PCR[171].R = 0x0604; // Config pad as DSPI_4 SCK output, AF1
  147. SIU.PCR[172].R = 0x0604; // Config pad as DSPI_4 CS_4 output, AF1
  148. SIU.PSMI[35].R = 0b0011; // Select PCR 171 for SCK_4
  149. SIU.PSMI[36].R = 0b0010; // Select PCR 169 for SIN_4
  150. SIU.PSMI[37].R = 0b0100; // Select PCR 172 for CS0_4
  151. }
  152. else if (p_DSPI==(&DSPI_6) && Config->Port==DSPI6_PortG14) {
  153. SIU.PCR[110].R = 0x0103; // Config pad as DSPI_6 SIN input, PG[14], TEMP DOUT,
  154. SIU.PCR[111].R = 0x0A04; // Config pad as DSPI_6 SOUT output, PG[15], n.u., AF2
  155. SIU.PCR[79].R = 0x0E04; // Config pad as DSPI_6 SCK_6 output,PE[15], TEMP CS, AF3
  156. SIU.PCR[107].R = 0x0E04; // Config pad as DSPI_6 CS0 output, PG[11], TEMP SCLK, AF3
  157. }
  158. else return -1;
  159. return 0;
  160. }
  161. /*
  162. int8_t DSPI_check_and_read(DSPI_config_t *const p_Config, uint32_t *data) {
  163. volatile struct DSPI_tag *p_DSPI;
  164. p_DSPI = p_Config->p_Modul;
  165. p_DSPI->SR.B.RFDF=1; //clear
  166. if (p_DSPI->SR.B.RFDF==1) { // Wait for Receive FIFO Drain Flag = 1
  167. *data = p_DSPI->POPR.R; // Read data received by master SPI
  168. p_DSPI->SR.R = 0x90020000; // Clear TCF, RDRF, EOQ flags by writing 1
  169. return 1; //Nachricht empfangen
  170. }
  171. else return 0; //keine Nachricht
  172. }
  173. */
  174. int8_t DSPI_push(DSPI_config_t *const p_Config, uint16_t data, uint8_t isEOQ)
  175. {
  176. volatile struct DSPI_tag *p_DSPI;
  177. uint32_t push_tmp = 0;
  178. p_DSPI = p_Config->p_Modul;
  179. p_DSPI->SR.B.TFFF = 1; //TFFF zurücksetzen
  180. if ( ! p_DSPI->SR.B.TFFF ) return -1; //Fifo voll?
  181. if (isEOQ) { //Letztes Byte/Wort des Frames?
  182. push_tmp |= 0x08000000; //EOQ End Of Queue
  183. }
  184. else {
  185. if (p_Config->CS_Cont==CS_Cont_ON)
  186. push_tmp |= 0x80000000;
  187. }
  188. push_tmp |= (p_Config->Std_CS_Mask << 16); //ChipSelect
  189. push_tmp |= data;
  190. p_DSPI->PUSHR.R = push_tmp;
  191. return 0;
  192. /* DSPI_0.PUSHR.B.CONT = 0; // Cont. CS enable between TX (0: CS is switch into idle after TX)
  193. DSPI_0.PUSHR.B.CTAS = 0b000; // No. of CTAR Reg. selected
  194. DSPI_0.PUSHR.B.EOQ = 0b1; // End of Queue (1: Last Data to be TX)
  195. DSPI_0.PUSHR.B.CTCNT = 0b0; // Clear TX Counter (0: do not clear counter)
  196. DSPI_0.PUSHR.B.PE = 0b0; // Parity enable (0: no parity)
  197. DSPI_0.PUSHR.B.PP = 0b0; // Parity Polarity (0: even)
  198. // ::2
  199. DSPI_0.PUSHR.B.PCS5 = 0b0; // 1: Assert peripheral Chip select
  200. DSPI_0.PUSHR.B.PCS4 = 0b0; // 1: Assert peripheral Chip select
  201. DSPI_0.PUSHR.B.PCS3 = 0b0; // 1: Assert peripheral Chip select
  202. DSPI_0.PUSHR.B.PCS2 = 0b0; // 1: Assert peripheral Chip select
  203. DSPI_0.PUSHR.B.PCS1 = 0b0; // 1: Assert peripheral Chip select
  204. DSPI_0.PUSHR.B.PCS0 = 0b1; // 1: Assert peripheral Chip select
  205. DSPI_0.PUSHR.B.TXDATA = TxDataDAC; // TX Data to be transmitted
  206. */
  207. }
  208. int8_t DSPI_pop(DSPI_config_t *const p_Config, volatile uint16_t *const data)
  209. {
  210. volatile struct DSPI_tag *p_DSPI;
  211. p_DSPI = p_Config->p_Modul;
  212. p_DSPI->SR.B.RFDF=1; //clear
  213. if ( ! p_DSPI->SR.B.RFDF ) return -1; //Fifo leer?
  214. *data = (vuint16_t)(p_DSPI->POPR.R & 0xFFFF);
  215. p_DSPI->SR.B.RFDF = 1; //Drain-Flag zurücksetzen
  216. return 0;
  217. }
  218. int8_t DSPI_init_Tx(DSPI_config_t *const p_Config)
  219. {
  220. volatile struct DSPI_tag *p_DSPI;
  221. p_DSPI = p_Config->p_Modul;
  222. if ( p_DSPI->SR.B.TXCTR != 0 ) return -1;
  223. p_DSPI->SR.B.EOQF = 1; //EOQ-Flag löschen
  224. p_DSPI->SR.B.TCF = 1; //EOQ-Flag löschen
  225. return 0;
  226. }
  227. int8_t DSPI_Clear_RxFifo(DSPI_config_t *const p_Config)
  228. {
  229. volatile struct DSPI_tag *p_DSPI;
  230. uint32_t dummy;
  231. p_DSPI = p_Config->p_Modul;
  232. while (p_DSPI->SR.B.RXCTR != 0) {
  233. dummy = p_DSPI->POPR.R;
  234. }
  235. p_DSPI->SR.B.RFDF = 1; //Drain-Flag zurücksetzen
  236. /*
  237. if (p_DSPI->SR.B.RXCTR != 0) {
  238. p_DSPI->MCR.B.CLR_RXF = 1;
  239. p_DSPI->SR.B.RFDF = 1; //Drain-Flag zurücksetzen
  240. return 1; //Fifo gelöscht
  241. }*/
  242. return 0; //keine Nachricht im Fifo
  243. }