spi.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. #include "driver/spi.h"
  2. typedef union {
  3. uint32 word[2];
  4. uint64 dword;
  5. } spi_buf_t;
  6. static uint32_t spi_clkdiv[2];
  7. /******************************************************************************
  8. * FunctionName : spi_lcd_mode_init
  9. * Description : SPI master initial function for driving LCD TM035PDZV36
  10. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  11. *******************************************************************************/
  12. void spi_lcd_mode_init(uint8 spi_no)
  13. {
  14. uint32 regvalue;
  15. if(spi_no>1) return; //handle invalid input number
  16. //bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock
  17. //bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock
  18. if(spi_no==SPI_SPI){
  19. WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); //clear bit9,and bit8
  20. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
  21. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
  22. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
  23. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
  24. }else if(spi_no==SPI_HSPI){
  25. WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9
  26. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
  27. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
  28. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
  29. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode
  30. }
  31. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND);
  32. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
  33. // SPI clock=CPU clock/8
  34. WRITE_PERI_REG(SPI_CLOCK(spi_no),
  35. ((1&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
  36. ((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
  37. ((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
  38. ((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
  39. }
  40. /******************************************************************************
  41. * FunctionName : spi_lcd_9bit_write
  42. * Description : SPI 9bits transmission function for driving LCD TM035PDZV36
  43. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  44. * uint8 high_bit - first high bit of the data, 0 is for "0",the other value 1-255 is for "1"
  45. * uint8 low_8bit- the rest 8bits of the data.
  46. *******************************************************************************/
  47. void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit)
  48. {
  49. uint32 regvalue;
  50. uint8 bytetemp;
  51. if(spi_no>1) return; //handle invalid input number
  52. if(high_bit) bytetemp=(low_8bit>>1)|0x80;
  53. else bytetemp=(low_8bit>>1)&0x7f;
  54. regvalue= ((8&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|((uint32)bytetemp); //configure transmission variable,9bit transmission length and first 8 command bit
  55. if(low_8bit&0x01) regvalue|=BIT15; //write the 9th bit
  56. while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR); //waiting for spi module available
  57. WRITE_PERI_REG(SPI_USER2(spi_no), regvalue); //write command and command length into spi reg
  58. SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR); //transmission start
  59. }
  60. /******************************************************************************
  61. * FunctionName : spi_set_clkdiv
  62. * Description : Set the clock divider
  63. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  64. * uint32 clock_div - new clock divider
  65. * Returns : uint32 - previous clock divider
  66. *******************************************************************************/
  67. uint32_t spi_set_clkdiv(uint8 spi_no, uint32_t clock_div)
  68. {
  69. uint32_t tmp_clkdiv;
  70. if (spi_no > 1) return 0; //handle invalid input number
  71. tmp_clkdiv = spi_clkdiv[spi_no];
  72. if (clock_div > 1) {
  73. uint8 i, k;
  74. i = (clock_div / 40) ? (clock_div / 40) : 1;
  75. k = clock_div / i;
  76. WRITE_PERI_REG(SPI_CLOCK(spi_no),
  77. (((i - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
  78. (((k - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
  79. ((((k + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
  80. (((k - 1) & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
  81. } else {
  82. WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK); // 80Mhz speed
  83. }
  84. if(spi_no==SPI_SPI){
  85. WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div <= 1 ? 0x100 : 0));
  86. }
  87. else if(spi_no==SPI_HSPI){
  88. WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div <= 1 ? 0x200 : 0));
  89. }
  90. spi_clkdiv[spi_no] = clock_div;
  91. return tmp_clkdiv;
  92. }
  93. /******************************************************************************
  94. * FunctionName : spi_master_init
  95. * Description : SPI master initial function for common byte units transmission
  96. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  97. *******************************************************************************/
  98. void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_div)
  99. {
  100. uint32 regvalue;
  101. if(spi_no>1) return; //handle invalid input number
  102. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER);
  103. // set clock polarity (Reference: http://bbs.espressif.com/viewtopic.php?f=49&t=1570)
  104. // phase is dependent on polarity. See Issue #1161
  105. if (cpol == 1) {
  106. SET_PERI_REG_MASK(SPI_PIN(spi_no), SPI_IDLE_EDGE);
  107. } else {
  108. CLEAR_PERI_REG_MASK(SPI_PIN(spi_no), SPI_IDLE_EDGE);
  109. }
  110. //set clock phase
  111. if (cpha == cpol) {
  112. // Mode 3: MOSI is set on falling edge of clock
  113. // Mode 0: MOSI is set on falling edge of clock
  114. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
  115. } else {
  116. // Mode 2: MOSI is set on rising edge of clock
  117. // Mode 1: MOSI is set on rising edge of clock
  118. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
  119. }
  120. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY);
  121. //clear Dual or Quad lines transmission mode
  122. CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE);
  123. spi_set_clkdiv(spi_no, clock_div);
  124. if(spi_no==SPI_SPI){
  125. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
  126. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
  127. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
  128. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
  129. }
  130. else if(spi_no==SPI_HSPI){
  131. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
  132. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
  133. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
  134. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode
  135. }
  136. }
  137. void spi_mast_byte_order(uint8 spi_no, uint8 order)
  138. {
  139. if(spi_no > 1)
  140. return;
  141. if (order == SPI_ORDER_MSB) {
  142. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER | SPI_WR_BYTE_ORDER);
  143. } else if (order == SPI_ORDER_LSB) {
  144. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER | SPI_WR_BYTE_ORDER);
  145. }
  146. }
  147. /******************************************************************************
  148. * FunctionName : spi_mast_blkset
  149. * Description : Copy a block of data to the MOSI FIFO
  150. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  151. * size_t bitlen - number of bits to copy, multiple of 8
  152. * uint8 *data - pointer to data buffer
  153. *******************************************************************************/
  154. void spi_mast_blkset(uint8 spi_no, size_t bitlen, const uint8 *data)
  155. {
  156. size_t aligned_len = bitlen >> 3;
  157. while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
  158. if (aligned_len % 4) {
  159. // length for memcpy needs to be aligned to uint32 bounday
  160. // otherwise single byte writes are issued to the register and corrupt data
  161. aligned_len += 4 - (aligned_len % 4);
  162. }
  163. os_memcpy((void *)SPI_W0(spi_no), (const void *)data, aligned_len);
  164. }
  165. /******************************************************************************
  166. * FunctionName : spi_mast_blkget
  167. * Description : Copy a block of data from the MISO FIFO
  168. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  169. * size_t bitlen - number of bits to copy, multiple of 8
  170. * uint8 *data - pointer to data buffer, the buffer must be able to
  171. * accept a multiple of 4*8 bits
  172. *******************************************************************************/
  173. void spi_mast_blkget(uint8 spi_no, size_t bitlen, uint8 *data)
  174. {
  175. size_t aligned_len = bitlen >> 3;
  176. while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
  177. if (aligned_len % 4) {
  178. // length for memcpy needs to be aligned to uint32 bounday
  179. // otherwise single byte reads are issued to the register and corrupt data
  180. aligned_len += 4 - (aligned_len % 4);
  181. }
  182. os_memcpy((void *)data, (void *)SPI_W0(spi_no), aligned_len);
  183. }
  184. static uint32 swap_endianess(uint32 n)
  185. {
  186. return ((n & 0xff) << 24) |
  187. ((n & 0xff00) << 8) |
  188. ((n & 0xff0000UL) >> 8) |
  189. ((n & 0xff000000UL) >> 24);
  190. }
  191. /******************************************************************************
  192. * FunctionName : spi_mast_set_mosi
  193. * Description : Enter provided data into MOSI buffer.
  194. * The data is regarded as a sequence of bits with length 'bitlen'.
  195. * It will be written left-aligned starting from position 'offset'.
  196. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  197. * uint16 offset - offset into MOSI buffer (number of bits)
  198. * uint8 bitlen - valid number of bits in data
  199. * uint32 data - data to be written into buffer
  200. *******************************************************************************/
  201. void spi_mast_set_mosi(uint8 spi_no, uint16 offset, uint8 bitlen, uint32 data)
  202. {
  203. spi_buf_t spi_buf;
  204. uint8 wn, shift;
  205. if (spi_no > 1)
  206. return; // handle invalid input number
  207. if (bitlen > 32)
  208. return; // handle invalid input number
  209. // determine which SPI_Wn register is addressed
  210. wn = offset >> 5;
  211. if (wn > 15) {
  212. return; // out of range
  213. }
  214. while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
  215. // transfer Wn to buf
  216. spi_buf.word[1] = READ_PERI_REG(SPI_W0(spi_no) + wn*4);
  217. spi_buf.word[1] = swap_endianess(spi_buf.word[1]);
  218. if (wn < 15) {
  219. spi_buf.word[0] = READ_PERI_REG(SPI_W0(spi_no) + (wn+1)*4);
  220. spi_buf.word[0] = swap_endianess(spi_buf.word[0]);
  221. }
  222. shift = 64 - (offset & 0x1f) - bitlen;
  223. spi_buf.dword &= ~((1ULL << bitlen)-1 << shift);
  224. spi_buf.dword |= (uint64)data << shift;
  225. if (wn < 15) {
  226. WRITE_PERI_REG(SPI_W0(spi_no) + (wn+1)*4, swap_endianess(spi_buf.word[0]));
  227. }
  228. WRITE_PERI_REG(SPI_W0(spi_no) + wn*4, swap_endianess(spi_buf.word[1]));
  229. return;
  230. }
  231. /******************************************************************************
  232. * FunctionName : spi_mast_get_miso
  233. * Description : Retrieve data from MISO buffer.
  234. * The data is regarded as a sequence of bits with length 'bitlen'.
  235. * It will be read starting left-aligned from position 'offset'.
  236. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  237. * uint16 offset - offset into MISO buffer (number of bits)
  238. * uint8 bitlen - requested number of bits in data
  239. *******************************************************************************/
  240. uint32 spi_mast_get_miso(uint8 spi_no, uint16 offset, uint8 bitlen)
  241. {
  242. uint8 wn;
  243. spi_buf_t spi_buf;
  244. uint32 result;
  245. if (spi_no > 1)
  246. return 0; // handle invalid input number
  247. // determine which SPI_Wn register is addressed
  248. wn = offset >> 5;
  249. if (wn > 15)
  250. return 0; // out of range
  251. while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
  252. // transfer Wn to buf
  253. spi_buf.word[1] = READ_PERI_REG(SPI_W0(spi_no) + wn*4);
  254. spi_buf.word[1] = swap_endianess(spi_buf.word[1]);
  255. if (wn < 15) {
  256. spi_buf.word[0] = READ_PERI_REG(SPI_W0(spi_no) + (wn+1)*4);
  257. spi_buf.word[0] = swap_endianess(spi_buf.word[0]);
  258. }
  259. result = (uint32)(spi_buf.dword >> (64 - ((offset & 0x1f) + bitlen)));
  260. result &= (1UL << bitlen)-1;
  261. return result;
  262. }
  263. /******************************************************************************
  264. * FunctionName : spi_mast_transaction
  265. * Description : Start a transaction and wait for completion.
  266. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  267. * uint8 cmd_bitlen - Valid number of bits in cmd_data.
  268. * uint16 cmd_data - Command data.
  269. * uint8 addr_bitlen - Valid number of bits in addr_data.
  270. * uint32 addr_data - Address data.
  271. * uint16 mosi_bitlen - Valid number of bits in MOSI buffer.
  272. * uint8 dummy_bitlen - Number of dummy cycles.
  273. * sint16 miso_bitlen - number of bits to be captured in MISO buffer.
  274. * negative value activates full-duplex mode.
  275. *******************************************************************************/
  276. void spi_mast_transaction(uint8 spi_no, uint8 cmd_bitlen, uint16 cmd_data, uint8 addr_bitlen, uint32 addr_data,
  277. uint16 mosi_bitlen, uint8 dummy_bitlen, sint16 miso_bitlen)
  278. {
  279. if (spi_no > 1)
  280. return; // handle invalid input number
  281. while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
  282. // default disable COMMAND, ADDR, MOSI, DUMMY, MISO, and DOUTDIN (aka full-duplex)
  283. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND|SPI_USR_ADDR|SPI_USR_MOSI|SPI_USR_DUMMY|SPI_USR_MISO|SPI_DOUTDIN);
  284. // default set bit lengths
  285. WRITE_PERI_REG(SPI_USER1(spi_no),
  286. ((addr_bitlen - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
  287. ((mosi_bitlen - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
  288. ((dummy_bitlen - 1) & SPI_USR_DUMMY_CYCLELEN) << SPI_USR_DUMMY_CYCLELEN_S |
  289. ((miso_bitlen - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S);
  290. // handle the transaction components
  291. if (cmd_bitlen > 0)
  292. {
  293. uint16 cmd = cmd_data << (16 - cmd_bitlen); // align to MSB
  294. cmd = (cmd >> 8) | (cmd << 8); // swap byte order
  295. WRITE_PERI_REG(SPI_USER2(spi_no),
  296. ((cmd_bitlen - 1 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
  297. (cmd & SPI_USR_COMMAND_VALUE));
  298. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND);
  299. }
  300. if (addr_bitlen > 0)
  301. {
  302. WRITE_PERI_REG(SPI_ADDR(spi_no), addr_data << (32 - addr_bitlen));
  303. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_ADDR);
  304. }
  305. if (mosi_bitlen > 0)
  306. {
  307. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
  308. }
  309. if (dummy_bitlen > 0)
  310. {
  311. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_DUMMY);
  312. }
  313. if (miso_bitlen > 0)
  314. {
  315. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
  316. }
  317. else if (miso_bitlen < 0)
  318. {
  319. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN);
  320. }
  321. // start transaction
  322. SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
  323. while(READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR);
  324. }
  325. /******************************************************************************
  326. * FunctionName : spi_byte_write_espslave
  327. * Description : SPI master 1 byte transmission function for esp8266 slave,
  328. * transmit 1byte data to esp8266 slave buffer needs 16bit transmission ,
  329. * first byte is command 0x04 to write slave buffer, second byte is data
  330. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  331. * uint8 data- transmitted data
  332. *******************************************************************************/
  333. void spi_byte_write_espslave(uint8 spi_no,uint8 data)
  334. {
  335. uint32 regvalue;
  336. if(spi_no>1) return; //handle invalid input number
  337. while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR);
  338. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
  339. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_DUMMY);
  340. //SPI_FLASH_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1,
  341. // bit15-0 is cmd value.
  342. //0x70000000 is for 8bits cmd, 0x04 is eps8266 slave write cmd value
  343. WRITE_PERI_REG(SPI_USER2(spi_no),
  344. ((7&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|4);
  345. WRITE_PERI_REG(SPI_W0(spi_no), (uint32)(data));
  346. SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
  347. }
  348. /******************************************************************************
  349. * FunctionName : spi_byte_read_espslave
  350. * Description : SPI master 1 byte read function for esp8266 slave,
  351. * read 1byte data from esp8266 slave buffer needs 16bit transmission ,
  352. * first byte is command 0x06 to read slave buffer, second byte is recieved data
  353. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  354. * uint8* data- recieved data address
  355. *******************************************************************************/
  356. void spi_byte_read_espslave(uint8 spi_no,uint8 *data)
  357. {
  358. uint32 regvalue;
  359. if(spi_no>1) return; //handle invalid input number
  360. while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR);
  361. SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
  362. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI|SPI_USR_ADDR|SPI_USR_DUMMY);
  363. //SPI_FLASH_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1,
  364. // bit15-0 is cmd value.
  365. //0x70000000 is for 8bits cmd, 0x06 is eps8266 slave read cmd value
  366. WRITE_PERI_REG(SPI_USER2(spi_no),
  367. ((7&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|6);
  368. SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
  369. while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR);
  370. *data=(uint8)(READ_PERI_REG(SPI_W0(spi_no))&0xff);
  371. }
  372. /******************************************************************************
  373. * FunctionName : spi_slave_init
  374. * Description : SPI slave mode initial funtion, including mode setting,
  375. * IO setting, transmission interrupt opening, interrupt function registration
  376. * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
  377. *******************************************************************************/
  378. void spi_slave_init(uint8 spi_no)
  379. {
  380. uint32 regvalue;
  381. if(spi_no>1)
  382. return; //handle invalid input number
  383. //clear bit9,bit8 of reg PERIPHS_IO_MUX
  384. //bit9 should be cleared when HSPI clock doesn't equal CPU clock
  385. //bit8 should be cleared when SPI clock doesn't equal CPU clock
  386. ////WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); //clear bit9//TEST
  387. if(spi_no==SPI_SPI){
  388. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
  389. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
  390. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
  391. PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
  392. }else if(spi_no==SPI_HSPI){
  393. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
  394. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
  395. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
  396. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode
  397. }
  398. //regvalue=READ_PERI_REG(SPI_FLASH_SLAVE(spi_no));
  399. //slave mode,slave use buffers which are register "SPI_FLASH_C0~C15", enable trans done isr
  400. //set bit 30 bit 29 bit9,bit9 is trans done isr mask
  401. SET_PERI_REG_MASK( SPI_SLAVE(spi_no),
  402. SPI_SLAVE_MODE|SPI_SLV_WR_RD_BUF_EN|
  403. SPI_SLV_WR_BUF_DONE_EN|SPI_SLV_RD_BUF_DONE_EN|
  404. SPI_SLV_WR_STA_DONE_EN|SPI_SLV_RD_STA_DONE_EN|
  405. SPI_TRANS_DONE_EN);
  406. //disable general trans intr
  407. //CLEAR_PERI_REG_MASK(SPI_SLAVE(spi_no),SPI_TRANS_DONE_EN);
  408. CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);//disable flash operation mode
  409. SET_PERI_REG_MASK(SPI_USER(spi_no),SPI_USR_MISO_HIGHPART);//SLAVE SEND DATA BUFFER IN C8-C15
  410. //////**************RUN WHEN SLAVE RECIEVE*******************///////
  411. //tow lines below is to configure spi timing.
  412. SET_PERI_REG_MASK(SPI_CTRL2(spi_no),(0x2&SPI_MOSI_DELAY_NUM)<<SPI_MOSI_DELAY_NUM_S) ;//delay num
  413. os_printf("SPI_CTRL2 is %08x\n",READ_PERI_REG(SPI_CTRL2(spi_no)));
  414. WRITE_PERI_REG(SPI_CLOCK(spi_no), 0);
  415. /////***************************************************//////
  416. //set 8 bit slave command length, because slave must have at least one bit addr,
  417. //8 bit slave+8bit addr, so master device first 2 bytes can be regarded as a command
  418. //and the following bytes are datas,
  419. //32 bytes input wil be stored in SPI_FLASH_C0-C7
  420. //32 bytes output data should be set to SPI_FLASH_C8-C15
  421. WRITE_PERI_REG(SPI_USER2(spi_no), (0x7&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S); //0x70000000
  422. //set 8 bit slave recieve buffer length, the buffer is SPI_FLASH_C0-C7
  423. //set 8 bit slave status register, which is the low 8 bit of register "SPI_FLASH_STATUS"
  424. SET_PERI_REG_MASK(SPI_SLAVE1(spi_no), ((0xff&SPI_SLV_BUF_BITLEN)<< SPI_SLV_BUF_BITLEN_S)|
  425. ((0x7&SPI_SLV_STATUS_BITLEN)<<SPI_SLV_STATUS_BITLEN_S)|
  426. ((0x7&SPI_SLV_WR_ADDR_BITLEN)<<SPI_SLV_WR_ADDR_BITLEN_S)|
  427. ((0x7&SPI_SLV_RD_ADDR_BITLEN)<<SPI_SLV_RD_ADDR_BITLEN_S));
  428. SET_PERI_REG_MASK(SPI_PIN(spi_no),BIT19);//BIT19
  429. //maybe enable slave transmission liston
  430. SET_PERI_REG_MASK(SPI_CMD(spi_no),SPI_USR);
  431. //register level2 isr function, which contains spi, hspi and i2s events
  432. ETS_SPI_INTR_ATTACH(spi_slave_isr_handler,NULL);
  433. //enable level2 isr, which contains spi, hspi and i2s events
  434. ETS_SPI_INTR_ENABLE();
  435. }
  436. /* =============================================================================================
  437. * code below is for spi slave r/w testcase with 2 r/w state lines connected to the spi master mcu
  438. * replace with your own process functions
  439. * find "add system_os_post here" in spi_slave_isr_handler.
  440. * =============================================================================================
  441. */
  442. #ifdef SPI_SLAVE_DEBUG
  443. #include "pm/swtimer.h"
  444. /******************************************************************************
  445. * FunctionName : hspi_master_readwrite_repeat
  446. * Description : SPI master test function for reading and writing esp8266 slave buffer,
  447. the function uses HSPI module
  448. *******************************************************************************/
  449. os_timer_t timer2;
  450. void hspi_master_readwrite_repeat(void)
  451. {
  452. static uint8 data=0;
  453. uint8 temp;
  454. os_timer_disarm(&timer2);
  455. spi_byte_read_espslave(SPI_HSPI,&temp);
  456. temp++;
  457. spi_byte_write_espslave(SPI_HSPI,temp);
  458. os_timer_setfn(&timer2, (os_timer_func_t *)hspi_master_readwrite_repeat, NULL);
  459. SWTIMER_REGISTER_CB_PTR(hspi_master_readwrite_repeat, SWTIMER_RESUME);
  460. //hspi_master_readwrite_repeat timer will be resumed on wake up, maybe data will still be in buffer?
  461. os_timer_arm(&timer2, 500, 0);
  462. }
  463. #endif
  464. /******************************************************************************
  465. * FunctionName : spi_slave_isr_handler
  466. * Description : SPI interrupt function, SPI HSPI and I2S interrupt can trig this function
  467. some basic operation like clear isr flag has been done,
  468. and it is availible for adding user coder in the funtion
  469. * Parameters : void *para- function parameter address, which has been registered in function spi_slave_init
  470. *******************************************************************************/
  471. #include "gpio.h"
  472. #include "user_interface.h"
  473. #include "mem.h"
  474. static uint8 spi_data[32] = {0};
  475. static uint8 idx = 0;
  476. static uint8 spi_flg = 0;
  477. #define SPI_MISO
  478. #define SPI_QUEUE_LEN 8
  479. os_event_t * spiQueue;
  480. #define MOSI 0
  481. #define MISO 1
  482. #define STATUS_R_IN_WR 2
  483. #define STATUS_W 3
  484. #define TR_DONE_ALONE 4
  485. #define WR_RD 5
  486. #define DATA_ERROR 6
  487. #define STATUS_R_IN_RD 7
  488. //init the two intr line of slave
  489. //gpio0: wr_ready ,and
  490. //gpio2: rd_ready , controlled by slave
  491. void ICACHE_FLASH_ATTR
  492. gpio_init()
  493. {
  494. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
  495. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
  496. //PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
  497. GPIO_OUTPUT_SET(0, 1);
  498. GPIO_OUTPUT_SET(2, 0);
  499. //GPIO_OUTPUT_SET(4, 1);
  500. }
  501. void spi_slave_isr_handler(void *para)
  502. {
  503. uint32 regvalue,calvalue;
  504. static uint8 state =0;
  505. uint32 recv_data,send_data;
  506. if(READ_PERI_REG(0x3ff00020)&BIT4){
  507. //following 3 lines is to clear isr signal
  508. CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI_SPI), 0x3ff);
  509. }else if(READ_PERI_REG(0x3ff00020)&BIT7){ //bit7 is for hspi isr,
  510. regvalue=READ_PERI_REG(SPI_SLAVE(SPI_HSPI));
  511. CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI),
  512. SPI_TRANS_DONE_EN|
  513. SPI_SLV_WR_STA_DONE_EN|
  514. SPI_SLV_RD_STA_DONE_EN|
  515. SPI_SLV_WR_BUF_DONE_EN|
  516. SPI_SLV_RD_BUF_DONE_EN);
  517. SET_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI), SPI_SYNC_RESET);
  518. CLEAR_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI),
  519. SPI_TRANS_DONE|
  520. SPI_SLV_WR_STA_DONE|
  521. SPI_SLV_RD_STA_DONE|
  522. SPI_SLV_WR_BUF_DONE|
  523. SPI_SLV_RD_BUF_DONE);
  524. SET_PERI_REG_MASK(SPI_SLAVE(SPI_HSPI),
  525. SPI_TRANS_DONE_EN|
  526. SPI_SLV_WR_STA_DONE_EN|
  527. SPI_SLV_RD_STA_DONE_EN|
  528. SPI_SLV_WR_BUF_DONE_EN|
  529. SPI_SLV_RD_BUF_DONE_EN);
  530. if(regvalue&SPI_SLV_WR_BUF_DONE){
  531. GPIO_OUTPUT_SET(0, 0);
  532. idx=0;
  533. while(idx<8){
  534. recv_data=READ_PERI_REG(SPI_W0(SPI_HSPI)+(idx<<2));
  535. spi_data[idx<<2] = recv_data&0xff;
  536. spi_data[(idx<<2)+1] = (recv_data>>8)&0xff;
  537. spi_data[(idx<<2)+2] = (recv_data>>16)&0xff;
  538. spi_data[(idx<<2)+3] = (recv_data>>24)&0xff;
  539. idx++;
  540. }
  541. //add system_os_post here
  542. GPIO_OUTPUT_SET(0, 1);
  543. }
  544. if(regvalue&SPI_SLV_RD_BUF_DONE){
  545. //it is necessary to call GPIO_OUTPUT_SET(2, 1), when new data is preped in SPI_W8-15 and needs to be sended.
  546. GPIO_OUTPUT_SET(2, 0);
  547. //add system_os_post here
  548. //system_os_post(USER_TASK_PRIO_1,WR_RD,regvalue);
  549. }
  550. }else if(READ_PERI_REG(0x3ff00020)&BIT9){ //bit7 is for i2s isr,
  551. }
  552. }
  553. #ifdef SPI_SLAVE_DEBUG
  554. void ICACHE_FLASH_ATTR
  555. set_miso_data()
  556. {
  557. if(GPIO_INPUT_GET(2)==0){
  558. WRITE_PERI_REG(SPI_W8(SPI_HSPI),0x05040302);
  559. WRITE_PERI_REG(SPI_W9(SPI_HSPI),0x09080706);
  560. WRITE_PERI_REG(SPI_W10(SPI_HSPI),0x0d0c0b0a);
  561. WRITE_PERI_REG(SPI_W11(SPI_HSPI),0x11100f0e);
  562. WRITE_PERI_REG(SPI_W12(SPI_HSPI),0x15141312);
  563. WRITE_PERI_REG(SPI_W13(SPI_HSPI),0x19181716);
  564. WRITE_PERI_REG(SPI_W14(SPI_HSPI),0x1d1c1b1a);
  565. WRITE_PERI_REG(SPI_W15(SPI_HSPI),0x21201f1e);
  566. GPIO_OUTPUT_SET(2, 1);
  567. }
  568. }
  569. void ICACHE_FLASH_ATTR
  570. disp_spi_data()
  571. {
  572. uint8 i = 0;
  573. for(i=0;i<32;i++){
  574. os_printf("data %d : 0x%02x\n\r",i,spi_data[i]);
  575. }
  576. //os_printf("d31:0x%02x\n\r",spi_data[31]);
  577. }
  578. void ICACHE_FLASH_ATTR
  579. spi_task(os_event_t *e)
  580. {
  581. uint8 data;
  582. switch(e->sig){
  583. case MOSI:
  584. disp_spi_data();
  585. break;
  586. case STATUS_R_IN_WR :
  587. os_printf("SR ERR in WRPR,Reg:%08x \n",e->par);
  588. break;
  589. case STATUS_W:
  590. os_printf("SW ERR,Reg:%08x\n",e->par);
  591. break;
  592. case TR_DONE_ALONE:
  593. os_printf("TD ALO ERR,Reg:%08x\n",e->par);
  594. break;
  595. case WR_RD:
  596. os_printf("WR&RD ERR,Reg:%08x\n",e->par);
  597. break;
  598. case DATA_ERROR:
  599. os_printf("Data ERR,Reg:%08x\n",e->par);
  600. break;
  601. case STATUS_R_IN_RD :
  602. os_printf("SR ERR in RDPR,Reg:%08x\n",e->par);
  603. break;
  604. default:
  605. break;
  606. }
  607. }
  608. void ICACHE_FLASH_ATTR
  609. spi_task_init(void)
  610. {
  611. spiQueue = (os_event_t*)os_malloc(sizeof(os_event_t)*SPI_QUEUE_LEN);
  612. system_os_task(spi_task,USER_TASK_PRIO_1,spiQueue,SPI_QUEUE_LEN);
  613. }
  614. os_timer_t spi_timer_test;
  615. void ICACHE_FLASH_ATTR
  616. spi_test_init()
  617. {
  618. os_printf("spi init\n\r");
  619. spi_slave_init(SPI_HSPI);
  620. os_printf("gpio init\n\r");
  621. gpio_init();
  622. os_printf("spi task init \n\r");
  623. spi_task_init();
  624. #ifdef SPI_MISO
  625. os_printf("spi miso init\n\r");
  626. set_miso_data();
  627. #endif
  628. //os_timer_disarm(&spi_timer_test);
  629. //os_timer_setfn(&spi_timer_test, (os_timer_func_t *)set_miso_data, NULL);//wjl
  630. //os_timer_arm(&spi_timer_test,50,1);
  631. }
  632. #endif