transmit_i2s.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * SPDX-FileCopyrightText: 2019 Helmut Pozimski <helmut@pozimski.eu>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0-only
  5. */
  6. #include <freertos/FreeRTOS.h>
  7. #include <freertos/event_groups.h>
  8. #include <esp_event.h>
  9. #include <esp_wifi.h>
  10. #include <esp_log.h>
  11. #include <esp_event_loop.h>
  12. #include <driver/gpio.h>
  13. #include <driver/i2s.h>
  14. #include <lwip/sockets.h>
  15. #include <soc/io_mux_reg.h>
  16. #include <nvs_flash.h>
  17. #include <string.h>
  18. #include "wifi_credentials.h"
  19. #include "configuration.h"
  20. #define WIFI_LOG_PREFIX "Wifi"
  21. #define TCP_LOG_PREFIX "TCP"
  22. // Mapping of board pins to the functions they are used for
  23. #define MD1 16
  24. #define MD0 17
  25. #define MD 18
  26. #define MC 19
  27. #define MS 21
  28. #define SLAVE_DATA_IN 27
  29. #define SLAVE_BCK_IN 26
  30. #define SLAVE_WS_IN 25
  31. #define GPIO_OUTPUT_PIN_SEL ((1ULL<<MD0) |(1ULL<<MD1) | (1ULL<<MD) | (1ULL<<MC) | (1ULL<<MS))
  32. #define gpio_set(x,y) ESP_ERROR_CHECK(gpio_set_level(x,y))
  33. /* Bit sequence to send to the clock generator */
  34. #if SAMPLE_RATE == 8000
  35. static uint16_t pll_seq = 21518;
  36. #elif SAMPLE_RATE == 16000
  37. static uint16_t pll_seq = 17422;
  38. #elif SAMPLE_RATE == 32000
  39. static uint16_t pll_seq = 25614;
  40. #elif SAMPLE_RATE == 44100
  41. static uint16_t pll_seq = 41998;
  42. #elif SAMPLE_RATE == 48000
  43. static uint16_t pll_seq = 9230;
  44. #endif
  45. /* Event group for Wifi events */
  46. static EventGroupHandle_t wifi_event_group;
  47. /* Bit to signal that a connection to the AP has been establisched */
  48. const int WIFI_CONNECTED_BIT = BIT0 ;
  49. /* Structures to handle synchronisation with the server */
  50. typedef struct {
  51. uint32_t sample_rate;
  52. uint32_t bits_per_sample;
  53. } sync;
  54. typedef struct {
  55. char ack[4];
  56. sync dat;
  57. } sync_ack;
  58. /*
  59. * Function: wifi_event_handler
  60. * ----------------------------
  61. * Callback function that handles wifi events
  62. *
  63. * ctx: context from which the function was called
  64. * event: event that occured and should be handled
  65. *
  66. * returns: an error code
  67. */
  68. static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) {
  69. ESP_LOGI(WIFI_LOG_PREFIX, "Event handler called");
  70. if (event->event_id == SYSTEM_EVENT_STA_START) {
  71. ESP_LOGI(WIFI_LOG_PREFIX, "Wifi connection started");
  72. esp_wifi_connect();
  73. } else if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
  74. ESP_LOGI(WIFI_LOG_PREFIX, "Acquired IP address: %s",
  75. ip4addr_ntoa (&event->event_info.got_ip.ip_info.ip));
  76. xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
  77. } else if (event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
  78. ESP_LOGI(WIFI_LOG_PREFIX, "Connection lost");
  79. esp_wifi_connect();
  80. xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);
  81. }
  82. return ESP_OK;
  83. }
  84. /*
  85. * Function: configure_wifi
  86. * ------------------------
  87. * Configures the necessary parameters to establish a wifi connection
  88. */
  89. static void configure_wifi(void) {
  90. wifi_event_group = xEventGroupCreate();
  91. tcpip_adapter_init();
  92. ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL));
  93. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  94. ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  95. ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
  96. wifi_config_t wifi_config = {
  97. .sta = {
  98. .ssid = WIFI_AP,
  99. .password = WIFI_WPA_KEY
  100. },
  101. };
  102. ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  103. ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
  104. ESP_ERROR_CHECK(esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B |
  105. WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N));
  106. ESP_ERROR_CHECK(esp_wifi_set_bandwidth(ESP_IF_WIFI_STA, WIFI_BW_HT40));
  107. ESP_ERROR_CHECK(esp_wifi_start());
  108. }
  109. /*
  110. * Function: setup_gpio
  111. * --------------------
  112. * Configures the GPIO Pins that are used
  113. *
  114. * returns: error code of the configuration operation
  115. */
  116. static esp_err_t setup_gpio(void) {
  117. esp_err_t gpio_err;
  118. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_GPIO16);
  119. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_GPIO17);
  120. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO18_U, FUNC_GPIO18_GPIO18);
  121. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, FUNC_GPIO19_GPIO19);
  122. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO21_U, FUNC_GPIO21_GPIO21);
  123. gpio_config_t io_conf = {
  124. .intr_type = GPIO_INTR_DISABLE,
  125. .mode = GPIO_MODE_OUTPUT,
  126. .pin_bit_mask = GPIO_OUTPUT_PIN_SEL,
  127. .pull_down_en = 0,
  128. .pull_up_en = 0,
  129. };
  130. gpio_err = gpio_config(&io_conf);
  131. return gpio_err;
  132. }
  133. /*
  134. * Function pcm1808_config
  135. * --------------------------
  136. * Sets the MD0 and MD1 inputs for the pcm1808
  137. *
  138. * md1: value for input md1
  139. * md0: value for input md0
  140. */
  141. static void pcm1808_config(uint32_t md1, uint32_t md0) {
  142. gpio_set(MD1, md1);
  143. gpio_set(MD0, md0);
  144. }
  145. /* Function send_pll_bits
  146. * ----------------------
  147. * Sends a bit sequence to configure the PLL1708
  148. *
  149. * bits: 16 bit unsigned integer representing the bits to be send from right to left
  150. */
  151. static void send_pll_bits(uint16_t bits) {
  152. gpio_set(MS,0);
  153. gpio_set(MC,0);
  154. for (uint8_t i=16; i>0; i--) {
  155. vTaskDelay(100 / portTICK_PERIOD_MS);
  156. gpio_set(MD, bits & 1);
  157. bits = bits >>1;
  158. gpio_set(MC, 1);
  159. vTaskDelay(100 / portTICK_PERIOD_MS);
  160. gpio_set(MC, 0);
  161. }
  162. gpio_set(MS,1);
  163. }
  164. /*
  165. * Function: setup_i2s
  166. * -------------------
  167. * Initializes the i2s driver with the proper configuration
  168. */
  169. static void setup_i2s(void) {
  170. i2s_config_t i2s_config = {
  171. .mode = I2S_MODE_SLAVE | I2S_MODE_RX,
  172. .sample_rate = SAMPLE_RATE,
  173. .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
  174. .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
  175. .communication_format = I2S_COMM_FORMAT_I2S,
  176. .dma_buf_count = 35,
  177. .dma_buf_len = 256
  178. };
  179. i2s_pin_config_t pin_config = {
  180. .bck_io_num = SLAVE_BCK_IN,
  181. .ws_io_num = SLAVE_WS_IN,
  182. .data_in_num = SLAVE_DATA_IN,
  183. .data_out_num = I2S_PIN_NO_CHANGE
  184. };
  185. ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL));
  186. ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM_0, &pin_config));
  187. }
  188. /*
  189. * Function: transmit_task
  190. * Function that reads values from i2s and transmits them via TCP, it represents the main task
  191. *
  192. * pvParameters: parameters passed to the task
  193. */
  194. static void transmit_task(void *pvParameters) {
  195. send_pll_bits(pll_seq);
  196. struct sockaddr_in dest_addr;
  197. dest_addr.sin_addr.s_addr = inet_addr(TARGET_HOST);
  198. dest_addr.sin_family = AF_INET;
  199. dest_addr.sin_port = htons(TARGET_PORT);
  200. int sock = 0;
  201. void *transmit_buffer = malloc(1458);
  202. if (transmit_buffer == NULL) {
  203. ESP_LOGE("MALLOC", "Could not allocate memory for data buffer");
  204. }
  205. uint16_t offset = 0;
  206. unsigned int bytes_read;
  207. int err;
  208. sync sync_data = {
  209. .sample_rate = SAMPLE_RATE,
  210. .bits_per_sample = 24
  211. };
  212. sync_ack ack;
  213. while (1) {
  214. if (sock != 0) {
  215. close(sock);
  216. }
  217. sock = socket(dest_addr.sin_family, SOCK_STREAM, IPPROTO_IP);
  218. if (sock < 0) {
  219. ESP_LOGE(TCP_LOG_PREFIX, "Could not create socket");
  220. continue;
  221. }
  222. xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
  223. ESP_LOGI(TCP_LOG_PREFIX, "Establishing connection");
  224. err = connect(sock, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
  225. if (err != 0) {
  226. ESP_LOGE(TCP_LOG_PREFIX, "Failed to establish a TCP connection");
  227. continue;
  228. }
  229. send(sock, &sync_data, sizeof(sync_data), 0);
  230. recv(sock, &ack, sizeof(ack), 0);
  231. if ((strcmp(ack.ack, "ACK") !=0) || (ack.dat.sample_rate != SAMPLE_RATE) || (ack.dat.bits_per_sample != 24)) {
  232. ESP_LOGE(TCP_LOG_PREFIX, "Synchronisation with server not successful");
  233. continue;
  234. }
  235. ESP_LOGI(TCP_LOG_PREFIX, "Connection successfully established");
  236. uint8_t discard;
  237. while (1) {
  238. if (offset < 1458) {
  239. i2s_read(I2S_NUM_0, transmit_buffer + offset, 3, &bytes_read, portMAX_DELAY);
  240. offset += 3;
  241. i2s_read(I2S_NUM_0, &discard, 1, &bytes_read, portMAX_DELAY);
  242. }
  243. if (offset == 1458) {
  244. err = send(sock, transmit_buffer, 1458, 0);
  245. if (err < 0) {
  246. ESP_LOGE(TCP_LOG_PREFIX, "TCP connection lost");
  247. break;
  248. }
  249. offset = 0;
  250. }
  251. }
  252. }
  253. vTaskDelete(NULL);
  254. }
  255. /*
  256. * Function: app_main
  257. * ------------------
  258. * Entry function that sets up the main task and initializes everything
  259. */
  260. void app_main(void) {
  261. ESP_ERROR_CHECK(nvs_flash_init());
  262. configure_wifi();
  263. xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
  264. // Initialize GPIO pins
  265. ESP_ERROR_CHECK(setup_gpio());
  266. // Set PCM1808 configuration
  267. pcm1808_config(0, 1);
  268. // Power down PLL1708
  269. send_pll_bits(40974);
  270. // Initialize the i2s driver
  271. setup_i2s();
  272. xTaskCreate(transmit_task, "transmit_task", 4096, NULL, 7, NULL);
  273. }