main.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // Copyright 2021 IOsetting <iosetting(at)outlook.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * Example code of wireless audio transer with NRF24L01 module
  16. *
  17. * Pin connection:
  18. * 8H3K32S2/8H1K08 NRF24L01
  19. * P35(SS, Ignored) => CSN 16
  20. * P34(MOSI) => MOSI 15
  21. * P33(MISO) => MISO 14
  22. * P32(SPCLK) => CLK 13
  23. * P36(INT2) => IRQ 17
  24. * P37(IO) => CE 18
  25. *
  26. * TX: STC8H3K32S2 MAX9814
  27. * P11(ADC1) => MIC
  28. * 3.3V => VDD
  29. * 3.3V => GAIN
  30. * GND => A/R
  31. * GND => GND
  32. *
  33. * RX: STC8H1K08 PAM8403
  34. * P10(PWM1P) => 200R => L or R Input
  35. * GND => _|_ Input
  36. * Ext 3.3V/5V => VCC
  37. * Ext GND => GND
  38. *
  39. * Note:
  40. * 1. Use individual power supply for PAM8403
  41. * 2. Switch RX_ADDRESS and TX_ADDRESS in nrf24l01.c for RX and TX
  42. */
  43. #include "nrf24l01.h"
  44. //#include "voice.h"
  45. #include <stdio.h>
  46. #define BUFF_UNITS 8
  47. #define BUFF_SIZE (BUFF_UNITS * NRF24_PLOAD_WIDTH)
  48. const NRF24_SCEN CURRENT_SCEN = NRF24_SCEN_TX;
  49. extern uint16_t NRF24L01_rxsn;
  50. extern uint8_t *NRF24L01_xbuf_data;
  51. __XDATA uint8_t MAIN_buf[2][BUFF_SIZE] = {{0}};
  52. uint8_t MAIN_buf_index = 0, MAIN_buf_pos = 0,
  53. MAIN_ready_index = 0xFF,
  54. MAIN_txrx_index, MAIN_txrx_pos = 0;
  55. //uint16_t voice_pos = 0, voice_size = 10665;
  56. void ADC_Init(void)
  57. {
  58. // Set ADC1(GPIO P1.1) HIP
  59. GPIO_P1_SetMode(GPIO_Pin_1, GPIO_Mode_Input_HIP);
  60. // Channel: ADC1
  61. ADC_SetChannel(0x01);
  62. // ADC Clock = SYSCLK / 2 / (1+2) = SYSCLK / 6
  63. ADC_SetClockPrescaler(0x02);
  64. // Left alignment, high 8-bit in ADC_RES
  65. ADC_SetResultAlignmentLeft();
  66. // Enable interrupts
  67. EXTI_Global_SetIntState(HAL_State_ON);
  68. EXTI_ADC_SetIntState(HAL_State_ON);
  69. // Turn on ADC power
  70. ADC_SetPowerState(HAL_State_ON);
  71. }
  72. void SPI_Init(void)
  73. {
  74. // MISO(P33) MOSI(P34)
  75. GPIO_P3_SetMode(GPIO_Pin_4, GPIO_Mode_InOut_QBD);
  76. // SCLK(P32) CSN(P35) CE(P37)
  77. GPIO_P3_SetMode(GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_7, GPIO_Mode_Output_PP);
  78. // IRQ(P36)
  79. GPIO_P3_SetMode(GPIO_Pin_6, GPIO_Mode_Input_HIP);
  80. // ST7567 doesn't work if SPI frequency is too high
  81. SPI_SetClockPrescaler(SPI_ClockPreScaler_16);
  82. // Clock idles low
  83. SPI_SetClockPolarity(HAL_State_OFF);
  84. // Data transfer is driven by lower SS pin
  85. SPI_SetClockPhase(SPI_ClockPhase_LeadingEdge);
  86. // MSB first
  87. SPI_SetDataOrder(SPI_DataOrder_MSB);
  88. // Define the output pins
  89. SPI_SetPort(SPI_AlterPort_P35_P34_P33_P32);
  90. // Ignore SS pin, use MSTR to swith between master/slave mode
  91. SPI_IgnoreSlaveSelect(HAL_State_ON);
  92. // Master mode
  93. SPI_SetMasterMode(HAL_State_ON);
  94. // Start SPI
  95. SPI_SetEnabled(HAL_State_ON);
  96. }
  97. void PWM_Init()
  98. {
  99. // Set GPIO pins output mode P10 -> PWMA.1P
  100. GPIO_P1_SetMode(GPIO_Pin_0, GPIO_Mode_Output_PP);
  101. // Turn off PWMA.1 before change its mode
  102. PWMA_PWM1_SetPortState(HAL_State_OFF);
  103. PWMA_PWM1N_SetPortState(HAL_State_OFF);
  104. // Set PWMA.1 port direction output
  105. PWMA_PWM1_SetPortDirection(PWMB_PortDirOut);
  106. // Set PWMA.1 output low voltage when counter is less than target value
  107. PWMA_PWM1_ConfigOutputMode(PWM_OutputMode_PWM_HighIfLess);
  108. // Enable comparison value preload to make duty cycle changing smooth
  109. PWMA_PWM1_SetComparePreload(HAL_State_ON);
  110. // Turn on PWMA.1
  111. PWMA_PWM1_SetPortState(HAL_State_ON);
  112. // Set PWM frequency to 16kHz, Fpwm = SYSCLK / (PWMx_PSCR + 1) / (PWMx_ARR + 1)
  113. PWMA_SetPrescaler(8);
  114. // PWM width = Period + 1 (side alignment), or AutoReloadPeriod * 2 (center alignment)
  115. PWMA_SetPeriod(0xFF);
  116. // Counter direction, down:from [PWMA_ARRH,PWMA_ARRL] to 0
  117. PWMA_SetCounterDirection(PWM_CounterDirection_Down);
  118. // Enable preload on reload-period
  119. PWMA_SetAutoReloadPreload(HAL_State_ON);
  120. // Enable output on PWMA.1P
  121. PWMA_SetPinOutputState(PWM_Pin_1, HAL_State_ON);
  122. // Set PWMA.1 alternative ports to P1.0 and P1.1
  123. PWMA_PWM1_SetPort(PWMA_PWM1_AlterPort_P10_P11);
  124. // Enable overall output
  125. PWMA_SetOverallState(HAL_State_ON);
  126. // Start counter
  127. PWMA_SetCounterState(HAL_State_ON);
  128. }
  129. void Timer0_Init()
  130. {
  131. TIM_Timer0_Config(HAL_State_ON, TIM_TimerMode_16BitAuto, 8000);
  132. EXTI_Timer0_SetIntState(HAL_State_ON);
  133. EXTI_Timer0_SetIntPriority(EXTI_IntPriority_High);
  134. EXTI_Global_SetIntState(HAL_State_ON);
  135. TIM_Timer0_SetRunState(HAL_State_ON);
  136. }
  137. void INT_Init()
  138. {
  139. EXTI_Int2_SetIntState(HAL_State_ON);
  140. EXTI_Global_SetIntState(HAL_State_ON);
  141. }
  142. INTERRUPT(ADC_Routine, EXTI_VectADC)
  143. {
  144. ADC_ClearInterrupt();
  145. MAIN_buf[MAIN_buf_index][MAIN_buf_pos] = ADC_RES;
  146. if (MAIN_buf_pos == BUFF_SIZE - 1)
  147. {
  148. MAIN_buf_pos = 0;
  149. MAIN_ready_index = MAIN_buf_index;
  150. MAIN_buf_index = 1 - MAIN_buf_index;
  151. }
  152. else
  153. {
  154. MAIN_buf_pos++;
  155. }
  156. }
  157. INTERRUPT(Timer0_Routine, EXTI_VectTimer0)
  158. {
  159. uint8_t dc;
  160. if (CURRENT_SCEN == NRF24_SCEN_TX)
  161. {
  162. ADC_Start();
  163. // MAIN_buf[MAIN_buf_index][MAIN_buf_pos] = voice_bulk[voice_pos++];
  164. // if (MAIN_buf_pos == BUFF_SIZE - 1)
  165. // {
  166. // MAIN_buf_pos = 0;
  167. // MAIN_ready_index = MAIN_buf_index;
  168. // MAIN_buf_index = 1 - MAIN_buf_index;
  169. // }
  170. // else
  171. // {
  172. // MAIN_buf_pos++;
  173. // }
  174. // if (voice_pos == voice_size) voice_pos = 0;
  175. }
  176. else if (CURRENT_SCEN == NRF24_SCEN_RX)
  177. {
  178. if (MAIN_txrx_index == 0xFF)
  179. {
  180. if (MAIN_ready_index != 0xFF)
  181. {
  182. MAIN_txrx_index = MAIN_ready_index;
  183. MAIN_ready_index = 0xFF;
  184. MAIN_txrx_pos = 0;
  185. }
  186. }
  187. if (MAIN_txrx_index != 0xFF)
  188. {
  189. dc = MAIN_buf[MAIN_txrx_index][MAIN_txrx_pos];
  190. PWMA_PWM1_SetCaptureCompareValue(dc);
  191. // UART1_TxHex(dc);
  192. // if (MAIN_txrx_pos % 32 == 0)
  193. // {
  194. // UART1_TxString("\r\n");
  195. // }
  196. if (MAIN_txrx_pos == BUFF_SIZE - 1)
  197. {
  198. MAIN_txrx_index = 0xFF;
  199. if (MAIN_ready_index != 0xFF)
  200. {
  201. MAIN_txrx_index = MAIN_ready_index;
  202. MAIN_ready_index = 0xFF;
  203. MAIN_txrx_pos = 0;
  204. }
  205. }
  206. else
  207. {
  208. MAIN_txrx_pos++;
  209. }
  210. }
  211. }
  212. }
  213. INTERRUPT(Int2_Routine, EXTI_VectInt2)
  214. {
  215. uint8_t pipe_num, status, i, *j;
  216. status = NRF24L01_HandelIrqFlag();
  217. pipe_num = (status >> 1) & 0x07;
  218. if (pipe_num != 0x07)
  219. {
  220. i = NRF24_PLOAD_WIDTH;
  221. j = NRF24L01_xbuf_data;
  222. while (i--)
  223. {
  224. MAIN_buf[MAIN_buf_index][MAIN_buf_pos++] = *j++;
  225. }
  226. //UART1_TxHex(MAIN_buf_pos);
  227. if (MAIN_buf_pos == 0)
  228. {
  229. MAIN_ready_index = MAIN_buf_index;
  230. MAIN_buf_index = 1 - MAIN_buf_index;
  231. }
  232. }
  233. }
  234. void main(void)
  235. {
  236. uint8_t *tmp;
  237. uint8_t pos = 0, succ = 0, err = 0, i;
  238. SYS_SetClock();
  239. // UART1, baud 115200, baud source Timer1, 1T mode, no interrupt
  240. UART1_Config8bitUart(UART1_BaudSource_Timer1, HAL_State_ON, 115200);
  241. UART1_TxString("UART Initialized\r\n");
  242. SPI_Init();
  243. UART1_TxString("SPI Initialized\r\n");
  244. while (NRF24L01_Check() == 1)
  245. {
  246. UART1_TxString("Check failed\r\n");
  247. SYS_Delay(1000);
  248. }
  249. UART1_TxString("NRF24L01 Checked\r\n");
  250. switch (CURRENT_SCEN)
  251. {
  252. case NRF24_SCEN_TX:
  253. ADC_Init();
  254. UART1_TxString("ADC Initialized\r\n");
  255. Timer0_Init();
  256. UART1_TxString("Timer0 Initialized\r\n");
  257. NRF24L01_Init(NRF24_MODE_TX);
  258. UART1_TxString("NRF24L01 Initialized\r\n");
  259. while (1)
  260. {
  261. if (MAIN_ready_index != 0xFF)
  262. {
  263. MAIN_txrx_index = MAIN_ready_index;
  264. MAIN_ready_index = 0xFF;
  265. for (pos = 0; pos < BUFF_UNITS; pos++)
  266. {
  267. tmp = (uint8_t *)MAIN_buf[MAIN_txrx_index] + (pos * NRF24_PLOAD_WIDTH);
  268. // for (i = 0; i < 32; i++)
  269. // {
  270. // UART1_TxHex(*(tmp + i));
  271. // }
  272. // UART1_TxString("\r\n");
  273. if (NRF24L01_WriteFast(tmp) == 0)
  274. {
  275. NRF24L01_ResetTX();
  276. err++;
  277. }
  278. else
  279. {
  280. succ++;
  281. }
  282. if (err >= 255 || succ >= 255)
  283. {
  284. UART1_TxHex(err);
  285. UART1_TxHex(succ);
  286. UART1_TxString("\r\n");
  287. err = 0;
  288. succ = 0;
  289. }
  290. //SYS_Delay(1);
  291. }
  292. }
  293. }
  294. break;
  295. case NRF24_SCEN_RX:
  296. INT_Init();
  297. PWM_Init();
  298. Timer0_Init();
  299. UART1_TxString("Timer0 Initialized\r\n");
  300. NRF24L01_Init(NRF24_MODE_RX);
  301. while (1)
  302. {
  303. UART1_TxHex(NRF24L01_rxsn >> 8);
  304. UART1_TxHex(NRF24L01_rxsn & 0xFF);
  305. UART1_TxString("\r\n");
  306. SYS_Delay(1000);
  307. }
  308. break;
  309. case NRF24_SCEN_HALF_DUPLEX:
  310. NRF24L01_Init(NRF24_MODE_RX);
  311. INT_Init();
  312. while (1)
  313. {
  314. NRF24L01_Tx(tmp);
  315. SYS_Delay(1000);
  316. }
  317. break;
  318. default:
  319. UART1_TxString("Unknown scen\r\n");
  320. break;
  321. }
  322. }