STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
main_http.c
Go to the documentation of this file.
1 
51 /* Includes ------------------------------------------------------------------*/
52 #include "main.h"
53 #include "lwip/netif.h"
54 #include "lwip/tcpip.h"
55 #include <lwip/sockets.h>
56 #include "cmsis_os.h"
57 #include "ethernetif.h"
58 #include "app_ethernet.h"
59 #include "lcd_log.h"
60 #include "httpserver-netconn.h"
61 
62 #include "udp.h"
63 #include "ip4.h"
64 #include "raw.h"
65 #include "init.h"
66 
67 /* Private typedef -----------------------------------------------------------*/
68 /* Private define ------------------------------------------------------------*/
69 /* Private macro -------------------------------------------------------------*/
70 /* Private variables ---------------------------------------------------------*/
71 struct netif gnetif; /* network interface structure */
72 struct netif gnetifUDANTE; /* network interface structure */
73 
74 /* Private function prototypes -----------------------------------------------*/
75 extern void SystemClock_Config(void);
76 extern void MPU_Config(void);
77 extern void CPU_CACHE_Enable(void);
78 
79 void StartHTTPDThread(void const * argument);
80 
81 #if 0
82 static void BSP_Config(void);
83 #endif
84 static void Netif_Config(void);
85 
86 /* Private functions ---------------------------------------------------------*/
87 
88 void http_taskCreate(void)
89 {
90  /* Init thread */
91  #if defined(__GNUC__)
93  #else
95  #endif
96 
97  osThreadCreate(osThread(Start), NULL);
98 }
99 
105 int main_http(void)
106 {
107  /* Configure the MPU attributes as Write Through */
108  MPU_Config();
109 
110  /* Enable the CPU Cache */
112 
113  /* STM32F7xx HAL library initialization:
114  - Configure the Flash ART accelerator on ITCM interface
115  - Configure the Systick to generate an interrupt each 1 msec
116  - Set NVIC Group Priority to 4
117  - Global MSP (MCU Support Package) initialization
118  */
119  HAL_Init();
120 
121  /* Configure the system clock to 200 MHz */
123 
124  /* Init thread */
125 #if 0
126 #if defined(__GNUC__)
128 #else
130 #endif
131 
132  osThreadCreate(osThread(Start), NULL);
133 #else
134  http_taskCreate();
135 #endif
136 
137  /* Start scheduler */
138  osKernelStart();
139 
140  /* We should never get here as control is now taken by the scheduler */
141  for( ;; );
142 
143  return 0;
144 }
145 
146 //PCBs for all the UDP ports we need (open some or all for all potential audio streams)
147 struct udp_pcb *pcb0;
148 #if 0
149 //we could open all potential UDP port, or just the one we found
150 struct udp_pcb *pcb1, *pcb2;
151 #endif
152 
153 //buffer for one network audio packet, as 24bit format
154 static unsigned char aBuf[48 * 2 * 3];
155 int recCnt = 0;
156 
157 void UDanteUDP_Receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
158 {
159  unsigned char *pAudio;
160 
161  unsigned char *paBuf;
162  u16_t len;
163 
164  //should we use a semaphore here? it is not reentrant, not thread-safe!
165  if (recCnt)
166  {
167  //error!
168  BSP_LED_On(LED1);
169  while (1) ;
170  }
171 
172  recCnt++;
173 
174  len = p->len;
175  if (len == 48 * 2 * 3 + 1 + 8)
176  {
177  //audio packet starts at: p + 1 + 8 (if without ETH header)
178  pAudio = (unsigned char *)p->payload;
179  pAudio += 1 + 8;
180  paBuf = aBuf;
181  //all samples are always 24bit, little endian - but we had to convert to big endian (PCM) here
182  {
183  int i;
184  //flip the endian for the audio samples - network audio is big endian
185  for (i = 0; i < (288); i += 3)
186  {
187  *(paBuf + 1) = *pAudio++;
188  *(paBuf + 0) = *pAudio++;
189  pAudio++;
190  paBuf += 2;
191  }
192  }
193 
194  //48 * 2 * 2 for 16bit audio
195  AUDIO_Player_QueueBuf(aBuf, 192);
196  }
197 
198  pbuf_free(p);
199  recCnt--;
200 }
201 
202 void main_UDanteUDP(void)
203 {
204  err_t err;
205 
206  //udp_init(); //it is actually empty
207  pcb0 = udp_new();
208 #if 0
209  pcb1 = udp_new();
210  pcb2 = udp_new();
211 #endif
212 
213 #if 0
214  err = udp_bind(pcb0, IP_ADDR_ANY, 14337);
215  if (err == ERR_OK)
216  {
217  udp_recv(pcb0, UDanteUDP_Receive, pcb0);
218  }
219 
220 #if 1
221  err = udp_bind(pcb1, IP_ADDR_ANY, 14339);
222  if (err == ERR_OK)
223  {
224  udp_recv(pcb1, UDanteUDP_Receive, pcb1);
225  }
226 
227  err = udp_bind(pcb2, IP_ADDR_ANY, 14341);
228  if (err == ERR_OK)
229  {
230  udp_recv(pcb2, UDanteUDP_Receive, pcb2);
231  }
232 #endif
233 #else
234  extern u16_t UDANTE_UDPPort;
235  err = udp_bind(pcb0, IP_ADDR_ANY, UDANTE_UDPPort);
236  if (err == ERR_OK)
237  {
238  udp_recv(pcb0, UDanteUDP_Receive, pcb0);
239  }
240 #endif
241 }
242 
248 void StartHTTPDThread(void const * argument)
249 {
250 #if 0
251  /* Initialize LCD and LEDs */
252  BSP_Config();
253 #endif
254 
255  /* Create tcp_ip stack thread */
256 #ifdef UDANTE
257  lwip_init(); /* if just network audio - call it w/o tcpip_init ! */
258 #else
259  tcpip_init(NULL, NULL);
260 #endif
261 
262  /* Initialize the LwIP stack */
263  Netif_Config();
264 
265 #ifndef UDANTE
266  /* Initialize webserver demo */
268 #endif
269 
270  /* Notify user about the network interface config */
272 
273 #ifdef USE_DHCP
274  /* Start DHCPClient */
275 #if defined(__GNUC__)
276  osThreadDef(DHCP, DHCP_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 5);
277 #else
278  osThreadDef(DHCP, DHCP_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 2);
279 #endif
280  osThreadCreate(osThread(DHCP), &gnetif);
281 #endif
282 
283  for( ;; )
284  {
285  /* Delete the Init Thread */
287  }
288 }
289 
291 {
292  ip_addr_t ipaddr;
293  ip_addr_t netmask;
294  ip_addr_t gw;
295 
296  /* IP address setting */
297  ip_addr_copy_from_ip4(ipaddr, ipAddr);
298  IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
299  IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
300 
301  /* - netif_add(struct netif *netif, ip_addr_t *ipaddr,
302  ip_addr_t *netmask, ip_addr_t *gw,
303  void *state, err_t (* init)(struct netif *netif),
304  err_t (* input)(struct pbuf *p, struct netif *netif))
305 
306  Adds your network interface to the netif_list. Allocate a struct
307  netif and pass a pointer to this structure as the first argument.
308  Give pointers to cleared ip_addr structures when using DHCP,
309  or fill them with sane numbers otherwise. The state pointer may be NULL.
310 
311  The init function pointer must point to a initialization function for
312  your ethernet netif interface. The following code illustrates it's use.*/
313 
314  netif_add(&gnetifUDANTE, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, (netif_input_fn)&ip4_input);
315 
316  /* Registers the default network interface. */
318 
320  {
321  /* When the netif is fully configured this function must be called.*/
323  }
324  else
325  {
326  /* When the netif link is down this function must be called */
328  }
329 }
330 
336 static void Netif_Config(void)
337 {
338  ip_addr_t ipaddr;
339  ip_addr_t netmask;
340  ip_addr_t gw;
341 
342  /* IP address setting */
343  IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
344  IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
345  IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
346 
347  /* - netif_add(struct netif *netif, ip_addr_t *ipaddr,
348  ip_addr_t *netmask, ip_addr_t *gw,
349  void *state, err_t (* init)(struct netif *netif),
350  err_t (* input)(struct pbuf *p, struct netif *netif))
351 
352  Adds your network interface to the netif_list. Allocate a struct
353  netif and pass a pointer to this structure as the first argument.
354  Give pointers to cleared ip_addr structures when using DHCP,
355  or fill them with sane numbers otherwise. The state pointer may be NULL.
356 
357  The init function pointer must point to a initialization function for
358  your ethernet netif interface. The following code illustrates it's use.*/
359 
360 #ifdef UDANTE
361  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, (netif_input_fn)&ip4_input);
362 #else
363  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
364 #endif
365 
366  /* Registers the default network interface. */
368 
369  if (netif_is_link_up(&gnetif))
370  {
371  /* When the netif is fully configured this function must be called.*/
373  }
374  else
375  {
376  /* When the netif link is down this function must be called */
378  }
379 }
380 
381 #if 0
382 
387 static void BSP_Config(void)
388 {
389  /* Initialize the LCD */
390  BSP_LCD_Init();
391 
392  /* Initialize the LCD Layers */
394 
395  /* Set LCD Foreground Layer */
397 
399 
400  /* Initialize LCD Log module */
401  LCD_LOG_Init();
402 
403  /* Show Header and Footer texts */
404  LCD_LOG_SetHeader((uint8_t *)"Webserver Application Netconn API");
405  LCD_LOG_SetFooter((uint8_t *)"STM32F769I-DISCO board");
406 
407  LCD_UsrLog((char *)" State: Ethernet Initialization ...\n");
408 }
409 #endif
410 
411 #if 0
412 
432 static void SystemClock_Config(void)
433 {
434  RCC_ClkInitTypeDef RCC_ClkInitStruct;
435  RCC_OscInitTypeDef RCC_OscInitStruct;
437 
438  /* Enable HSE Oscillator and activate PLL with HSE as source */
439  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
440  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
441  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
442  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
443  RCC_OscInitStruct.PLL.PLLM = 25;
444  RCC_OscInitStruct.PLL.PLLN = 400;
445  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
446  RCC_OscInitStruct.PLL.PLLQ = 9;
447 
448  ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
449  if(ret != HAL_OK)
450  {
451  while(1) { ; }
452  }
453 
454  /* Activate the OverDrive to reach the 200 MHz Frequency */
456  if(ret != HAL_OK)
457  {
458  while(1) { ; }
459  }
460 
461  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
463  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
464  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
465  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
466  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
467 
468  ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
469  if(ret != HAL_OK)
470  {
471  while(1) { ; }
472  }
473 }
474 
482 static void MPU_Config(void)
483 {
484  MPU_Region_InitTypeDef MPU_InitStruct;
485 
486  /* Disable the MPU */
487  HAL_MPU_Disable();
488 
489  /* Configure the MPU attributes as WT for SRAM */
490  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
491  MPU_InitStruct.BaseAddress = 0x20010000;
492  MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
493  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
494  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
495  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
496  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
497  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
498  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
499  MPU_InitStruct.SubRegionDisable = 0x00;
500  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
501 
502  HAL_MPU_ConfigRegion(&MPU_InitStruct);
503 
504  /* Enable the MPU */
505  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
506 }
507 
513 static void CPU_CACHE_Enable(void)
514 {
515  /* Enable I-Cache */
517 
518  /* Enable D-Cache */
520 }
521 #endif
522 
523 #ifdef USE_FULL_ASSERT
524 
531 void assert_failed(uint8_t* file, uint32_t line)
532 {
533  /* User can add his own implementation to report the file name and line number,
534  ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
535 
536  /* Infinite loop */
537  while (1)
538  {
539  }
540 }
541 #endif
542 
543 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Header of cmsis_os.c A new set of APIs are added in addition to existing ones, these APIs are specifi...
osStatus osKernelStart(void)
Start the RTOS Kernel with executing the specified thread.
Definition: cmsis_os.c:152
err_t(* netif_input_fn)(struct pbuf *p, struct netif *inp)
Definition: netif.h:131
#define RCC_CLOCKTYPE_PCLK1
#define RCC_SYSCLKSOURCE_PLLCLK
void http_taskCreate(void)
Definition: main_http.c:88
void SystemClock_Config(void)
System Clock Configuration The system Clock is configured as follow : System Clock source = PLL (HSE)...
Definition: main.c:913
void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address)
Initializes the LCD layers.
RCC System, AHB and APB busses clock configuration structure definition.
void BSP_LCD_SelectLayer(uint32_t LayerIndex)
Selects the LCD Layer.
#define GW_ADDR0
Definition: main.h:121
#define RCC_CLOCKTYPE_HCLK
struct udp_pcb * pcb0
Definition: main_http.c:147
int recCnt
Definition: main_http.c:155
void BSP_LCD_SetFont(sFONT *fonts)
Sets the LCD text font.
#define LCD_FB_START_ADDRESS
LCD FB_StartAddress.
void CPU_CACHE_Enable(void)
CPU L1-Cache enable.
Definition: main.c:986
priority: below normal
Definition: cmsis_os.h:238
#define IP_ADDR2
Definition: main.h:110
#define RCC_CLOCKTYPE_SYSCLK
#define RCC_PLLP_DIV2
void main_UDanteUDP(void)
Definition: main_http.c:202
#define RCC_SYSCLK_DIV1
#define IP_ADDR0
Definition: main.h:108
uint8_t BSP_LCD_Init(void)
Initializes the DSI LCD.
void LCD_LOG_Init(void)
Initializes the LCD Log module.
Definition: lcd_log.c:141
#define GW_ADDR2
Definition: main.h:123
#define netif_is_link_up(netif)
Definition: netif.h:368
void StartHTTPDThread(void const *argument)
Start Thread.
Definition: main_http.c:248
void netif_set_default(struct netif *netif)
Definition: netif.c:511
#define LCD_DEFAULT_FONT
LCD default font.
u16_t len
Definition: pbuf.h:125
#define GW_ADDR3
Definition: main.h:124
RCC_PLLInitTypeDef PLL
struct netif gnetif
Definition: main_http.c:71
#define RCC_PLL_ON
#define NETMASK_ADDR2
Definition: main.h:117
void netif_set_up(struct netif *netif)
Definition: netif.c:530
void lwip_init(void)
Definition: init.c:310
#define osThreadDef(name, thread, priority, instances, stacksz)
Definition: cmsis_os.h:445
#define RCC_HCLK_DIV2
#define GW_ADDR1
Definition: main.h:122
#define NULL
Definition: usbd_def.h:53
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:652
priority: normal (default)
Definition: cmsis_os.h:239
err_t tcpip_input(struct pbuf *p, struct netif *inp)
Definition: tcpip.c:186
HAL_StatusTypeDef HAL_Init(void)
This function is used to initialize the HAL Library; it must be the first instruction to be executed ...
#define LCD_UsrLog(...)
Definition: lcd_log.h:103
#define ERR_OK
Definition: err.h:52
Definition: pbuf.h:108
void MPU_Config(void)
Configure the MPU attributes as Write Through for SRAM1/2.
Definition: main.c:806
HAL_StatusTypeDef HAL_PWREx_EnableOverDrive(void)
s8_t err_t
Definition: err.h:47
__STATIC_INLINE void SCB_EnableICache(void)
Enable I-Cache.
Definition: core_cm7.h:2073
void LCD_LOG_SetFooter(uint8_t *footer)
Display the application footer on the LCD screen.
Definition: lcd_log.c:201
Definition: netif.h:182
void BSP_LED_On(Led_TypeDef Led)
Turns selected LED On.
osStatus osThreadTerminate(osThreadId thread_id)
Terminate execution of a thread and remove it from Active Threads.
Definition: cmsis_os.c:238
void AUDIO_Player_QueueBuf(uint8_t *buf, int len)
Put the Network Audio samples into SAI output buffer.
Definition: AudioPlayer.c:304
#define RCC_HSE_ON
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument)
Create a thread and add it to Active Threads and set it to state READY.
Definition: cmsis_os.c:204
#define RCC_OSCILLATORTYPE_HSE
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
void tcpip_init(tcpip_init_done_fn initfunc, void *arg)
Definition: tcpip.c:559
#define RCC_PLLSOURCE_HSE
#define NETMASK_ADDR0
Definition: main.h:115
void Netif_AddUDANTE(ip_addr_t ipAddr)
Definition: main_http.c:290
RCC Internal/External Oscillator (HSE, HSI, LSE and LSI) configuration structure definition.
void User_notification(struct netif *netif)
Notify the User about the network interface config status.
Definition: app_ethernet.c:72
header for the lcd_log.c file
#define NETMASK_ADDR3
Definition: main.h:118
void netif_set_down(struct netif *netif)
Definition: netif.c:587
int main_http(void)
Main program.
Definition: main_http.c:105
ip6_addr_t ip_addr_t
Definition: ip_addr.h:194
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
#define FLASH_LATENCY_7
void UDanteUDP_Receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
Definition: main_http.c:157
struct netif gnetifUDANTE
Definition: main_http.c:72
void http_server_netconn_init(void)
Initialize the HTTP server (start its thread)
#define configMINIMAL_STACK_SIZE
void LCD_LOG_SetHeader(uint8_t *header)
Display the application header on the LCD screen.
Definition: lcd_log.c:177
#define RCC_HCLK_DIV4
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
Definition: netif.c:184
#define osThread(name)
Definition: cmsis_os.h:454
HAL_StatusTypeDef
HAL Status structures definition.
#define RCC_CLOCKTYPE_PCLK2
__STATIC_INLINE void SCB_EnableDCache(void)
Enable D-Cache.
Definition: core_cm7.h:2123
err_t ethernetif_init(struct netif *netif)
Should be called at the beginning of the program to set up the network interface. It calls the functi...
Definition: ethernetif.c:478
#define NETMASK_ADDR1
Definition: main.h:116
unsigned short u16_t
Definition: cc.h:40
void * payload
Definition: pbuf.h:113
#define IP_ADDR1
Definition: main.h:109
#define IP_ADDR3
Definition: main.h:111