ad0x0_spi2.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. #include "main.h"
  2. #include "ad0x0_spi2.h"
  3. #include "ad0x0_spi_ext.h"
  4. #include "../admisc/ad0x0_timman.h"
  5. #include "stm32f1xx_hal_spi.h"
  6. #include <string.h>
  7. /*не проебать
  8. SPE: SPI enable
  9. в ините врубаем это SPIX->CR2 |= (SPI_CR2_ERRIE);
  10. */
  11. #define SPIX ((SPI_TypeDef *)SPI2_BASE)
  12. //#undef AD0X0_SPI2_DBG
  13. //#define AD0X0_SPI2_DBG
  14. //ADQS == AD0x0 Queue Spi
  15. #define ADQS_SPI_EV_DISABLE SPIX->CR2 &= ~(SPI_CR2_TXEIE|SPI_CR2_RXNEIE);
  16. /*Хотелось бы выключить нахер пилу, которая идет в прерывание SPI
  17. Для этого события нужно включать только для команд предачи и выключать при операциях с очередью*/
  18. #define ADQS_SPI_EV_GETSTATE(LAST_STATE) LAST_STATE=SPIX->CR2 & (SPI_CR2_TXEIE|SPI_CR2_RXNEIE);
  19. #define ADQS_SPI_EV_SETSTATE(LAST_STATE) __disable_irq(); SPIX->CR2 &= ~(SPI_CR2_TXEIE|SPI_CR2_RXNEIE); SPIX->CR2 |= (LAST_STATE); __enable_irq();
  20. #define ADQS_SPI_EV_ENABLE SPIX->CR2 |= (SPI_CR2_TXEIE|SPI_CR2_RXNEIE);
  21. #define ADQS_SPI_DISABLE SPIX->CR1&= ~SPI_CR1_SPE;
  22. #define ADQS_SPI_ENABLE SPIX->CR1|= SPI_CR1_SPE;
  23. SPI_HandleTypeDef *phspi2=NULL;
  24. __weak void ad0x0_spi2_err_cb(void);
  25. void ad0x0_spi2_process(void);
  26. void ad0x0_spi2_err(void);
  27. void ad0x0_spi2_pop(void);
  28. void ad0x0_spi2_init_desc(void);
  29. struct ad0x0_spi_cmd_s ad0x0_spi2_fifo[AD0X0_SPI_FIFO_COUNT];
  30. volatile struct ad0x0_spi_cmd_s *ad0x0_spi2_pcurhwi=0,*ad0x0_spi2_pcurswi=0;
  31. ad0x0_spi_desc_s ad0x0_spi2_desc;
  32. volatile uint32_t ad0x0_spi2_last_HAL_RES=0, ad0x0_spi2_DMAERR_count=0;
  33. volatile uint32_t ad0x0_spi2_wait_cycles=0,ad0x0_spi2_wait_cycles_push=0;
  34. GPIO_TypeDef *AD_SPI2_DC_GPIO_Port=NULL, *AD_SPI2_RES_GPIO_Port=NULL,*AD_SPI2_NSS_GPIO_Port=NULL;
  35. uint16_t AD_SPI2_DC_Pin=0, AD_SPI2_RES_Pin=0, AD_SPI2_NSS_Pin=0;
  36. #ifdef AD0X0_DAMN_DBG
  37. //volatile int16_t c_enter_process=0,c_enter_ext=0;
  38. #endif
  39. uint32_t ad0x0_spi2_lhwitime(void){
  40. uint32_t t=(HAL_GetTick()<ad0x0_spi2_desc.last_hwi_process_tick)
  41. ?((uint64_t)HAL_GetTick()+UINT32_MAX-ad0x0_spi2_desc.last_hwi_process_tick)
  42. :(HAL_GetTick()-ad0x0_spi2_desc.last_hwi_process_tick);
  43. return t;
  44. }
  45. void ad0x0_spi2_push(ADQS_t _ctype,uint8_t _cbyte){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  46. #ifdef AD0X0_SPI2_DBG
  47. ADDBG2_HIGH;
  48. #endif
  49. uint32_t t=ad0x0_spi2_lhwitime();
  50. uint16_t ev_state;
  51. if(t>2){//ms
  52. /* if(ad0x0_spi2_pcurhwi->ctype==0x4B){
  53. ad0x0_spi2_pop();
  54. ad0x0_spi2_process();
  55. }*/
  56. }
  57. // while((I2CX->CR1 & I2C_CR1_STOP));//это единственный while, который НЕЗАМЕТНО срабатывает раз в час...
  58. if(ad0x0_spi2_pcurswi->ctype & ADQS_EMPTY){
  59. ADQS_SPI_EV_GETSTATE(ev_state);
  60. ADQS_SPI_EV_DISABLE;
  61. __disable_irq();
  62. ad0x0_spi2_pcurswi->ctype=_ctype;
  63. ad0x0_spi2_pcurswi->cbyte=_cbyte;
  64. ad0x0_spi2_pcurswi=ad0x0_spi2_pcurswi->pnext;
  65. __enable_irq();
  66. if((!(ad0x0_spi2_pcurhwi->ctype & ADQS_PROCESSED)) ){
  67. ad0x0_spi2_process();//
  68. }else ADQS_SPI_EV_SETSTATE(ev_state);
  69. //ADQS_SPI_EV_ENABLE;//решить!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  70. #ifdef AD0X0_SPI2_DBG
  71. ADDBG2_LOW;
  72. #endif
  73. return;
  74. }
  75. //ad0x0_spi2_pcurswi указывает на незанятый
  76. if(!(ad0x0_spi2_pcurswi->ctype & ADQS_EMPTY)){//если наткнулся на невыкинутый эл-т == очередь забита
  77. uint32_t c=10000000;
  78. ADQS_SPI_EV_ENABLE;
  79. while(!(ad0x0_spi2_pcurswi->ctype & ADQS_EMPTY) && c--){
  80. //__WFI();
  81. __asm("nop");__asm("nop");__asm("nop");__asm("nop");
  82. ad0x0_spi2_wait_cycles_push++;
  83. }
  84. if(!(ad0x0_spi2_pcurswi->ctype & ADQS_EMPTY)){
  85. ad0x0_spi2_err();
  86. }
  87. }
  88. ADQS_SPI_EV_GETSTATE(ev_state);
  89. ADQS_SPI_EV_DISABLE;
  90. __disable_irq();
  91. ad0x0_spi2_pcurswi->ctype=_ctype;
  92. ad0x0_spi2_pcurswi->cbyte=_cbyte;
  93. ad0x0_spi2_pcurswi=ad0x0_spi2_pcurswi->pnext;
  94. __enable_irq();
  95. if((!(ad0x0_spi2_pcurhwi->ctype & ADQS_PROCESSED)) ){
  96. ad0x0_spi2_process();
  97. }else ADQS_SPI_EV_SETSTATE(ev_state);
  98. //ADQS_SPI_EV_ENABLE;//решить!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  99. #ifdef AD0X0_SPI2_DBG
  100. ADDBG2_LOW;
  101. #endif
  102. }
  103. void ad0x0_spi2_pop(){//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  104. int was_masked=__disable_irq();
  105. if(!(ad0x0_spi2_pcurhwi->ctype & ADQS_PROCESSED)){
  106. //попытка выкинуть необработанный элемент
  107. if(!was_masked)__enable_irq();
  108. ad0x0_spi2_err();
  109. }
  110. ad0x0_spi2_pcurhwi->ctype|=0x80;//метим как выкинутую
  111. ad0x0_spi2_pcurhwi=ad0x0_spi2_pcurhwi->pnext;
  112. if(!was_masked)__enable_irq();
  113. }
  114. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  115. uint8_t ad0x0_spi2_get_ext_async(uint8_t *_p_out_handle,ad0x0_spi_ext_t **_p_out_desc){
  116. uint8_t r=0;
  117. uint32_t ne_hvataet_suka_cpp=10000000;
  118. r = ad0x0_spi_ext_get(_p_out_handle, _p_out_desc);
  119. while( (!r) && ne_hvataet_suka_cpp--){
  120. __enable_irq();
  121. ad0x0_spi2_wait_cycles++;
  122. ADQS_SPI_EV_ENABLE;
  123. r = ad0x0_spi_ext_get(_p_out_handle, _p_out_desc);
  124. }
  125. if(!r){
  126. ad0x0_spi2_err();//пересмотреть!!!!!!!!!!!!!!!!!! мож надо ждать
  127. }
  128. return 1;
  129. }
  130. uint8_t ad0x0_spi2_get_ext_async2(uint8_t *_p_out_handle,void **_p_out_spi_ext_t){
  131. uint8_t r=0;
  132. uint32_t ne_hvataet_suka_cpp=10000000;
  133. r = ad0x0_spi_ext_get(_p_out_handle, (ad0x0_spi_ext_t**)_p_out_spi_ext_t);
  134. while( (!r) && ne_hvataet_suka_cpp--){
  135. __enable_irq();
  136. ad0x0_spi2_wait_cycles++;
  137. ADQS_SPI_EV_ENABLE;
  138. r = ad0x0_spi_ext_get(_p_out_handle, (ad0x0_spi_ext_t**)_p_out_spi_ext_t);
  139. }
  140. if(!r){
  141. ad0x0_spi2_err();//пересмотреть!!!!!!!!!!!!!!!!!! мож надо ждать
  142. }
  143. return 1;
  144. }
  145. uint8_t ad0x0_spi2_get_ext_setbuf(uint8_t *_tx_pbuf,uint8_t *_rx_pbuf, uint8_t _count){
  146. //c_enter_ext++;
  147. uint8_t i;
  148. ad0x0_spi_ext_t *pf;
  149. ad0x0_spi2_get_ext_async(&i,&pf);
  150. // if(pf->pSetTXRXBuf ||pf->_p_cb_func|| pf->calls_count)ad0x0_spi2_err();//УБРАТЬ
  151. pf->pbuf_tx=_tx_pbuf;
  152. pf->pbuf_rx=_rx_pbuf;
  153. pf->pbuf_count=_count;
  154. pf->spi=SPIX;
  155. pf->p_pre_SetTXRXBuf=EXT_SetTXRXBuf;//ну я хз, пока делаем так... ПЕРЕДЕЛАТЬ!!!!!!
  156. return i;
  157. //ad0x0_spi2_push(ADQS_USE_EXT,i);
  158. //c_enter_ext--;
  159. }
  160. void ad0x0_spi2_push_txrx_dma_ext(uint8_t *_tx_pbuf,uint8_t *_rx_pbuf, uint8_t _count){
  161. //c_enter_ext++;
  162. ad0x0_spi2_push(ADQS_TXRX_PBUF_DMA_EXT,ad0x0_spi2_get_ext_setbuf(_tx_pbuf,_rx_pbuf,_count));
  163. //c_enter_ext--;
  164. }
  165. void ad0x0_spi2_push_tx_pbuf_ext(uint8_t *_tx_pbuf,uint8_t *_rx_pbuf, uint8_t _count){
  166. //c_enter_ext++;
  167. ad0x0_spi2_push(ADQS_TX_PBUF_EXT,ad0x0_spi2_get_ext_setbuf(_tx_pbuf,_rx_pbuf,_count));
  168. //c_enter_ext--;
  169. }
  170. void ad0x0_spi2_push_tx_pbuf_dma_ext(uint8_t *_tx_pbuf,uint8_t *_rx_pbuf, uint8_t _count){
  171. //c_enter_ext++;
  172. ad0x0_spi2_push(ADQS_TX_PBUF_DMA_EXT,ad0x0_spi2_get_ext_setbuf(_tx_pbuf,_rx_pbuf,_count));
  173. //c_enter_ext--;
  174. }
  175. void ad0x0_spi2_push_ext_setfunc(uint8_t _sf_id,void (*_p_cb_func)(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t)){
  176. //c_enter_ext++;
  177. uint8_t i;
  178. ad0x0_spi_ext_t *pf;
  179. ad0x0_spi2_get_ext_async(&i,&pf);
  180. pf->sf_id=_sf_id;
  181. pf->_p_post_cb_func=_p_cb_func;//ну я хз, пока делаем так... ПЕРЕДЕЛАТЬ!!!!!!
  182. pf->spi=SPIX;
  183. ad0x0_spi2_push(ADQS_USE_EXT,i);
  184. //c_enter_ext--;
  185. }
  186. uint8_t ad0x0_spi2_next(void){
  187. ad0x0_spi2_pop();
  188. if(!(ad0x0_spi2_pcurhwi->ctype & ADQS_EMPTY)){//(очередь не пустая)
  189. ad0x0_spi2_process();
  190. }
  191. return 1;
  192. }
  193. void ad0x0_spi2_process(void){
  194. //c_enter_process++;
  195. //тут мы шото меняем какие то флаги, а затем ждем прерывания для текущей команды
  196. #ifdef AD0X0_SPI2_DBG
  197. // ADDBG2_HIGH;
  198. #endif
  199. //если тип не впишится в свитч, то комнда либо отброшена, либо обработана ранее
  200. switch(ad0x0_spi2_pcurhwi->ctype){
  201. case ADQS_TX:
  202. __disable_irq();
  203. //I2CX->CR1 |= I2C_CR1_ACK;
  204. if(ad0x0_spi2_pcurhwi->cbyte==0x1b){
  205. __asm("nop");
  206. }
  207. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  208. SPIX->DR = ad0x0_spi2_pcurhwi->cbyte;
  209. __enable_irq();
  210. ADQS_SPI_EV_ENABLE;
  211. break;
  212. case ADQS_TX_PBUF:
  213. __disable_irq();
  214. #ifdef SPI2_NSS_GPIO_Port
  215. HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port,SPI2_NSS_Pin,GPIO_PIN_RESET);
  216. #endif
  217. ad0x0_spi2_desc.pbuf_counter_cur=ad0x0_spi2_desc.pbuf_counter;
  218. ad0x0_spi2_desc.tx_pbuf_cur=ad0x0_spi2_desc.tx_pbuf;
  219. ad0x0_spi2_desc.rx_pbuf_cur=0;
  220. //ad0x0_spi2_desc.pbuf_counter=ad0x0_spi2_pcurhwi->cbyte;
  221. SPIX->DR = *ad0x0_spi2_desc.tx_pbuf_cur++;
  222. ad0x0_spi2_desc.pbuf_counter_cur--;
  223. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  224. __enable_irq();
  225. ADQS_SPI_EV_ENABLE;
  226. break;
  227. case ADQS_TX_PBUF_EXT:
  228. __disable_irq();
  229. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_RESET);
  230. //ext - ф-я дма, в случае перезапуска не выполняется, т.к. буферы уже назначены
  231. if(!(ad0x0_spi2_pcurhwi->cbyte & 0x80)){
  232. ad0x0_spi_ext_pre_process(&ad0x0_spi2_desc,ad0x0_spi2_pcurhwi->cbyte);
  233. }
  234. ad0x0_spi2_desc.pbuf_counter_cur=ad0x0_spi2_desc.pbuf_counter;
  235. ad0x0_spi2_desc.tx_pbuf_cur=ad0x0_spi2_desc.tx_pbuf;
  236. ad0x0_spi2_desc.rx_pbuf_cur=0;
  237. //ad0x0_spi2_desc.pbuf_counter=ad0x0_spi2_pcurhwi->cbyte;
  238. SPIX->DR = *ad0x0_spi2_desc.tx_pbuf_cur++;
  239. ad0x0_spi2_desc.pbuf_counter_cur--;
  240. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  241. __enable_irq();
  242. ADQS_SPI_EV_ENABLE;
  243. break;
  244. case ADQS_TX_PBUF_DMA:
  245. __disable_irq();
  246. //ad0x0_spi2_desc.pbuf_counter=ad0x0_spi2_pcurhwi->cbyte;//все через EXT
  247. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  248. __enable_irq();
  249. ADQS_SPI_EV_DISABLE;
  250. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_RESET);
  251. if((!ad0x0_spi2_desc.pbuf_counter) || (!ad0x0_spi2_desc.tx_pbuf) )ad0x0_spi2_err();
  252. ad0x0_spi2_last_HAL_RES=HAL_SPI_Transmit_DMA(phspi2,(uint8_t*)ad0x0_spi2_desc.tx_pbuf,ad0x0_spi2_desc.pbuf_counter);
  253. //for (uint32_t i=0;i<1000000;i++)
  254. if(HAL_OK != ad0x0_spi2_last_HAL_RES){
  255. ad0x0_spi2_pcurhwi->ctype&=~ADQS_PROCESSED;//финт ушами,
  256. ad0x0_spi2_DMAERR_count++;
  257. ADQS_SPI_EV_ENABLE;
  258. }else break;
  259. if(HAL_OK != ad0x0_spi2_last_HAL_RES)ad0x0_spi2_err();
  260. break;
  261. case ADQS_TX_PBUF_DMA_EXT:
  262. __disable_irq();
  263. //ad0x0_spi2_desc.pbuf_counter=ad0x0_spi2_pcurhwi->cbyte;//все через EXT
  264. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  265. if(!(ad0x0_spi2_pcurhwi->cbyte & 0x80)){
  266. ad0x0_spi_ext_pre_process(&ad0x0_spi2_desc,ad0x0_spi2_pcurhwi->cbyte);
  267. }
  268. __enable_irq();
  269. ADQS_SPI_EV_DISABLE;
  270. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_RESET);
  271. if((!ad0x0_spi2_desc.pbuf_counter) || (!ad0x0_spi2_desc.tx_pbuf) )ad0x0_spi2_err();
  272. ad0x0_spi2_last_HAL_RES=HAL_SPI_Transmit_DMA(phspi2,(uint8_t*)ad0x0_spi2_desc.tx_pbuf,ad0x0_spi2_desc.pbuf_counter);
  273. //for (uint32_t i=0;i<1000000;i++)
  274. if(HAL_OK != ad0x0_spi2_last_HAL_RES){
  275. ad0x0_spi2_pcurhwi->ctype&=~ADQS_PROCESSED;//финт ушами,
  276. ad0x0_spi2_DMAERR_count++;
  277. ADQS_SPI_EV_ENABLE;
  278. }else break;
  279. if(HAL_OK != ad0x0_spi2_last_HAL_RES)ad0x0_spi2_err();
  280. break;
  281. case ADQS_TXRX_PBUF_DMA:
  282. __disable_irq();
  283. //тут дуализм сраный. сейчас байт данных не должен ни за что отвечать
  284. if(ad0x0_spi2_pcurhwi->cbyte)ad0x0_spi2_desc.pbuf_counter=ad0x0_spi2_pcurhwi->cbyte;
  285. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  286. __enable_irq();
  287. ADQS_SPI_EV_DISABLE;
  288. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_RESET);
  289. if((!ad0x0_spi2_desc.pbuf_counter) || (!ad0x0_spi2_desc.tx_pbuf) || (!ad0x0_spi2_desc.rx_pbuf) )ad0x0_spi2_err();
  290. ad0x0_spi2_last_HAL_RES=HAL_SPI_TransmitReceive_DMA(phspi2,(uint8_t*)ad0x0_spi2_desc.tx_pbuf,(uint8_t*)ad0x0_spi2_desc.rx_pbuf,ad0x0_spi2_desc.pbuf_counter);
  291. //for (uint32_t i=0;i<1000000;i++)
  292. if(HAL_OK != ad0x0_spi2_last_HAL_RES){
  293. ad0x0_spi2_pcurhwi->ctype&=~ADQS_PROCESSED;//финт ушами,
  294. ad0x0_spi2_DMAERR_count++;
  295. ADQS_SPI_EV_ENABLE;
  296. //NVIC_SetPendingIRQ(SPI2_IRQn);//ПЕРЕСМОТРЕТЬ
  297. }
  298. //if(ad0x0_spi2_DMAERR_count>100)ad0x0_spi2_err();//ПЕРЕСМОТРЕТЬ
  299. break;
  300. case ADQS_TXRX_PBUF_DMA_EXT:
  301. __disable_irq();
  302. //тут дуализм сраный. сейчас байт данных не должен ни за что отвечать
  303. if(ad0x0_spi2_pcurhwi->cbyte)ad0x0_spi2_desc.pbuf_counter=ad0x0_spi2_pcurhwi->cbyte;
  304. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  305. //ext - ф-я дма, в случае перезапуска не выполняется, т.к. буферы уже назначены
  306. if(!(ad0x0_spi2_pcurhwi->cbyte & 0x80)){
  307. ad0x0_spi_ext_pre_process(&ad0x0_spi2_desc,ad0x0_spi2_pcurhwi->cbyte);
  308. }
  309. __enable_irq();
  310. ADQS_SPI_EV_DISABLE;
  311. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_RESET);
  312. if((!ad0x0_spi2_desc.pbuf_counter) || (!ad0x0_spi2_desc.tx_pbuf) || (!ad0x0_spi2_desc.rx_pbuf) )ad0x0_spi2_err();
  313. ad0x0_spi2_last_HAL_RES=HAL_SPI_TransmitReceive_DMA(phspi2,(uint8_t*)ad0x0_spi2_desc.tx_pbuf,(uint8_t*)ad0x0_spi2_desc.rx_pbuf,ad0x0_spi2_desc.pbuf_counter);
  314. //for (uint32_t i=0;i<1000000;i++)
  315. if(HAL_OK != ad0x0_spi2_last_HAL_RES){
  316. ad0x0_spi2_pcurhwi->ctype&=~ADQS_PROCESSED;//финт ушами,
  317. ad0x0_spi2_DMAERR_count++;
  318. ADQS_SPI_EV_ENABLE;
  319. //NVIC_SetPendingIRQ(SPI2_IRQn);//ПЕРЕСМОТРЕТЬ
  320. }
  321. //if(ad0x0_spi2_DMAERR_count>100)ad0x0_spi2_err();//ПЕРЕСМОТРЕТЬ
  322. break;
  323. case ADQS_USE_EXT:
  324. __disable_irq();
  325. if(ad0x0_spi2_pcurhwi->ctype & ADQS_PROCESSED){__enable_irq();ad0x0_spi2_err();}
  326. else{
  327. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  328. ADQS_SPI_EV_ENABLE;//иначе очередь может остановиться и не просраться
  329. // ad0x0_spi2_pcurhwi->cbyte
  330. __enable_irq();
  331. uint8_t cb=ad0x0_spi2_pcurhwi->cbyte;
  332. ad0x0_spi2_pcurhwi->cbyte|=0x80;
  333. ad0x0_spi_ext_pre_process(&ad0x0_spi2_desc,cb);
  334. ad0x0_spi_ext_post_process(&ad0x0_spi2_desc,cb);
  335. ad0x0_spi2_next();//если здесь накидывается куча команд, то стэк это.. того...
  336. //v2
  337. /*ad0x0_spi2_pop();
  338. ADQS_SPI_EV_ENABLE;
  339. NVIC_SetPendingIRQ(SPI2_IRQn);*/
  340. //v3
  341. /*ad0x0_spi2_pop();
  342. if(!(ad0x0_spi2_pcurhwi->ctype & ADQS_EMPTY)){//(очередь не пустая)
  343. ad0x0_spi2_process();
  344. }*/
  345. }
  346. //__enable_irq();
  347. break;
  348. case ADQS_DELAY_MS:
  349. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  350. ad0x0_timman_add(ad0x0_spi2_pcurhwi->cbyte,ad0x0_spi2_next);
  351. break;
  352. case ADQS_ST7735_SET_DC:
  353. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  354. //если состояние пина не изменится, то выкидываем команду из очереди
  355. while(SPIX->SR & SPI_SR_BSY);
  356. if(ad0x0_spi2_pcurhwi->pnext->cbyte==0xC0){
  357. __asm("nop");
  358. }
  359. if(AD_SPI2_DC_GPIO_Port)HAL_GPIO_WritePin( AD_SPI2_DC_GPIO_Port,AD_SPI2_DC_Pin,ad0x0_spi2_pcurhwi->cbyte ? GPIO_PIN_SET : GPIO_PIN_RESET);
  360. ad0x0_spi2_next();
  361. break;
  362. case ADQS_ST7735_SET_CS:
  363. if(ad0x0_spi2_pcurhwi->cbyte){
  364. SPIX->CR1|= SPI_CR1_SSI;
  365. SPIX->CR1&=~SPI_CR1_SSM;//0: Software slave management disabled
  366. }else{
  367. SPIX->CR1&= ~SPI_CR1_SSI;
  368. SPIX->CR1|=SPI_CR1_SSM;//1: Software slave management enabled
  369. }
  370. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  371. ad0x0_spi2_next();
  372. break;
  373. case ADQS_ST7735_SET_RESET:
  374. if(AD_SPI2_RES_GPIO_Port)HAL_GPIO_WritePin( AD_SPI2_RES_GPIO_Port,AD_SPI2_RES_Pin,ad0x0_spi2_pcurhwi->cbyte ? GPIO_PIN_SET : GPIO_PIN_RESET);
  375. //HAL_GPIO_WritePin( AD_RES_GPIO_Port,AD_RES_Pin,ad0x0_spi2_pcurhwi->cbyte ? GPIO_PIN_SET : GPIO_PIN_RESET);
  376. ad0x0_spi2_pcurhwi->ctype|=ADQS_PROCESSED;//метим как обработанную
  377. ad0x0_spi2_next();
  378. break;
  379. default:
  380. ad0x0_spi2_err();
  381. }
  382. //c_enter_process--;
  383. #ifdef AD0X0_SPI2_DBG
  384. // ADDBG2_LOW;
  385. #endif
  386. }
  387. void ad0x0_spi2_irq_err(void){
  388. //я бы это не обрабатывал, если бы не пидорский гироскоп, который не прислал нак при адресе...
  389. //метим команду как необработанную и пробуем по новой
  390. uint8_t ctypex=ad0x0_spi2_pcurhwi->ctype;
  391. uint32_t sr=0;
  392. sr=SPIX->SR;//
  393. ad0x0_spi2_err();
  394. switch(ctypex & 0x3f){
  395. case ADQS_TX_PBUF_DMA:
  396. if(sr & SPI_SR_OVR){
  397. /*When the SPI is used only to transmit data, it is possible to enable only the SPI Tx DMA
  398. channel. In this case, the OVR flag is set because the data received are not read*/
  399. __ASM("nop");
  400. }
  401. break;
  402. default:
  403. ad0x0_spi2_err();
  404. }
  405. }
  406. void ad0x0_spi2_dma_err(void){
  407. //всякая херня случается, и... приводит как всегда к ad0x0_spi2_err();
  408. uint8_t ctypex=ad0x0_spi2_pcurhwi->ctype;
  409. ad0x0_spi2_err();
  410. }
  411. void ad0x0_spi2_dma(void){
  412. uint8_t ctypex=ad0x0_spi2_pcurhwi->ctype;
  413. switch(ctypex & 0x3f){
  414. case ADQS_TX_PBUF_DMA:
  415. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_SET);
  416. ad0x0_spi2_next();
  417. break;
  418. case ADQS_TXRX_PBUF_DMA:
  419. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_SET);
  420. //ad0x0_spi2_next();
  421. //v2 почему так? потому что начинает сыпаться ф-я хал с дма-передачей
  422. ad0x0_spi2_pop();
  423. NVIC_SetPendingIRQ(SPI2_IRQn);
  424. break;
  425. case ADQS_TX_PBUF_DMA_EXT:
  426. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_SET);
  427. if(!(ad0x0_spi2_pcurhwi->cbyte & 0x80)){
  428. ad0x0_spi_ext_post_process(&ad0x0_spi2_desc,ad0x0_spi2_pcurhwi->cbyte);
  429. ad0x0_spi2_pcurhwi->cbyte|=0x80;
  430. }
  431. //ad0x0_spi2_next();
  432. //v2 почему так? потому что начинает сыпаться ф-я хал с дма-передачей
  433. ad0x0_spi2_pop();
  434. NVIC_SetPendingIRQ(SPI2_IRQn);
  435. break;
  436. case ADQS_TXRX_PBUF_DMA_EXT:
  437. if(AD_SPI2_NSS_GPIO_Port)HAL_GPIO_WritePin(AD_SPI2_NSS_GPIO_Port,AD_SPI2_NSS_Pin,GPIO_PIN_SET);
  438. if(!(ad0x0_spi2_pcurhwi->cbyte & 0x80)){
  439. ad0x0_spi_ext_post_process(&ad0x0_spi2_desc,ad0x0_spi2_pcurhwi->cbyte);
  440. ad0x0_spi2_pcurhwi->cbyte|=0x80;
  441. }
  442. ad0x0_spi2_pop();
  443. NVIC_SetPendingIRQ(SPI2_IRQn);
  444. break;
  445. default:
  446. //}else{
  447. ad0x0_spi2_err();
  448. }
  449. }
  450. void ad0x0_spi2_irq(void)
  451. {
  452. /* In order to detect unexpected events during development,
  453. it is recommended to set a breakpoint on the following instruction.
  454. */
  455. ad0x0_spi2_desc.insint=1;
  456. ADS1_HIGH;
  457. /* для и2ц было так: когда генерится стоп, игнорим прерывания, для spi так не делаем
  458. if(I2CX->CR1 & I2C_CR1_STOP){
  459. #ifdef AD0X0_SPI2_DBG
  460. ADINT_LOW;
  461. #endif
  462. ad0x0_spi2_insint=0;
  463. return;
  464. }*/
  465. /**/
  466. uint32_t sr=SPIX->SR;//
  467. /*if(sr & SPI_SR_RXNE){
  468. uint8_t data=SPIX->DR;
  469. sr=SPIX->SR;
  470. }*/
  471. uint8_t ctypex=ad0x0_spi2_pcurhwi->ctype;
  472. if(!(ctypex & ADQS_PROCESSED)){//эл-т для которого не делался process
  473. if(!(ad0x0_spi2_pcurhwi->ctype & ADQS_EMPTY)){//(очередь не пустая)
  474. ad0x0_spi2_process();
  475. #ifdef AD0X0_SPI2_DBG
  476. ADINT_LOW;
  477. #endif
  478. ad0x0_spi2_desc.insint=0;
  479. return;
  480. }else ADQS_SPI_EV_DISABLE;
  481. }
  482. if(ctypex & ADQS_EMPTY){//уже обработанный эл-т...== пустая очередь
  483. #ifdef AD0X0_SPI2_DBG
  484. ADINT_LOW;
  485. #endif
  486. ADQS_SPI_EV_DISABLE;
  487. //ADQS_SPI_DISABLE;
  488. ad0x0_spi2_desc.insint=0;
  489. return;
  490. }
  491. switch(ctypex & 0x3f){
  492. case ADQS_TX:
  493. if(sr & SPI_SR_TXE){
  494. /*
  495. так не сработает, т.к. прерывание приходит пока байт передается,
  496. Зато работает с ДМА!!!
  497. #ifdef SPI2_NSS_GPIO_Port
  498. HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port,SPI2_NSS_Pin,GPIO_PIN_SET);
  499. #endif*/
  500. ad0x0_spi2_pop();
  501. if(!(ad0x0_spi2_pcurhwi->ctype & ADQS_EMPTY)){//(очередь не пустая)
  502. ad0x0_spi2_process();
  503. }
  504. }
  505. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  506. uint8_t d=SPIX->DR;
  507. }
  508. ADQS_SPI_EV_DISABLE;
  509. break;
  510. case ADQS_TX_PBUF:
  511. if(sr & SPI_SR_TXE)
  512. {
  513. if(ad0x0_spi2_desc.pbuf_counter_cur){
  514. __disable_irq();
  515. SPIX->DR = *ad0x0_spi2_desc.tx_pbuf_cur++;
  516. ad0x0_spi2_desc.pbuf_counter_cur--;
  517. __enable_irq();
  518. }else{
  519. ADQS_SPI_EV_DISABLE;
  520. ad0x0_spi2_next();
  521. }
  522. }
  523. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  524. uint8_t d=SPIX->DR;
  525. }
  526. //ADQS_SPI_EV_DISABLE;
  527. break;
  528. case ADQS_TX_PBUF_EXT:
  529. if(sr & SPI_SR_TXE)
  530. {
  531. if(ad0x0_spi2_desc.pbuf_counter_cur){
  532. __disable_irq();
  533. SPIX->DR = *ad0x0_spi2_desc.tx_pbuf_cur++;
  534. ad0x0_spi2_desc.pbuf_counter_cur--;
  535. __enable_irq();
  536. }else{
  537. ADQS_SPI_EV_DISABLE;
  538. if(!(ad0x0_spi2_pcurhwi->cbyte & 0x80)){
  539. ad0x0_spi_ext_post_process(&ad0x0_spi2_desc,ad0x0_spi2_pcurhwi->cbyte);
  540. ad0x0_spi2_pcurhwi->cbyte|=0x80;
  541. }
  542. ad0x0_spi2_next();
  543. }
  544. }
  545. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  546. uint8_t d=SPIX->DR;
  547. }
  548. //ADQS_SPI_EV_DISABLE;
  549. break;
  550. case ADQS_TX_PBUF_DMA:
  551. /* if(SPIX->CR2 & SPI_CR2_TXEIE){
  552. __asm("nop");
  553. }*/
  554. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  555. uint8_t d=SPIX->DR;
  556. }
  557. ADQS_SPI_EV_DISABLE;
  558. break;
  559. case ADQS_TX_PBUF_DMA_EXT:
  560. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  561. uint8_t d=SPIX->DR;
  562. }
  563. ADQS_SPI_EV_DISABLE;
  564. break;
  565. case ADQS_TXRX_PBUF_DMA:
  566. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  567. uint8_t d=SPIX->DR;//Clearing the RXNE bit is performed by reading the SPI_DR register.
  568. }
  569. ADQS_SPI_EV_DISABLE;
  570. break;
  571. case ADQS_TXRX_PBUF_DMA_EXT:
  572. if(sr & SPI_SR_RXNE){//ad0x0 09102020 проверить
  573. uint8_t d=SPIX->DR;//Clearing the RXNE bit is performed by reading the SPI_DR register.
  574. }
  575. ADQS_SPI_EV_DISABLE;
  576. break;
  577. case ADQS_DELAY_MS:
  578. ADQS_SPI_EV_DISABLE;
  579. break;
  580. case ADQS_ST7735_SET_DC:
  581. ADQS_SPI_EV_DISABLE;
  582. break;
  583. case ADQS_USE_EXT:
  584. ADQS_SPI_EV_DISABLE;
  585. break;
  586. default:
  587. //}else{
  588. ad0x0_spi2_err();
  589. }
  590. ad0x0_spi2_desc.insint=0;
  591. ADS1_LOW;
  592. }
  593. void ad0x0_spi2_initq(void){
  594. ad0x0_spi2_pcurhwi=ad0x0_spi2_pcurswi=ad0x0_spi2_fifo;
  595. ad0x0_spi2_fifo[AD0X0_SPI_FIFO_COUNT-1].pnext=ad0x0_spi2_fifo;
  596. ad0x0_spi2_fifo[AD0X0_SPI_FIFO_COUNT-1].ctype=ADQS_EMPTY;
  597. for(uint16_t i=0;i<=AD0X0_SPI_FIFO_COUNT-2;i++){
  598. ad0x0_spi2_fifo[i].pnext=ad0x0_spi2_fifo+i+1;
  599. ad0x0_spi2_fifo[i].ctype=ADQS_EMPTY;
  600. }
  601. // HAL_SPI_R
  602. }
  603. void ad0x0_spi2_err(void){
  604. ad0x0_err();
  605. }
  606. uint8_t ad0x0_spi2_is_queue_empty(void){
  607. return ((ad0x0_spi2_pcurhwi->ctype & ADQS_EMPTY) && (ad0x0_spi2_pcurhwi->pnext->ctype & ADQS_EMPTY) && !(SPIX->SR & SPI_SR_BSY));
  608. }
  609. void ad0x0_spi2_wait(void){
  610. uint16_t ev_state;
  611. ADQS_SPI_EV_GETSTATE(ev_state);
  612. while(!ad0x0_spi2_is_queue_empty()){ADQS_SPI_EV_ENABLE;}//!!!!!!!!!!ubrat' etot pizdets
  613. ADQS_SPI_EV_SETSTATE(ev_state);
  614. }
  615. void ad0x0_spi2_init(SPI_HandleTypeDef *_phspi2,GPIO_TypeDef *_LCD_DC_GPIO_Port,uint16_t _LCD_DC_Pin, GPIO_TypeDef *_LCD_RES_GPIO_Port,uint16_t _LCD_RES_Pin,
  616. GPIO_TypeDef *_NSS_GPIO_Port,uint16_t _NSS_Pin) {
  617. phspi2=_phspi2;
  618. AD_SPI2_DC_GPIO_Port=_LCD_DC_GPIO_Port;
  619. AD_SPI2_DC_Pin=_LCD_DC_Pin;
  620. AD_SPI2_RES_GPIO_Port=_LCD_RES_GPIO_Port;
  621. AD_SPI2_RES_Pin=_LCD_RES_Pin;
  622. AD_SPI2_NSS_GPIO_Port=_NSS_GPIO_Port;
  623. AD_SPI2_NSS_Pin=_NSS_Pin;
  624. SPIX->CR1|= SPI_CR1_SSM;//1: Software slave management enabled
  625. SPIX->CR1|= SPI_CR1_SSI;//The value of this bit is forced onto the NSS pin and the IO value of the NSS pin is ignored
  626. SPIX->CR2 |= (SPI_CR2_ERRIE);
  627. SPIX->CR1|=SPI_CR1_SPE;
  628. ad0x0_spi2_initq();
  629. ad0x0_spi2_init_desc();
  630. //pins configuing in cubemx...main.c
  631. }
  632. void ad0x0_spi2_init_desc(void){
  633. memset(&ad0x0_spi2_desc,0,sizeof(ad0x0_spi2_desc));
  634. ad0x0_spi2_desc.spix=SPIX;
  635. ad0x0_spi2_desc.perrfunc=ad0x0_spi2_err;
  636. }