spi.c 28 KB

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