Skip to content
Snippets Groups Projects
Select Git revision
  • 965904ea3a70cde91c75faba43a2be483442d49b
  • master default protected
  • esp32-nimble-wiki
  • rahix/hw-lock-new-mutex
  • dx/somewhat-more-dynamic-config
  • schneider/sdk-0.2.1-7
  • schneider/bsec
  • dx/meh-bdf-to-stm
  • dx/flatten-config-module
  • genofire/ble-follow-py
  • schneider/ble-stability
  • schneider/ble-stability-new-phy
  • add_menu_vibration
  • plaetzchen/ios-workaround
  • blinkisync-as-preload
  • schneider/max30001-pycardium
  • schneider/max30001-epicaridum
  • schneider/max30001
  • schneider/stream-locks
  • schneider/fundamental-test
  • schneider/ble-buffers
  • v1.12
  • v1.11
  • v1.10
  • v1.9
  • v1.8
  • v1.7
  • v1.6
  • v1.5
  • v1.4
  • v1.3
  • v1.2
  • v1.1
  • v1.0
  • release-1
  • bootloader-v1
  • v0.0
37 results

display.py

Blame
  • Forked from card10 / firmware
    Source project has a limited visibility.
    main.c 12.72 KiB
    /*******************************************************************************
     * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
     *
     * Permission is hereby granted, free of charge, to any person obtaining a
     * copy of this software and associated documentation files (the "Software"),
     * to deal in the Software without restriction, including without limitation
     * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     * and/or sell copies of the Software, and to permit persons to whom the
     * Software is furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included
     * in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
     * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     * OTHER DEALINGS IN THE SOFTWARE.
     *
     * Except as contained in this notice, the name of Maxim Integrated 
     * Products, Inc. shall not be used except as stated in the Maxim Integrated 
     * Products, Inc. Branding Policy.
     *
     * The mere transfer of this software does not imply any licenses
     * of trade secrets, proprietary technology, copyrights, patents,
     * trademarks, maskwork rights, or any other form of intellectual
     * property whatsoever. Maxim Integrated Products, Inc. retains all 
     * ownership rights.
     *******************************************************************************
     */
    
    /* config.h is the required application configuration; RAM layout, stack, chip type etc. */
    #include "mxc_config.h"
    #include "board.h"
    
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    
    /* FreeRTOS */
    #include "FreeRTOS.h"
    #include "task.h"
    #include "semphr.h"
    
    /* FreeRTOS+ */
    #include "FreeRTOS_CLI.h"
    
    /* Maxim CMSIS SDK */
    #include "rtc.h"
    #include "uart.h"
    #include "lp.h"
    #include "led.h"
    #include "board.h"
    
    /* FreeRTOS+CLI */
    void vRegisterCLICommands(void);
    
    /* Mutual exclusion (mutex) semaphores */
    SemaphoreHandle_t xGPIOmutex;
    
    /* Task IDs */
    TaskHandle_t cmd_task_id;
    
    /* Enables/disables tick-less mode */
    unsigned int disable_tickless = 1;
    
    /* Stringification macros */
    #define STRING(x) STRING_(x)
    #define STRING_(x) #x
    
    /* Console ISR selection */
    #if (CONSOLE_UART==0)
    #define UARTx_IRQHandler UART0_IRQHandler
    #define UARTx_IRQn UART0_IRQn
    #elif (CONSOLE_UART==1)
    #define UARTx_IRQHandler UART1_IRQHandler
    #define UARTx_IRQn UART1_IRQn
    #else
    #error "Please update ISR macro for UART CONSOLE_UART"
    #endif
    mxc_uart_regs_t *ConsoleUART = MXC_UART_GET_UART(CONSOLE_UART);
    
    /* Array sizes */
    #define CMD_LINE_BUF_SIZE  80
    #define OUTPUT_BUF_SIZE  512
    
    /* =| vTask0 |============================================
     * 
     * This task blinks LED0 at a 0.5Hz rate, and does not
     *  drift due to the use of vTaskDelayUntil(). It may have
     *  jitter, however, due to any higher-priority task or
     *  interrupt causing delays in scheduling.
     *
     * =======================================================
     */
    void vTask0(void *pvParameters)
    {
      TickType_t xLastWakeTime;
      unsigned int x = LED_OFF;
    
      /* Get task start time */
      xLastWakeTime = xTaskGetTickCount();
      
      while (1) {
        /* Protect hardware access with mutex
         *
         * Note: This is not strictly necessary, since GPIO_SetOutVal() is implemented with bit-band
         * access, which is inherently task-safe. However, for other drivers, this would be required.
         *
         */
        if (xSemaphoreTake(xGPIOmutex, portMAX_DELAY) == pdTRUE) {
          if (x == LED_OFF) {
    	x = LED_ON;
          } else {
    	x = LED_OFF;
          }
          /* Return the mutex after we have modified the hardware state */
          xSemaphoreGive(xGPIOmutex);
        }
        /* Wait 1 second until next run */
        vTaskDelayUntil(&xLastWakeTime, configTICK_RATE_HZ);    
      }
    }
    
    /* =| vTask1 |============================================
     * 
     * This task blinks LED1 at a 0.5Hz rate, and does not
     *  drift due to the use of vTaskDelayUntil(). It may have
     *  jitter, however, due to any higher-priority task or
     *  interrupt causing delays in scheduling.
     *
     * NOTE: The MAX32660 EV Kit has only 1 LED, so this task
     *  does not blink an LED.
     *
     * =======================================================
     */
    void vTask1(void *pvParameters)
    {
      TickType_t xLastWakeTime;
      unsigned int x = LED_ON;
    
      /* Get task start time */
      xLastWakeTime = xTaskGetTickCount();
      
      while (1) {
        /* Protect hardware access with mutex
         *
         * Note: This is not strictly necessary, since GPIO_SetOutVal() is implemented with bit-band
         * access, which is inherently task-safe. However, for other drivers, this would be required.
         *
         */
        if (xSemaphoreTake(xGPIOmutex, portMAX_DELAY) == pdTRUE) {
          if (x == LED_OFF) {
    	LED_On(0);
    	x = LED_ON;
          } else {
    	LED_Off(0);
    	x = LED_OFF;
          }
          /* Return the mutex after we have modified the hardware state */
          xSemaphoreGive(xGPIOmutex);
        }
        /* Wait 1 second until next run */
        vTaskDelayUntil(&xLastWakeTime, configTICK_RATE_HZ);
      }
    }
    
    /* =| vTickTockTask |============================================
     * 
     * This task writes the current RTOS tick time to the console
     *
     * =======================================================
     */
    void vTickTockTask(void *pvParameters)
    {
      TickType_t ticks = 0;
      TickType_t xLastWakeTime;
    
      /* Get task start time */
      xLastWakeTime = xTaskGetTickCount();
      
      while (1) {
        ticks = xTaskGetTickCount();
        printf("Uptime is 0x%08x (%u seconds), tickless-idle is %s\n",
    	   ticks, ticks / configTICK_RATE_HZ,
    	   disable_tickless ? "disabled" : "ENABLED");
        vTaskDelayUntil(&xLastWakeTime, (configTICK_RATE_HZ * 60));
      }
    }
    
    /* =| UART0_IRQHandler |======================================
     * 
     * This function overrides the weakly-declared interrupt handler
     *  in system_max326xx.c and is needed for asynchronous UART
     *  calls to work properly
     *
     * ===========================================================
     */
    void UARTx_IRQHandler(void)
    {
        UART_Handler(ConsoleUART);
    }
    
    /* =| vCmdLineTask_cb |======================================
     * 
     * Callback on asynchronous reads to wake the waiting command
     *  processor task
     *
     * ===========================================================
     */
    void vCmdLineTask_cb(uart_req_t *req, int error)
    {
      BaseType_t xHigherPriorityTaskWoken;
    
      /* Wake the task */
      xHigherPriorityTaskWoken = pdFALSE;
      vTaskNotifyGiveFromISR(cmd_task_id, &xHigherPriorityTaskWoken);
      portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
    
    /* =| vCmdLineTask |======================================
     * 
     * The command line task provides a prompt on the serial
     *  interface and takes input from the user to evaluate
     *  via the FreeRTOS+CLI parser.
     *
     * NOTE: FreeRTOS+CLI is part of FreeRTOS+ and has 
     *  different licensing requirements. Please see 
     *  http://www.freertos.org/FreeRTOS-Plus for more information
     *
     * =======================================================
     */
    void vCmdLineTask(void *pvParameters)
    {
      unsigned char tmp;
      unsigned int index;     /* Index into buffer */
      unsigned int x;
      char buffer[CMD_LINE_BUF_SIZE];        /* Buffer for input */
      char output[OUTPUT_BUF_SIZE];        /* Buffer for output */
      BaseType_t xMore;
      uart_req_t async_read_req;
      gpio_cfg_t uart_rx_pin = {PORT_0, PIN_10, GPIO_FUNC_IN, GPIO_PAD_NONE};
    
      memset(buffer, 0, CMD_LINE_BUF_SIZE);
      index = 0;
        
      /* Register available CLI commands */
      vRegisterCLICommands();
    
    #if configUSE_TICKLESS_IDLE
      /* Configure wake-up for GPIO pin corresponding to the UART RX line */
      LP_EnableGPIOWakeup(&uart_rx_pin);
      GPIO_IntConfig(&uart_rx_pin, GPIO_INT_EDGE, GPIO_INT_FALLING);
    #endif
    
      /* Enable UART0 interrupt */
      NVIC_ClearPendingIRQ(UARTx_IRQn);
      NVIC_DisableIRQ(UARTx_IRQn);
      NVIC_SetPriority(UARTx_IRQn, 1);
      NVIC_EnableIRQ(UARTx_IRQn);
    
      /* Async read will be used to wake process */
      async_read_req.data = &tmp;
      async_read_req.len = 1;
      async_read_req.callback = vCmdLineTask_cb;
      
      printf("\nEnter 'help' to view a list of available commands.\n");
      printf("cmd> ");
      fflush(stdout);
      while (1) {
        /* Register async read request */
        if (UART_ReadAsync(ConsoleUART, &async_read_req) != E_NO_ERROR) {
          printf("Error registering async request. Command line unavailable.\n");
          vTaskDelay(portMAX_DELAY);
        }
        /* Hang here until ISR wakes us for a character */
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
        /* Check that we have a valid character */
        if (async_read_req.num > 0) {
          /* Process character */
          do {
    	if (tmp == 0x08) {
    	  /* Backspace */
    	  if (index > 0) {
    	    index--;
    	    printf("\x08 \x08");
    	  }
    	  fflush(stdout);
    	} else if (tmp == 0x03) {
    	  /* ^C abort */
    	  index = 0;
    	  printf("^C");
    	  printf("\ncmd> ");
    	  fflush(stdout);
    	} else if ((tmp == '\r') ||
    		   (tmp == '\n')) {
    	  printf("\r\n");
    	  /* Null terminate for safety */
    	  buffer[index] = 0x00;
    	  /* Evaluate */
    	  do {
    	    xMore = FreeRTOS_CLIProcessCommand(buffer, output, OUTPUT_BUF_SIZE);
    	    /* If xMore == pdTRUE, then output buffer contains no null termination, so 
    	     *  we know it is OUTPUT_BUF_SIZE. If pdFALSE, we can use strlen.
    	     */
    	    for (x = 0; x < (xMore == pdTRUE ? OUTPUT_BUF_SIZE : strlen(output)) ; x++) {
    	      putchar(*(output+x));
    	    }
    	  } while (xMore != pdFALSE);
    	  /* New prompt */
    	  index = 0;
    	  printf("\ncmd> ");
    	  fflush(stdout);
    	} else if (index < CMD_LINE_BUF_SIZE) {
    	  putchar(tmp);
    	  buffer[index++] = tmp;
    	  fflush(stdout);
    	} else {
    	  /* Throw away data and beep terminal */
    	  putchar(0x07);
    	  fflush(stdout);
    	}
    	/* If more characters are ready, process them here */
          } while ((UART_NumReadAvail(MXC_UART_GET_UART(CONSOLE_UART)) > 0) &&
    	       UART_Read(MXC_UART_GET_UART(CONSOLE_UART), (uint8_t *)&tmp, 1, NULL));
        }
      }
    }
    
    #if configUSE_TICKLESS_IDLE
    /* =| freertos_permit_tickless |==========================
     * 
     * Determine if any hardware activity should prevent 
     *  low-power tickless operation.
     *
     * =======================================================
     */
    int freertos_permit_tickless(void)
    {
      if (disable_tickless == 1) {
        return E_BUSY;
      }
    
      return UART_PrepForSleep(MXC_UART_GET_UART(CONSOLE_UART));
    }
    #endif
    
    void RTC_IRQHandler(void)
    {
      MXC_RTC->ctrl &= ~(MXC_F_RTC_CTRL_ALSF);
    }
    
    /* =| main |==============================================
     * 
     * This program demonstrates FreeRTOS tasks, mutexes, 
     *  and the FreeRTOS+CLI extension.
     *
     * =======================================================
     */
    int main(void)
    {
    #if configUSE_TICKLESS_IDLE
      uart_cfg_t uart_cfg = {
        .parity = UART_PARITY_DISABLE,
        .size   = UART_DATA_SIZE_8_BITS,
        .stop   = UART_STOP_1,
        .flow   = UART_FLOW_CTRL_DIS,
        .pol    = UART_FLOW_POL_DIS,
        .baud   = 115200,
        .clksel = UART_CLKSEL_SYSTEM
      };
      sys_cfg_uart_t uart_sys_cfg = {MAP_A, Enable};
    
      /* The RTC must be enabled for tickless operation */
      RTC_Init(MXC_RTC, 0, 0, NULL);
      RTC_EnableRTCE(MXC_RTC);
      NVIC_ClearPendingIRQ(RTC_IRQn);
      NVIC_EnableIRQ(RTC_IRQn);
      LP_EnableRTCAlarmWakeup();
      /* If running tickless idle, must reduce baud rate to avoid losing character */
      if (UART_Init(ConsoleUART, &uart_cfg, &uart_sys_cfg) != E_NO_ERROR) {
        MXC_ASSERT_FAIL();
      }
    #endif
      
      /* Print banner (RTOS scheduler not running) */
      printf("\n-=- %s FreeRTOS (%s) Demo -=-\n", STRING(TARGET), tskKERNEL_VERSION_NUMBER);
    #if configUSE_TICKLESS_IDLE
      printf("Tickless idle is configured. Type 'tickless 1' to enable.\n");
    #endif
    
      /* Create mutexes */
      xGPIOmutex = xSemaphoreCreateMutex();
      if (xGPIOmutex == NULL) {
        printf("xSemaphoreCreateMutex failed to create a mutex.\n");
      } else {
        /* Configure task */
        if ((xTaskCreate(vTask0, (const char *)"Task0",
    		     configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) ||
    	(xTaskCreate(vTask1, (const char *)"Task1",
    		     configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) ||
    	(xTaskCreate(vTickTockTask, (const char *)"TickTock",
    		     2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+2, NULL) != pdPASS) ||
    	(xTaskCreate(vCmdLineTask, (const char *)"CmdLineTask",
    		     configMINIMAL_STACK_SIZE+CMD_LINE_BUF_SIZE+OUTPUT_BUF_SIZE, NULL, tskIDLE_PRIORITY+1, &cmd_task_id) != pdPASS)) {
          printf("xTaskCreate() failed to create a task.\n");
        } else {
          /* Start scheduler */
          printf("Starting scheduler.\n");
          vTaskStartScheduler();
        }
      }
      
      /* This code is only reached if the scheduler failed to start */
      printf("ERROR: FreeRTOS did not start due to above error!\n");
      while (1) {
        __NOP();
      }
    
      /* Quiet GCC warnings */
      return -1;
    }