ad0x0_spi1.c 27 KB

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