Compare commits
159 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a67f2b8fa4 | |||
| 62af1350d9 | |||
| 67645299cb | |||
| 4949d7898f | |||
| 19de13565d | |||
| e5e4d92f53 | |||
| 4c913a5f4c | |||
| 7710f098ec | |||
| 98d945de8d | |||
| dac7c819fe | |||
| f0ad7adcc4 | |||
| b474ab69f7 | |||
| 75ec90e6d9 | |||
| ce018803aa | |||
| a760658577 | |||
| 13210f73f2 | |||
| 01e53f7f72 | |||
| cb3445e9ca | |||
| 94d5413ceb | |||
| e18befa26d | |||
| 4d4ac8576f | |||
| 3f980237c7 | |||
| 460b0d6705 | |||
| 6d6600475e | |||
| 85812c3770 | |||
| f3e3724855 | |||
| e5ff1c5f78 | |||
| fa796d6b61 | |||
| 0c4ec15b93 | |||
| e35b4dbda6 | |||
| ab706aee83 | |||
| be088432ef | |||
| 7876ed2352 | |||
| 5edb950906 | |||
| 2133083c41 | |||
| ed86d3dc51 | |||
| a49d495f19 | |||
| 8e5cac178c | |||
| 9c52557f7f | |||
| a905ef0166 | |||
| 794eb048ba | |||
| 5b9898cd68 | |||
| 640b27c99d | |||
| b0f7679545 | |||
| a27733c879 | |||
| c9ecde9eba | |||
| 3bb6487384 | |||
| e2eb731ea1 | |||
| b3d1a4abd3 | |||
| bf2209ccde | |||
| 0256a74c27 | |||
| e7f7757eaa | |||
| b9b43875f4 | |||
| d85a87c6fd | |||
| 9ec7363729 | |||
| dfaed7fc5a | |||
| aaaa331bcb | |||
| 17f3120ed9 | |||
| 2d7dbb6b4a | |||
| 1a39199666 | |||
| 1beb237590 | |||
| 316f00c8f9 | |||
| f4cb22f436 | |||
| 5892bffd3c | |||
| 24df573e7c | |||
| 306177a647 | |||
| 46ce36d71c | |||
| a4e6d59996 | |||
| 643d3230a1 | |||
| 0ce9377eb1 | |||
| 28df9885e3 | |||
| 03106860f7 | |||
| 1edd217b5c | |||
| 5b52d39bba | |||
| 00413b5098 | |||
| c144c6ff27 | |||
| ca3e0ebb69 | |||
| 9c8300c31b | |||
| 3c0822efe3 | |||
| 10856ca6dd | |||
| 939f4034da | |||
| 669f0f0c48 | |||
| f915dd3b9a | |||
| 77071869b2 | |||
| 3532dfe8e3 | |||
| 3522da08b0 | |||
| 3741c79e97 | |||
| 76d08f50bf | |||
| 4e21ae6934 | |||
| d10a7b95cc | |||
| 901aa2b860 | |||
| 5223e2a782 | |||
| d9a2a7b4e2 | |||
| 84ace26dd6 | |||
| fba64e0716 | |||
| 31c691c7c5 | |||
| 7f5337d0c8 | |||
| d163394faf | |||
| 0d40e8a2bc | |||
| e3c969b3e1 | |||
| 3968bb1a5b | |||
| 566101b7c8 | |||
| 6d8edfbf40 | |||
| 0c9b8d2b8d | |||
| e6621dee5a | |||
| f1e8f66a39 | |||
| f192bb44c5 | |||
| 0b3d60d1b3 | |||
| a310520643 | |||
| b476520494 | |||
| d3803c43ae | |||
| a404a98c25 | |||
| 9916809ddf | |||
| cfe55c5e23 | |||
| 50ef6af023 | |||
| d3114ed49f | |||
| 0e90206dda | |||
| 443f38e90c | |||
| 7eb82ae895 | |||
| 385b5ad471 | |||
| 2bf247c103 | |||
| c4bb2fec1f | |||
| 0e9a2baa56 | |||
| 9faf9f8692 | |||
| 4cecf11510 | |||
| d6f62f8b22 | |||
| fb60d3c254 | |||
| c45c81e0ac | |||
| 3cf2a1453d | |||
| 5e8cab7512 | |||
| ca2c177949 | |||
| ad35d558e4 | |||
| d585a711ac | |||
| afcd31c12f | |||
| 92ec0d79a1 | |||
| 82f8018af1 | |||
| afa267e0be | |||
| e3c1a5a579 | |||
| e27421d2bf | |||
| 41759ddfaf | |||
| 059305ecbf | |||
| 06184562e8 | |||
| 28d1d31402 | |||
| 2c4e6a921f | |||
| d0706fa05c | |||
| 399fdf6a45 | |||
| 8f45c844cd | |||
| c1d841239d | |||
| 216c9c40f8 | |||
| d563e23105 | |||
| c42b96a6eb | |||
| d9c1bf6a49 | |||
| 6b30832545 | |||
| 55db0df3d9 | |||
| dd7a8eb33e | |||
| 06171ec3ae | |||
| 52f75b1969 | |||
| e23abeb2d8 | |||
| c42094626a |
@@ -2,3 +2,4 @@
|
||||
/.visualgdb/
|
||||
/VisualGDB/
|
||||
*.vgdbsettings.*.user
|
||||
*.zip
|
||||
|
||||
+93
-97
@@ -26,7 +26,6 @@
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
@@ -38,8 +37,8 @@
|
||||
/*-----------------------------------------------------------
|
||||
* Possible configurations for system timer
|
||||
*/
|
||||
#define FREERTOS_USE_RTC 0 /**< Use real time clock for the system */
|
||||
#define FREERTOS_USE_SYSTICK 1 /**< Use SysTick timer for system */
|
||||
#define FREERTOS_USE_RTC 0 /**< Use real time clock for the system */
|
||||
#define FREERTOS_USE_SYSTICK 1 /**< Use SysTick timer for system */
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
@@ -53,155 +52,152 @@
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configTICK_SOURCE FREERTOS_USE_RTC
|
||||
#define configTICK_SOURCE FREERTOS_USE_RTC
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
#define configUSE_TICKLESS_IDLE_SIMPLE_DEBUG 1 /* See into vPortSuppressTicksAndSleep source code for explanation */
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ 1024
|
||||
#define configMAX_PRIORITIES ( 6 )
|
||||
#define configMINIMAL_STACK_SIZE ( 192 )
|
||||
#define configTOTAL_HEAP_SIZE ( 32 * 1024 )
|
||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
|
||||
#define configQUEUE_REGISTRY_SIZE 2
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
#define configUSE_TICKLESS_IDLE_SIMPLE_DEBUG 1 /* See into vPortSuppressTicksAndSleep source code for explanation */
|
||||
#define configCPU_CLOCK_HZ (SystemCoreClock)
|
||||
#define configTICK_RATE_HZ 1024
|
||||
#define configMAX_PRIORITIES (6)
|
||||
#define configMINIMAL_STACK_SIZE (192)
|
||||
#define configTOTAL_HEAP_SIZE (32 * 1024)
|
||||
#define configMAX_TASK_NAME_LEN (16)
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
|
||||
#define configQUEUE_REGISTRY_SIZE 2
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES (2)
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( 2 )
|
||||
#define configTIMER_QUEUE_LENGTH 32
|
||||
#define configTIMER_TASK_STACK_DEPTH ( 80 )
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY (2)
|
||||
#define configTIMER_QUEUE_LENGTH 32
|
||||
#define configTIMER_TASK_STACK_DEPTH (80)
|
||||
|
||||
/* Tickless Idle configuration. */
|
||||
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
|
||||
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
|
||||
#define configASSERT( x ) ASSERT(x)
|
||||
#define configASSERT(x) ASSERT(x)
|
||||
#endif
|
||||
|
||||
/* FreeRTOS MPU specific definitions. */
|
||||
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 1
|
||||
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 1
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 0
|
||||
#define INCLUDE_uxTaskPriorityGet 0
|
||||
#define INCLUDE_vTaskDelete 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_xResumeFromISR 0
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||
#define INCLUDE_pcTaskGetTaskName 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
#define INCLUDE_vTaskPrioritySet 0
|
||||
#define INCLUDE_uxTaskPriorityGet 0
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_xResumeFromISR 0
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||
#define INCLUDE_pcTaskGetTaskName 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||
function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY _PRIO_APP_HIGH
|
||||
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY _PRIO_APP_HIGH
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY configLIBRARY_LOWEST_INTERRUPT_PRIORITY
|
||||
#define configKERNEL_INTERRUPT_PRIORITY configLIBRARY_LOWEST_INTERRUPT_PRIORITY
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
|
||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||
standard names - or at least those used in the unmodified vector table. */
|
||||
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Settings that are generated automatically
|
||||
* basing on the settings above
|
||||
*/
|
||||
#if (configTICK_SOURCE == FREERTOS_USE_SYSTICK)
|
||||
// do not define configSYSTICK_CLOCK_HZ for SysTick to be configured automatically
|
||||
// to CPU clock source
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
// do not define configSYSTICK_CLOCK_HZ for SysTick to be configured automatically
|
||||
// to CPU clock source
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
#elif (configTICK_SOURCE == FREERTOS_USE_RTC)
|
||||
#define configSYSTICK_CLOCK_HZ ( 32768UL )
|
||||
#define xPortSysTickHandler RTC1_IRQHandler
|
||||
#define configSYSTICK_CLOCK_HZ (32768UL)
|
||||
#define xPortSysTickHandler RTC1_IRQHandler
|
||||
#else
|
||||
#error Unsupported configTICK_SOURCE value
|
||||
#error Unsupported configTICK_SOURCE value
|
||||
#endif
|
||||
|
||||
/* Code below should be only used by the compiler, and not the assembler. */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__ASSEMBLER__))
|
||||
#include "nrf.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
/* This part of definitions may be problematic in assembly - it uses definitions from files that are not assembly compatible. */
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#error "This port requires __NVIC_PRIO_BITS to be defined"
|
||||
#endif
|
||||
/* This part of definitions may be problematic in assembly - it uses definitions from files that are not assembly compatible. */
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#error "This port requires __NVIC_PRIO_BITS to be defined"
|
||||
#endif
|
||||
|
||||
/* Access to current system core clock is required only if we are ticking the system by systimer */
|
||||
#if (configTICK_SOURCE == FREERTOS_USE_SYSTICK)
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
/* Access to current system core clock is required only if we are ticking the system by systimer */
|
||||
#if (configTICK_SOURCE == FREERTOS_USE_SYSTICK)
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
#endif /* !assembler */
|
||||
|
||||
/** Implementation note: Use this with caution and set this to 1 ONLY for debugging
|
||||
* ----------------------------------------------------------
|
||||
* Set the value of configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG to below for enabling or disabling RTOS tick auto correction:
|
||||
* 0. This is default. If the RTC tick interrupt is masked for more than 1 tick by higher priority interrupts, then most likely
|
||||
* one or more RTC ticks are lost. The tick interrupt inside RTOS will detect this and make a correction needed. This is needed
|
||||
* for the RTOS internal timers to be more accurate.
|
||||
* 1. The auto correction for RTOS tick is disabled even though few RTC tick interrupts were lost. This feature is desirable when debugging
|
||||
* the RTOS application and stepping though the code. After stepping when the application is continued in debug mode, the auto-corrections of
|
||||
* RTOS tick might cause asserts. Setting configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG to 1 will make RTC and RTOS go out of sync but could be
|
||||
* convenient for debugging.
|
||||
*/
|
||||
#define configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG 0
|
||||
* Set the value of configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG to below for enabling or disabling RTOS tick auto correction:
|
||||
* 0. This is default. If the RTC tick interrupt is masked for more than 1 tick by higher priority interrupts, then most likely
|
||||
* one or more RTC ticks are lost. The tick interrupt inside RTOS will detect this and make a correction needed. This is needed
|
||||
* for the RTOS internal timers to be more accurate.
|
||||
* 1. The auto correction for RTOS tick is disabled even though few RTC tick interrupts were lost. This feature is desirable when debugging
|
||||
* the RTOS application and stepping though the code. After stepping when the application is continued in debug mode, the auto-corrections of
|
||||
* RTOS tick might cause asserts. Setting configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG to 1 will make RTC and RTOS go out of sync but could be
|
||||
* convenient for debugging.
|
||||
*/
|
||||
#define configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG 0
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "adc_drv.h"
|
||||
|
||||
#if (DEF_ADS8691_ENABLED)
|
||||
#include "ads8691.h"
|
||||
extern const adc_drv_if_t ads8691;
|
||||
static const adc_drv_if_t *p_inst = &ads8691;
|
||||
#else
|
||||
#include "builtin_saadc.h"
|
||||
static const adc_drv_if_t *p_inst = &builtin_saadc;
|
||||
#endif
|
||||
|
||||
#if (DEF_ADC_DRV_ENABLED)
|
||||
|
||||
int adc_init(void)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->init();
|
||||
}
|
||||
|
||||
int adc_reset(void)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->reset();
|
||||
}
|
||||
|
||||
int adc_gain(adc_gain_t gain)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->gain(gain);
|
||||
}
|
||||
|
||||
int adc_read(uint32_t channel, int32_t *adc_val)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read(channel, adc_val);
|
||||
}
|
||||
|
||||
int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read_multiple_channels(p_channel, p_adc_val, cnt);
|
||||
}
|
||||
|
||||
int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void))
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read_multiple_channels_ex(p_channel, p_adc_val, cnt, preliminary_action);
|
||||
}
|
||||
|
||||
int adc_read_multiple_milivolt_ex(uint32_t *p_channel, float *p_val, uint32_t cnt, void (*preliminary_action)(void))
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read_multiple_milivolt_ex(p_channel, p_val, cnt, preliminary_action);
|
||||
}
|
||||
|
||||
int adc_read_milivolt(uint32_t channel, float *mv)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read_milivolt(channel, mv);
|
||||
}
|
||||
|
||||
#endif /* ! DEF_ADC_DRV_ENABLED */
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef __ADC_DRV_H__
|
||||
#define __ADC_DRV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "adc_drv_if.h"
|
||||
|
||||
#define ADC_DRV_ERROR (-1)
|
||||
#define ADC_DRV_SUCCESS (0)
|
||||
|
||||
#define AIN0 0
|
||||
#define AIN1 1
|
||||
#define AIN2 2
|
||||
#define AIN3 3
|
||||
#define AIN4 4
|
||||
#define AIN5 5
|
||||
#define AIN6 6
|
||||
#define AIN7 7
|
||||
|
||||
#if (DEF_ADC_DRV_ENABLED)
|
||||
int adc_init(void);
|
||||
int adc_reset(void);
|
||||
int adc_gain(adc_gain_t gain);
|
||||
int adc_read(uint32_t channel, int32_t *adc_val);
|
||||
int adc_read_milivolt(uint32_t channel, float *mv);
|
||||
int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt);
|
||||
int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void));
|
||||
int adc_read_multiple_milivolt_ex(uint32_t *p_channel, float *p_val, uint32_t cnt, void (*preliminary_action)(void));
|
||||
#else
|
||||
#define adc_init()
|
||||
#define adc_reset()
|
||||
#define adc_gain(x)
|
||||
#define adc_read(x, y)
|
||||
#define adc_read_milivolt(x, y)
|
||||
#define adc_read_mutiple_channels(x, y, z)
|
||||
#define adc_read_mutiple_channels_ex(x, y, z, a)
|
||||
#define adc_read_multiple_milivolt_ex(x, y, z, a)
|
||||
#endif /* ! DEF_ADC_DRV_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ADC_DRV_H__ */
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifndef __ADC_DRV_IF_H__
|
||||
#define __ADC_DRV_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ADC0 (0x01 << 0)
|
||||
#define ADC1 (0x01 << 1)
|
||||
#define ADC2 (0x01 << 2)
|
||||
#define ADC3 (0x01 << 3)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GAIN_0P625,
|
||||
GAIN_1P000,
|
||||
GAIN_1P200,
|
||||
GAIN_1P250,
|
||||
GAIN_1P500,
|
||||
GAIN_2P000,
|
||||
GAIN_2P500,
|
||||
GAIN_3P000,
|
||||
GAIN_6P000,
|
||||
GAIN_12P000,
|
||||
GAIN_24P000,
|
||||
} adc_gain_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int (*init)(void);
|
||||
int (*reset)(void);
|
||||
int (*read)(uint32_t channel, int32_t *adc_val);
|
||||
int (*read_milivolt)(uint32_t channel, float *p_val);
|
||||
int (*read_multiple_milivolt_ex)(uint32_t *p_channels, float *p_val, uint32_t count, void (*preliminary_action));
|
||||
int (*read_multiple_channels)(uint32_t *p_channels, int32_t *adc_val, uint32_t count);
|
||||
int (*read_multiple_channels_ex)(uint32_t *p_channels, int32_t *adc_val, uint32_t count, void (*preliminary_action)(void));
|
||||
int (*gain)(adc_gain_t gain);
|
||||
} adc_drv_if_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ADC_DRV_IF_H__ */
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#include "adgs1412.h"
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "nrf_delay.h"
|
||||
|
||||
#if (DEF_ADGS1412_ENABLED)
|
||||
|
||||
#define DAISY_CHAIN_MODE 0x2500
|
||||
|
||||
static sw_t m_sw;
|
||||
|
||||
static int adgs1412_reset(void)
|
||||
{
|
||||
// the datasheet lacks clarity, RST_SW_PIN needs to be delayed after the motion signal
|
||||
nrf_gpio_pin_clear(RST_SW_PIN);
|
||||
nrf_delay_ms(1);
|
||||
nrf_gpio_pin_set(RST_SW_PIN);
|
||||
nrf_delay_ms(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adgs1412_write(sw_t sw_mask)
|
||||
{
|
||||
uint8_t cmd[ASGS1412_COUNT];
|
||||
uint64_t val = m_sw.val = sw_mask.val;
|
||||
for (int i = 1; i <= ASGS1412_COUNT; i++)
|
||||
{
|
||||
cmd[sizeof(cmd) - i] = val & ((0x01 << SW_PER_BYTE) - 1);
|
||||
val = val >> 4;
|
||||
}
|
||||
spim_xfer(CS_SW_PIN, NRF_SPIM_MODE_0, (uint8_t *)cmd, sizeof(cmd), NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adgs1412_read(sw_t *p_sw_mask)
|
||||
{
|
||||
*p_sw_mask = m_sw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adgs1412_get_sw_count(uint32_t *p_sw_cnt)
|
||||
{
|
||||
*p_sw_cnt = SW_TOTAL_COUNT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adgs1412_init(void)
|
||||
{
|
||||
/* reset */
|
||||
adgs1412_reset();
|
||||
|
||||
/* enter daisy chain mode */
|
||||
uint16_t cmd = __REV16(DAISY_CHAIN_MODE);
|
||||
spim_xfer(CS_SW_PIN, NRF_SPIM_MODE_0, (uint8_t *)&cmd, sizeof(cmd), NULL, 0);
|
||||
|
||||
/* sw status initialize */
|
||||
m_sw.val = 0;
|
||||
adgs1412_write(m_sw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sw_drv_if_t adgs1412 = {
|
||||
.init = adgs1412_init,
|
||||
.reset = adgs1412_reset,
|
||||
.write = adgs1412_write,
|
||||
.read = adgs1412_read,
|
||||
.get_sw_count = adgs1412_get_sw_count,
|
||||
};
|
||||
|
||||
#endif /* ! DEF_ADGS1412_ENABLED */
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
#ifndef __ADGS1412_H__
|
||||
#define __ADGS1412_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "sw_drv_if.h"
|
||||
|
||||
#if (DEF_ADGS1412_ENABLED)
|
||||
|
||||
#define ASGS1412_COUNT 2
|
||||
#define SW_PER_ASGS1412 4
|
||||
#define SW_TOTAL_COUNT (SW_PER_ASGS1412 * ASGS1412_COUNT)
|
||||
#define SW_PER_BYTE SW_PER_ASGS1412
|
||||
|
||||
#if (SW_TOTAL_COUNT > 64)
|
||||
#error "unsupport"
|
||||
#endif /* ! SW_TOTAL_COUNT */
|
||||
|
||||
extern const sw_drv_if_t adgs1412;
|
||||
|
||||
#endif /* ! DEF_ADGS1412_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ADGS1412_H__ */
|
||||
@@ -0,0 +1,336 @@
|
||||
#include "ads8691.h"
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "nrf_delay.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if (DEF_ADS8691_ENABLED)
|
||||
|
||||
/*
|
||||
* ADS8691
|
||||
* Features:
|
||||
* -18-Bit ADC With Integrated Analog Front-End
|
||||
* -High Speed: 1 MSPS
|
||||
*
|
||||
* Spi data:
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Input | 9-bit address | 16-bit data |
|
||||
* | Commands | | |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* -CMD [7bits]
|
||||
* 0b11000xx CLEAR_HWORD
|
||||
* 0b11001xx READ_HWORD
|
||||
* 0b01001xx READ
|
||||
* 0b1101000 WRITE (We used this CMD)
|
||||
* 0b1101001 WRITE
|
||||
* 0b1101010 WRITE
|
||||
* 0b11011xx SET_HWORD
|
||||
*
|
||||
* -Address [9bits]
|
||||
* 00h DEVICE_ID_REG
|
||||
* 04h RST_PWRCTL_REG
|
||||
* 08h SDI_CTL_REG
|
||||
* 0Ch SDO_CTL_REG
|
||||
* 10h DATAOUT_CTL_REG
|
||||
* 14h RANGE_SEL_REG
|
||||
* 20h ALARM_REG
|
||||
* 24h ALARM_H_TH_REG
|
||||
* 28h ALARM_L_TH_REG
|
||||
*
|
||||
*/
|
||||
|
||||
#define ADS8691_CMD_NOP 0b0000000 // 7 bits
|
||||
#define ADS8691_CMD_CLR_HWORD 0b1100000
|
||||
#define ADS8691_CMD_READ_HWORD 0b1100100
|
||||
#define ADS8691_CMD_READ 0b0100100
|
||||
#define ADS8691_CMD_WRITE 0b1101000
|
||||
#define ADS8691_CMD_WRITE_MSB 0b1101001
|
||||
#define ADS8691_CMD_WRITE_LSB 0b1101010
|
||||
#define ADS8691_CMD_SET_HWORD 0b1101100
|
||||
|
||||
#define DEVICE_ID_REG 0x0000
|
||||
#define RST_PWRCTL_REG 0x0004
|
||||
#define SDI_CTL_REG 0x0008
|
||||
#define DATAOUT_CTL_REG 0x0010
|
||||
#define RANGE_SEL_REG 0x0014
|
||||
#define ALARM_H_TH_REG 0x0024
|
||||
#define ALARM_L_TH_REG 0x0028
|
||||
|
||||
#define ADS8691_SPI_MODE0 0b00
|
||||
#define ADS8691_SPI_MODE1 0b01
|
||||
#define ADS8691_SPI_MODE2 0b10
|
||||
#define ADS8691_SPI_MODE3 0b11
|
||||
|
||||
#define INT_VREF_ENABLE 0 // Internal reference is enabled
|
||||
#define INT_VREF_DISABLE 1 // Internal reference is disabled
|
||||
#define VREF_NP_3P000 0b0000 // +/- 3.000 x Vref
|
||||
#define VREF_NP_2P500 0b0001 // +/- 2.500 x Vref
|
||||
#define VREF_NP_1P500 0b0010 // +/- 1.500 x Vref
|
||||
#define VREF_NP_1P250 0b0011 // +/- 1.250 x Vref
|
||||
#define VREF_NP_0P625 0b0100 // +/- 0.625 x Vref
|
||||
#define VREF_P_3P000 0b1000 // 3.000 x Vref
|
||||
#define VREF_P_2P500 0b1001 // 2.500 x Vref
|
||||
#define VREF_P_1P500 0b1010 // 1.500 x Vref
|
||||
#define VREF_P_1P250 0b1011 // 1.250 x Vref
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t data;
|
||||
uint16_t addr : 9;
|
||||
uint16_t cmd : 7;
|
||||
};
|
||||
uint32_t val;
|
||||
} opcode_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t data_val : 3;
|
||||
uint16_t par_en : 1;
|
||||
uint16_t : 4;
|
||||
uint16_t range_incl : 1;
|
||||
uint16_t : 1;
|
||||
uint16_t in_active_alarm_incl : 2;
|
||||
uint16_t vdd_active_alarm_incl : 2;
|
||||
uint16_t device_addr_incl : 1;
|
||||
uint16_t : 1;
|
||||
};
|
||||
uint16_t val;
|
||||
} dataout_ctl_t;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t range_sel : 4;
|
||||
uint16_t : 2;
|
||||
uint16_t intref_dis : 1;
|
||||
uint16_t : 1;
|
||||
uint16_t : 8;
|
||||
};
|
||||
uint16_t val;
|
||||
} range_sel_t;
|
||||
static dataout_ctl_t m_dataout_ctl;
|
||||
static range_sel_t m_range_sel;
|
||||
static uint32_t m_channel = 0;
|
||||
static void write_cmd(uint32_t cmd, uint32_t addr, uint16_t data)
|
||||
{
|
||||
opcode_t opcode = {
|
||||
.cmd = cmd,
|
||||
.addr = addr,
|
||||
.data = data,
|
||||
};
|
||||
uint32_t tx = __REV(opcode.val);
|
||||
spim_xfer(CS_ADC_PIN, NRF_SPIM_MODE_0, (uint8_t *)&tx, sizeof(tx), NULL, 0);
|
||||
}
|
||||
|
||||
static uint16_t read_hword(void)
|
||||
{
|
||||
uint32_t tx = 0x00000000;
|
||||
uint32_t rx = 0x00000000;
|
||||
spim_xfer(CS_ADC_PIN, NRF_SPIM_MODE_0, (uint8_t *)&tx, sizeof(tx), (uint8_t *)&rx, sizeof(rx));
|
||||
rx = __REV(rx);
|
||||
return rx >> 16;
|
||||
}
|
||||
|
||||
static uint32_t read_word(void)
|
||||
{
|
||||
uint32_t tx = 0x00000000;
|
||||
uint32_t rx = 0x00000000;
|
||||
spim_xfer(CS_ADC_PIN, NRF_SPIM_MODE_0, (uint8_t *)&tx, sizeof(tx), (uint8_t *)&rx, sizeof(rx));
|
||||
rx = __REV(rx);
|
||||
return rx;
|
||||
}
|
||||
|
||||
static int write_dev_id(uint32_t new_id)
|
||||
{
|
||||
write_cmd(ADS8691_CMD_WRITE, DEVICE_ID_REG + 2, new_id & 0b1111);
|
||||
write_cmd(ADS8691_CMD_READ_HWORD, DEVICE_ID_REG + 2, 0x0000);
|
||||
return read_hword() == (new_id & 0b1111) ? 0 : -1;
|
||||
}
|
||||
|
||||
uint32_t read_dev_id(void)
|
||||
{
|
||||
write_cmd(ADS8691_CMD_READ_HWORD, DEVICE_ID_REG + 2, 0x0000);
|
||||
return read_hword();
|
||||
}
|
||||
|
||||
static int write_dataout_ctrl(dataout_ctl_t *dataout_ctl)
|
||||
{
|
||||
write_cmd(ADS8691_CMD_WRITE, DATAOUT_CTL_REG, dataout_ctl->val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_dataout_ctrl(dataout_ctl_t *dataout_ctl)
|
||||
{
|
||||
write_cmd(ADS8691_CMD_READ_HWORD, DATAOUT_CTL_REG, 0x0000);
|
||||
dataout_ctl->val = read_hword();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_range_sel(range_sel_t *range_sel)
|
||||
{
|
||||
write_cmd(ADS8691_CMD_WRITE, RANGE_SEL_REG, range_sel->val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_range_sel(range_sel_t *range_sel)
|
||||
{
|
||||
write_cmd(ADS8691_CMD_READ_HWORD, DATAOUT_CTL_REG, 0x0000);
|
||||
range_sel->val = read_hword();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double adc_convert_volt(uint16_t range_sel, int32_t val_18bit)
|
||||
{
|
||||
// LSB[uV]
|
||||
#define LSB_VREF_NP_3P000 93.75
|
||||
#define LSB_VREF_NP_2P500 78.125
|
||||
#define LSB_VREF_NP_1P500 48.875
|
||||
#define LSB_VREF_NP_1P250 39.06
|
||||
#define LSB_VREF_NP_0P625 19.53
|
||||
#define LSB_VREF_P_3P000 46.875
|
||||
#define LSB_VREF_P_2P500 39.06
|
||||
#define LSB_VREF_P_1P500 23.43
|
||||
#define LSB_VREF_P_1P250 19.53
|
||||
|
||||
// FULL-SCALE RANGE[V]
|
||||
#define FSR_VREF_NP_3P000 24.576
|
||||
#define FSR_VREF_NP_2P500 20.48
|
||||
#define FSR_VREF_NP_1P500 12.288
|
||||
#define FSR_VREF_NP_1P250 10.24
|
||||
#define FSR_VREF_NP_0P625 5.12
|
||||
#define FSR_VREF_P_3P000 12.288
|
||||
#define FSR_VREF_P_2P500 10.24
|
||||
#define FSR_VREF_P_1P500 6.144
|
||||
#define FSR_VREF_P_1P250 5.12
|
||||
|
||||
double volt;
|
||||
|
||||
if (range_sel == VREF_NP_3P000)
|
||||
volt = (double)val_18bit * LSB_VREF_NP_3P000 / 1000000 - FSR_VREF_NP_3P000 / 2;
|
||||
else if (range_sel == VREF_NP_2P500)
|
||||
volt = (double)val_18bit * LSB_VREF_NP_2P500 / 1000000 - FSR_VREF_NP_2P500 / 2;
|
||||
else if (range_sel == VREF_NP_1P500)
|
||||
volt = (double)val_18bit * LSB_VREF_NP_1P500 / 1000000 - FSR_VREF_NP_1P500 / 2;
|
||||
else if (range_sel == VREF_NP_1P250)
|
||||
volt = (double)val_18bit * LSB_VREF_NP_1P250 / 1000000 - FSR_VREF_NP_1P250 / 2;
|
||||
else if (range_sel == VREF_NP_0P625)
|
||||
volt = (double)val_18bit * LSB_VREF_NP_0P625 / 1000000 - FSR_VREF_NP_0P625 / 2;
|
||||
else if (range_sel == VREF_P_3P000)
|
||||
volt = (double)val_18bit * LSB_VREF_P_3P000 / 1000000 - FSR_VREF_P_3P000 / 2;
|
||||
else if (range_sel == VREF_P_2P500)
|
||||
volt = (double)val_18bit * LSB_VREF_P_2P500 / 1000000 - FSR_VREF_P_2P500 / 2;
|
||||
else if (range_sel == VREF_P_1P500)
|
||||
volt = (double)val_18bit * LSB_VREF_P_1P500 / 1000000 - FSR_VREF_P_1P500 / 2;
|
||||
else if (range_sel == VREF_P_1P250)
|
||||
volt = (double)val_18bit * LSB_VREF_P_1P250 / 1000000 - FSR_VREF_P_1P250 / 2;
|
||||
|
||||
return volt;
|
||||
}
|
||||
|
||||
static int ads8691_read(uint32_t channel, int32_t *adc_val)
|
||||
{
|
||||
if (m_channel != channel)
|
||||
{
|
||||
m_channel = channel;
|
||||
nrf_gpio_pin_write(ADCA0_PIN, m_channel & (0x01 << 0));
|
||||
nrf_gpio_pin_write(ADCA1_PIN, m_channel & (0x01 << 1));
|
||||
nrf_gpio_pin_write(ADCA2_PIN, m_channel & (0x01 << 2));
|
||||
nrf_delay_us(100);
|
||||
}
|
||||
|
||||
read_word();
|
||||
|
||||
uint32_t val = read_word();
|
||||
*adc_val = val >> 14;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ads8691_read_milivolt(uint32_t channel, float *mv)
|
||||
{
|
||||
int32_t val = 0;
|
||||
ads8691_read(channel, &val);
|
||||
*mv = adc_convert_volt(m_range_sel.range_sel, val) * 1000.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ads8691_gain(adc_gain_t gain)
|
||||
{
|
||||
switch (gain)
|
||||
{
|
||||
case GAIN_3P000:
|
||||
m_range_sel.range_sel = VREF_NP_3P000;
|
||||
break;
|
||||
case GAIN_2P500:
|
||||
m_range_sel.range_sel = VREF_NP_2P500;
|
||||
break;
|
||||
case GAIN_1P500:
|
||||
m_range_sel.range_sel = VREF_NP_1P500;
|
||||
break;
|
||||
case GAIN_1P250:
|
||||
m_range_sel.range_sel = VREF_NP_1P250;
|
||||
break;
|
||||
case GAIN_0P625:
|
||||
m_range_sel.range_sel = VREF_NP_0P625;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
write_range_sel(&m_range_sel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ads8691_reset(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ads8691_init(void)
|
||||
{
|
||||
int ret = -1;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (read_dev_id() == 0b0101)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
if (write_dev_id(0b0101) == 0)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
read_dataout_ctrl(&m_dataout_ctl);
|
||||
read_range_sel(&m_range_sel);
|
||||
nrf_gpio_pin_write(ADCA0_PIN, m_channel & (0x01 << 0));
|
||||
nrf_gpio_pin_write(ADCA1_PIN, m_channel & (0x01 << 1));
|
||||
nrf_gpio_pin_write(ADCA2_PIN, m_channel & (0x01 << 2));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const adc_drv_if_t ads8691 = {
|
||||
.init = ads8691_init,
|
||||
.reset = ads8691_reset,
|
||||
.read = ads8691_read,
|
||||
.gain = ads8691_gain,
|
||||
.read_milivolt = ads8691_read_milivolt,
|
||||
};
|
||||
|
||||
#endif /* ! DEF_ADS8691_ENABLED */
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef __ADS8691_H__
|
||||
#define __ADS8691_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "adc_drv_if.h"
|
||||
|
||||
#if (DEF_ADS8691_ENABLED)
|
||||
|
||||
extern const adc_drv_if_t ads8691;
|
||||
|
||||
#endif /* ! DEF_ADS8691_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ADS8691_H__ */
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#include "apa102_2020.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_APA102_2020_ENABLED)
|
||||
|
||||
#define DISP_LED_COLOR 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t brightness : 5;
|
||||
uint8_t preamble : 3;
|
||||
struct led_color color;
|
||||
} led_t;
|
||||
|
||||
static led_t *p_led = NULL;
|
||||
static uint32_t led_count = 0;
|
||||
|
||||
const led_t led_default = {
|
||||
.brightness = 0b00000,
|
||||
.preamble = 0b111,
|
||||
.color = {
|
||||
.B = 0,
|
||||
.G = 0,
|
||||
.R = 0},
|
||||
};
|
||||
|
||||
static void apa102_led_write(uint8_t *pucData, uint32_t ulSize)
|
||||
{
|
||||
spi1_write(pucData, ulSize);
|
||||
}
|
||||
|
||||
int32_t apa102_led_set(uint32_t idx, struct led_color color, uint8_t brightness)
|
||||
{
|
||||
uint32_t start_frame = 0x00000000;
|
||||
uint32_t end_frame = 0xFFFFFFFF;
|
||||
p_led[idx].color = color;
|
||||
p_led[idx].brightness = brightness;
|
||||
|
||||
apa102_led_write((void *)&start_frame, sizeof(start_frame));
|
||||
apa102_led_write((void *)p_led, led_count * sizeof(*p_led));
|
||||
apa102_led_write((void *)&end_frame, sizeof(end_frame));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t apa102_init(uint32_t cnt)
|
||||
{
|
||||
uint32_t start_frame = 0x00000000;
|
||||
uint32_t end_frame = 0xFFFFFFFF;
|
||||
|
||||
led_count = cnt;
|
||||
p_led = pvPortMalloc(led_count * sizeof(*p_led));
|
||||
|
||||
for (int i = 0; i < led_count; i++)
|
||||
{
|
||||
p_led[i] = led_default;
|
||||
}
|
||||
|
||||
apa102_led_write((void *)&start_frame, sizeof(start_frame));
|
||||
apa102_led_write((void *)p_led, led_count * sizeof(*p_led));
|
||||
apa102_led_write((void *)&end_frame, sizeof(end_frame));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const led_drv_if_t apa102_drv = {
|
||||
.init = apa102_init,
|
||||
.set = apa102_led_set,
|
||||
};
|
||||
|
||||
#endif /* ! DEF_APA102_2020_ENABLED */
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef __APA102_2020_H__
|
||||
#define __APA102_2020_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "led_drv_if.h"
|
||||
|
||||
#if (DEF_APA102_2020_ENABLED)
|
||||
|
||||
extern const led_drv_if_t apa102_drv;
|
||||
|
||||
#endif /* ! DEF_APA102_2020_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __APA102_2020_H__ */
|
||||
+162
-57
@@ -1,4 +1,3 @@
|
||||
#pragma once
|
||||
#ifndef __APP_CONFIG_H__
|
||||
#define __APP_CONFIG_H__
|
||||
|
||||
@@ -22,9 +21,9 @@ extern "C"
|
||||
|
||||
// SEGGER-RTT
|
||||
#define SEGGER_RTT_SECTION ".segger_rtt"
|
||||
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 1
|
||||
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
|
||||
#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 1
|
||||
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4000
|
||||
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 2048
|
||||
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
|
||||
#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
|
||||
|
||||
@@ -103,83 +102,189 @@ extern "C"
|
||||
#define BLE_ADVERTISING_ENABLED 1
|
||||
|
||||
// BLE device name
|
||||
#define DEF_ELITE_EDC_15RE 0x00020107
|
||||
#define DEF_ELITE_EDC_15R2 0x00020108
|
||||
#define DEF_ELITE_EIS_10 0x00040100
|
||||
#define DEF_ELITE_EIS_11 0x00040101
|
||||
#define DEF_ELITE_EIS_MINI_10 0x00040102
|
||||
#define DEF_ELITE_MODEL DEF_ELITE_EIS_11
|
||||
#define DEF_ELITE_DEV 0x00000000
|
||||
#define DEF_ELITE_EDC_20 0x00020109
|
||||
#define DEF_PULSE_E_LOAD_10 0x00070000
|
||||
#define DEF_CURRENT_PULSE_GANERATOR_10 0x00080000
|
||||
#define DEF_ELITE_MODEL DEF_PULSE_E_LOAD_10
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_DEV)
|
||||
#define ELITE_DEVICE_NAME "Elite-Dev"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 0
|
||||
#define MAJOR_VERSION_NUMBER 0
|
||||
#define MINOR_VERSION_NUMBER 0
|
||||
|
||||
#define DEF_LED_COUNT 0
|
||||
#define DEF_LED_DRV_ENABLED 0
|
||||
#define DEF_APA102_2020_ENABLED 0
|
||||
|
||||
#define DEF_ADC_DRV_ENABLED 0
|
||||
#define DEF_ADS8691_ENABLED 0
|
||||
#define DEF_BULTIN_ADC_ENABED 0
|
||||
|
||||
#define DEF_DAC_DRV_ENABLED 0
|
||||
#define DEF_MAX5136_ENABLED 0
|
||||
|
||||
#define DEF_SW_DRV_ENABLED 0
|
||||
#define DEF_ADGS1412_ENABLED 0
|
||||
|
||||
#define DEF_FS_ENABLED 0
|
||||
#define DEF_FS_RTT_DIR 0
|
||||
#define DEF_GD25D10C_ENABLED 0
|
||||
|
||||
#define DEF_BTN_ENABLED 0
|
||||
|
||||
#define DEF_RTT_JSCOP_ENABLED 0
|
||||
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#define ELITE_DEVICE_NAME "Elite-EDC"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 9
|
||||
|
||||
#define DEF_LED_COUNT 12
|
||||
#define DEF_LED_DRV_ENABLED 1
|
||||
#define DEF_APA102_2020_ENABLED 1
|
||||
|
||||
#define DEF_ADC_DRV_ENABLED 1
|
||||
#define DEF_ADS8691_ENABLED 1
|
||||
#define DEF_BULTIN_ADC_ENABED 0
|
||||
|
||||
#define DEF_DAC_DRV_ENABLED 1
|
||||
#define DEF_MAX5136_ENABLED 1
|
||||
|
||||
#define DEF_SW_DRV_ENABLED 1
|
||||
#define DEF_ADGS1412_ENABLED 1
|
||||
|
||||
#define DEF_FS_ENABLED 0
|
||||
#define DEF_FS_RTT_DIR 0
|
||||
#define DEF_GD25D10C_ENABLED 0
|
||||
|
||||
#define DEF_BTN_ENABLED 1
|
||||
|
||||
#define DEF_RTT_JSCOP_ENABLED 0
|
||||
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
#define ELITE_DEVICE_NAME "Elite-PEL"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 9
|
||||
|
||||
#define DEF_LED_COUNT 0
|
||||
#define DEF_LED_DRV_ENABLED 0
|
||||
#define DEF_APA102_2020_ENABLED 0
|
||||
|
||||
#define DEF_ADC_DRV_ENABLED 1
|
||||
#define DEF_ADS8691_ENABLED 0
|
||||
#define DEF_BULTIN_ADC_ENABED 1
|
||||
|
||||
#define DEF_DAC_DRV_ENABLED 0
|
||||
#define DEF_MAX5136_ENABLED 0
|
||||
|
||||
#define DEF_SW_DRV_ENABLED 0
|
||||
#define DEF_ADGS1412_ENABLED 0
|
||||
|
||||
#define DEF_FS_ENABLED 0
|
||||
#define DEF_FS_RTT_DIR 0
|
||||
#define DEF_GD25D10C_ENABLED 0
|
||||
|
||||
#define DEF_BTN_ENABLED 0
|
||||
|
||||
#define DEF_RTT_JSCOP_ENABLED 0
|
||||
|
||||
#elif (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
#define ELITE_DEVICE_NAME "Elite-CPG"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 9
|
||||
|
||||
#define DEF_LED_COUNT 0
|
||||
#define DEF_LED_DRV_ENABLED 0
|
||||
#define DEF_APA102_2020_ENABLED 0
|
||||
|
||||
#define DEF_ADC_DRV_ENABLED 0
|
||||
#define DEF_ADS8691_ENABLED 0
|
||||
#define DEF_BULTIN_ADC_ENABED 0
|
||||
|
||||
#define DEF_DAC_DRV_ENABLED 0
|
||||
#define DEF_MAX5136_ENABLED 0
|
||||
|
||||
#define DEF_SW_DRV_ENABLED 0
|
||||
#define DEF_ADGS1412_ENABLED 0
|
||||
|
||||
#define DEF_FS_ENABLED 0
|
||||
#define DEF_FS_RTT_DIR 0
|
||||
#define DEF_GD25D10C_ENABLED 0
|
||||
|
||||
#define DEF_BTN_ENABLED 0
|
||||
|
||||
#define DEF_RTT_JSCOP_ENABLED 0
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_15RE)
|
||||
#define ELITE_DEVICE_NAME "EDC"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 7
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15R2)
|
||||
#define ELITE_DEVICE_NAME "EDC"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 8
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_10)
|
||||
#define ELITE_DEVICE_NAME "EIS"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 4
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 0
|
||||
#define BLE_EIS_ENABLED 1
|
||||
#define EIS_BLE_OBSERVER_PRIO 3
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_11)
|
||||
#define ELITE_DEVICE_NAME "EIS"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 4
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 1
|
||||
#define BLE_EIS_ENABLED 1
|
||||
#define EIS_BLE_OBSERVER_PRIO 3
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_MINI_10)
|
||||
#define ELITE_DEVICE_NAME "EIS"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 4
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
#define MINOR_VERSION_NUMBER 2
|
||||
#endif
|
||||
|
||||
#define ELITE_COMPANY_CODE "Elite"
|
||||
#define BLE_ELITE_SRV_ENABLED 1
|
||||
#define BLE_ELITE_OBSERVER_PRIO 3
|
||||
#define ELITE_UUID 0xFFF0
|
||||
#define ELITE_COMPANY_CODE "BPHS"
|
||||
#define ELITE_HW_VER \
|
||||
{ \
|
||||
MAJOR_PRODUCT_NUMBER, MINOR_PRODUCT_NUMBER, MAJOR_VERSION_NUMBER, MINOR_VERSION_NUMBER \
|
||||
}
|
||||
|
||||
// Maximum number of peripheral links.
|
||||
#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1
|
||||
#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1
|
||||
// Maximum number of central links.
|
||||
#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0
|
||||
#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0
|
||||
// Total link count.
|
||||
#define NRF_SDH_BLE_TOTAL_LINK_COUNT 1
|
||||
#define NRF_SDH_BLE_TOTAL_LINK_COUNT 1
|
||||
|
||||
// Enable GATT module.
|
||||
#define NRF_BLE_GATT_ENABLED 1
|
||||
#define NRF_BLE_GATT_ENABLED 1
|
||||
// Priority with which BLE events are dispatched to the GATT module.
|
||||
#define NRF_BLE_GATT_BLE_OBSERVER_PRIO 1
|
||||
#define NRF_BLE_GATT_BLE_OBSERVER_PRIO 1
|
||||
// Requested BLE GAP data length to be negotiated.
|
||||
#define NRF_SDH_BLE_GAP_DATA_LENGTH 251
|
||||
#define NRF_SDH_BLE_GAP_DATA_LENGTH 251
|
||||
// GAP event length. The time set aside for this connection on every connection interval in 1.25 ms units.
|
||||
#define NRF_SDH_BLE_GAP_EVENT_LENGTH (0xFFFF)
|
||||
#define NRF_SDH_BLE_GAP_EVENT_LENGTH (0xFFFF)
|
||||
// Static maximum MTU size.
|
||||
#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
|
||||
#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
|
||||
|
||||
// Enable ble device info module
|
||||
#define BLE_DIS_ENABLED 1
|
||||
#define BLE_DIS_ENABLED 1
|
||||
|
||||
// DFU
|
||||
#define NRF_DFU_TRANSPORT_BLE 1
|
||||
#define BLE_DFU_BLE_OBSERVER_PRIO 2
|
||||
#define NRF_PWR_MGMT_ENABLED 1
|
||||
#define NRF_DFU_TRANSPORT_BLE 1
|
||||
#define BLE_DFU_BLE_OBSERVER_PRIO 2
|
||||
#define NRF_PWR_MGMT_ENABLED 1
|
||||
|
||||
// Enable spim
|
||||
#define SPI_ENABLED 1
|
||||
#define SPI1_ENABLED 1
|
||||
#define SPI1_USE_EASY_DMA 1
|
||||
#define SPI2_ENABLED 1
|
||||
#define SPI2_USE_EASY_DMA 1
|
||||
#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 7
|
||||
#define NRFX_SPIM_MISO_PULL_CFG 3
|
||||
|
||||
// Enable twi(i2c)
|
||||
#define TWI_ENABLED 1
|
||||
#define TWI0_ENABLED 1
|
||||
#define TWI0_USE_EASY_DMA 1
|
||||
|
||||
// Enable gpiote
|
||||
#define NRFX_GPIOTE_ENABLED 1
|
||||
#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1
|
||||
#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 6
|
||||
|
||||
#define COUNT_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !__APP_CONFIG_H__
|
||||
#endif /* ! __APP_CONFIG_H__ */
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef __BLOCK_DEV_DRV_IF_H__
|
||||
#define __BLOCK_DEV_DRV_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BLOCK_DEV_SUCCESS (0)
|
||||
#define BLOCK_DEV_ERROR (-1)
|
||||
typedef struct
|
||||
{
|
||||
int (*init)(void);
|
||||
int (*reset)(void);
|
||||
int (*sect_erase)(uint32_t addr, uint32_t sect_cnt);
|
||||
int (*block_erase)(uint32_t addr, uint32_t block_cnt);
|
||||
int (*read_data)(uint8_t *p_dest, uint32_t addr, uint32_t size);
|
||||
int (*page_prog)(uint8_t *p_src, uint32_t addr, uint32_t page_cnt);
|
||||
const uint32_t page_size;
|
||||
const uint32_t sect_size;
|
||||
const uint32_t sect_count;
|
||||
const uint32_t block_size;
|
||||
const uint32_t block_count;
|
||||
const uint32_t page_per_sect;
|
||||
} block_dev_drv_if_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __BLOCK_DEV_DRV_IF_H__ */
|
||||
@@ -111,11 +111,12 @@
|
||||
<MaxBreakpointLimit>0</MaxBreakpointLimit>
|
||||
<EnableVerboseMode>true</EnableVerboseMode>
|
||||
<EnablePrettyPrinters>false</EnablePrettyPrinters>
|
||||
<EnableAbsolutePathReporting>true</EnableAbsolutePathReporting>
|
||||
</AdditionalGDBSettings>
|
||||
<DebugMethod>
|
||||
<ID>jlink-jtag</ID>
|
||||
<InterfaceID>com.sysprogs.debug.jlink.jlinksw</InterfaceID>
|
||||
<InterfaceSerialNumber>000682409936</InterfaceSerialNumber>
|
||||
<InterfaceSerialNumber>000801018887</InterfaceSerialNumber>
|
||||
<Configuration xsi:type="com.visualgdb.edp.segger.settings">
|
||||
<CommandLine>-select USB -device $$SYS:MCU_ID$$ -speed auto -if SWD</CommandLine>
|
||||
<ProgramMode>Enabled</ProgramMode>
|
||||
@@ -140,9 +141,17 @@
|
||||
<EnableVirtualHalts>false</EnableVirtualHalts>
|
||||
<DynamicAnalysisSettings />
|
||||
<EndOfStackSymbol>_estack</EndOfStackSymbol>
|
||||
<TimestampProviderTicksPerSecond>0</TimestampProviderTicksPerSecond>
|
||||
<TimestampProvider>com.sysprogs.arm.dwt</TimestampProvider>
|
||||
<TimestampProviderTicksPerSecond>64000000</TimestampProviderTicksPerSecond>
|
||||
<KeepConsoleAfterExit>false</KeepConsoleAfterExit>
|
||||
<UnusedStackFillPattern xsi:nil="true" />
|
||||
<RelatedExecutables>
|
||||
<RelatedExecutable>
|
||||
<Program>false</Program>
|
||||
<LoadSymbols>false</LoadSymbols>
|
||||
<ShowInLiveWatch>false</ShowInLiveWatch>
|
||||
</RelatedExecutable>
|
||||
</RelatedExecutables>
|
||||
<CheckInterfaceDrivers>true</CheckInterfaceDrivers>
|
||||
</Debug>
|
||||
</VisualGDBProjectSettings2>
|
||||
@@ -45,18 +45,29 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
|
||||
<ClCompile>
|
||||
<CLanguageStandard>GNU99</CLanguageStandard>
|
||||
<AdditionalIncludeDirectories>.;../bmd380_sdk/components/softdevice/s140/headers;../bmd380_sdk/components/softdevice/s140/headers/nrf52;../bmd380_sdk/external/segger_rtt;../bmd380_sdk/components/libraries/log;../bmd380_sdk/components/libraries/log/src;../bmd380_sdk/components/libraries/memobj;../bmd380_sdk/components/libraries/ringbuf;../bmd380_sdk/components/libraries/atomic;../bmd380_sdk/components/libraries/balloc;../bmd380_sdk/external/freertos/portable/CMSIS/nrf52;../bmd380_sdk/external/freertos/portable/GCC/nrf52;../bmd380_sdk/integration/nrfx;../bmd380_sdk/integration/nrfx/legacy;../bmd380_sdk/components/libraries/experimental_section_vars;../bmd380_sdk/components/libraries/strerror;../bmd380_sdk/external/freertos/source/include;../bmd380_sdk/components/softdevice/common;../bmd380_sdk/components/ble/common;../bmd380_sdk/components/ble/ble_advertising;../bmd380_sdk/components/libraries/atomic_flags;../bmd380_sdk/components/ble/ble_db_discovery;../bmd380_sdk/components/ble/ble_dtm;../bmd380_sdk/components/ble/ble_link_ctx_manager;../bmd380_sdk/components/ble/ble_racp;../bmd380_sdk/components/ble/ble_radio_notification;../bmd380_sdk/components/ble/ble_services/ble_ancs_c;../bmd380_sdk/components/ble/ble_services/ble_ans_c;../bmd380_sdk/components/ble/ble_services/ble_bas;../bmd380_sdk/components/ble/ble_services/ble_bas_c;../bmd380_sdk/components/ble/ble_services/ble_bps;../bmd380_sdk/components/ble/ble_services/ble_cscs;../bmd380_sdk/components/ble/ble_services/ble_cts_c;../bmd380_sdk/components/ble/ble_services/ble_dfu;../bmd380_sdk/components/ble/ble_services/ble_dis;../bmd380_sdk/components/ble/ble_services/ble_dis_c;../bmd380_sdk/components/ble/ble_services/ble_escs;../bmd380_sdk/components/ble/ble_services/ble_gls;../bmd380_sdk/components/ble/ble_services/ble_hids;../bmd380_sdk/components/ble/ble_services/ble_hrs;../bmd380_sdk/components/ble/ble_services/ble_hrs_c;../bmd380_sdk/components/ble/ble_services/ble_hts;../bmd380_sdk/components/ble/ble_services/ble_ias;../bmd380_sdk/components/ble/ble_services/ble_ias_c;../bmd380_sdk/components/ble/ble_services/ble_ipsp;../bmd380_sdk/components/ble/ble_services/ble_lbs;../bmd380_sdk/components/ble/ble_services/ble_lbs_c;../bmd380_sdk/components/ble/ble_services/ble_lls;../bmd380_sdk/components/ble/ble_services/ble_nus;../bmd380_sdk/components/ble/ble_services/ble_nus_c;../bmd380_sdk/components/ble/ble_services/ble_rscs;../bmd380_sdk/components/ble/ble_services/ble_rscs_c;../bmd380_sdk/components/ble/ble_services/ble_tps;../bmd380_sdk/components/ble/ble_services/eddystone;../bmd380_sdk/components/ble/ble_services/experimental_ble_lns;../bmd380_sdk/components/ble/ble_services/experimental_ble_ots;../bmd380_sdk/components/ble/ble_services/experimental_gatts_c;../bmd380_sdk/components/ble/ble_services/experimental_nrf_ble_cgms;../bmd380_sdk/components/ble/ble_services/experimental_nrf_ble_ots_c;../bmd380_sdk/components/ble/ble_services/nrf_ble_bms;../bmd380_sdk/components/ble/nrf_ble_gatt;../bmd380_sdk/components/ble/nrf_ble_gq;../bmd380_sdk/components/ble/nrf_ble_qwr;../bmd380_sdk/components/ble/nrf_ble_scan;../bmd380_sdk/components/ble/peer_manager;../bmd380_sdk/components/libraries/pwr_mgmt;%(ClCompile.AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEBUG=1;USE_APP_CONFIG=1;%(ClCompile.PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;../bmd380_sdk/components/softdevice/s140/headers;../bmd380_sdk/components/softdevice/s140/headers/nrf52;../bmd380_sdk/external/segger_rtt;../bmd380_sdk/components/libraries/log;../bmd380_sdk/components/libraries/log/src;../bmd380_sdk/components/libraries/memobj;../bmd380_sdk/components/libraries/ringbuf;../bmd380_sdk/components/libraries/atomic;../bmd380_sdk/components/libraries/balloc;../bmd380_sdk/external/freertos/portable/CMSIS/nrf52;../bmd380_sdk/external/freertos/portable/GCC/nrf52;../bmd380_sdk/integration/nrfx;../bmd380_sdk/integration/nrfx/legacy;../bmd380_sdk/components/libraries/experimental_section_vars;../bmd380_sdk/components/libraries/strerror;../bmd380_sdk/external/freertos/source/include;../bmd380_sdk/components/softdevice/common;../bmd380_sdk/components/ble/common;../bmd380_sdk/components/ble/ble_advertising;../bmd380_sdk/components/libraries/atomic_flags;../bmd380_sdk/components/ble/ble_db_discovery;../bmd380_sdk/components/ble/ble_dtm;../bmd380_sdk/components/ble/ble_link_ctx_manager;../bmd380_sdk/components/ble/ble_racp;../bmd380_sdk/components/ble/ble_radio_notification;../bmd380_sdk/components/ble/ble_services/ble_ancs_c;../bmd380_sdk/components/ble/ble_services/ble_ans_c;../bmd380_sdk/components/ble/ble_services/ble_bas;../bmd380_sdk/components/ble/ble_services/ble_bas_c;../bmd380_sdk/components/ble/ble_services/ble_bps;../bmd380_sdk/components/ble/ble_services/ble_cscs;../bmd380_sdk/components/ble/ble_services/ble_cts_c;../bmd380_sdk/components/ble/ble_services/ble_dfu;../bmd380_sdk/components/ble/ble_services/ble_dis;../bmd380_sdk/components/ble/ble_services/ble_dis_c;../bmd380_sdk/components/ble/ble_services/ble_escs;../bmd380_sdk/components/ble/ble_services/ble_gls;../bmd380_sdk/components/ble/ble_services/ble_hids;../bmd380_sdk/components/ble/ble_services/ble_hrs;../bmd380_sdk/components/ble/ble_services/ble_hrs_c;../bmd380_sdk/components/ble/ble_services/ble_hts;../bmd380_sdk/components/ble/ble_services/ble_ias;../bmd380_sdk/components/ble/ble_services/ble_ias_c;../bmd380_sdk/components/ble/ble_services/ble_ipsp;../bmd380_sdk/components/ble/ble_services/ble_lbs;../bmd380_sdk/components/ble/ble_services/ble_lbs_c;../bmd380_sdk/components/ble/ble_services/ble_lls;../bmd380_sdk/components/ble/ble_services/ble_nus;../bmd380_sdk/components/ble/ble_services/ble_nus_c;../bmd380_sdk/components/ble/ble_services/ble_rscs;../bmd380_sdk/components/ble/ble_services/ble_rscs_c;../bmd380_sdk/components/ble/ble_services/ble_tps;../bmd380_sdk/components/ble/ble_services/eddystone;../bmd380_sdk/components/ble/ble_services/experimental_ble_lns;../bmd380_sdk/components/ble/ble_services/experimental_ble_ots;../bmd380_sdk/components/ble/ble_services/experimental_gatts_c;../bmd380_sdk/components/ble/ble_services/experimental_nrf_ble_cgms;../bmd380_sdk/components/ble/ble_services/experimental_nrf_ble_ots_c;../bmd380_sdk/components/ble/ble_services/nrf_ble_bms;../bmd380_sdk/components/ble/nrf_ble_gatt;../bmd380_sdk/components/ble/nrf_ble_gq;../bmd380_sdk/components/ble/nrf_ble_qwr;../bmd380_sdk/components/ble/nrf_ble_scan;../bmd380_sdk/components/ble/peer_manager;../bmd380_sdk/components/libraries/pwr_mgmt;littlefs;%(ClCompile.AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEBUG=1;USE_APP_CONFIG=1;LFS_THREADSAFE=1;%(ClCompile.PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions />
|
||||
<CPPLanguageStandard />
|
||||
<Optimization>O0</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLinkerInputs>%(Link.AdditionalLinkerInputs)</AdditionalLinkerInputs>
|
||||
<LibrarySearchDirectories>%(Link.LibrarySearchDirectories)</LibrarySearchDirectories>
|
||||
<AdditionalLibraryNames>%(Link.AdditionalLibraryNames)</AdditionalLibraryNames>
|
||||
<AdditionalLinkerInputs>;%(Link.AdditionalLinkerInputs)</AdditionalLinkerInputs>
|
||||
<LibrarySearchDirectories>;%(Link.LibrarySearchDirectories)</LibrarySearchDirectories>
|
||||
<AdditionalLibraryNames>;%(Link.AdditionalLibraryNames)</AdditionalLibraryNames>
|
||||
<LinkerScript>nRF52840_XXAA_S140_reserve.lds</LinkerScript>
|
||||
<AdditionalOptions />
|
||||
</Link>
|
||||
<ToolchainSettingsContainer>
|
||||
<InstructionSet>THUMB</InstructionSet>
|
||||
</ToolchainSettingsContainer>
|
||||
<ToolchainSettingsContainer>
|
||||
<FloatABI>hard</FloatABI>
|
||||
</ToolchainSettingsContainer>
|
||||
<ToolchainSettingsContainer>
|
||||
<ARMFPU>fpv4-sp-d16</ARMFPU>
|
||||
<ARMCPU>cortex-m4</ARMCPU>
|
||||
</ToolchainSettingsContainer>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|VisualGDB'">
|
||||
<ClCompile>
|
||||
@@ -164,7 +175,8 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\integration\nrfx\legacy\nrf_drv_spi.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\integration\nrfx\legacy\nrf_drv_spis.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
|
||||
@@ -173,19 +185,47 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\integration\nrfx\legacy\nrf_drv_twi.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
|
||||
</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\integration\nrfx\legacy\nrf_drv_uart.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="eis_regular_data.c" />
|
||||
<ClCompile Include="adc_drv.c" />
|
||||
<ClCompile Include="adgs1412.c" />
|
||||
<ClCompile Include="ads8691.c" />
|
||||
<ClCompile Include="apa102_2020.c" />
|
||||
<ClCompile Include="btn.c" />
|
||||
<ClCompile Include="builtin_saadc.c" />
|
||||
<ClCompile Include="cpg.c" />
|
||||
<ClCompile Include="cpg10_dev_mode.c" />
|
||||
<ClCompile Include="cpg10_io.c" />
|
||||
<ClCompile Include="elite_board.c" />
|
||||
<ClCompile Include="dac_drv.c" />
|
||||
<ClCompile Include="elite_dev.c" />
|
||||
<ClCompile Include="edc20_cycle_iv_mode.c" />
|
||||
<ClCompile Include="fs.c" />
|
||||
<ClCompile Include="gd25d10c.c" />
|
||||
<ClCompile Include="max5136.c" />
|
||||
<ClCompile Include="edc20_io.c" />
|
||||
<ClCompile Include="edc20.c" />
|
||||
<ClCompile Include="elite.c" />
|
||||
<ClCompile Include="elite_adc.c" />
|
||||
<ClCompile Include="elite_dac.c" />
|
||||
<ClCompile Include="elite_correction.c" />
|
||||
<ClCompile Include="led_drv.c" />
|
||||
<ClCompile Include="le_adv.c" />
|
||||
<ClCompile Include="le_dfu.c" />
|
||||
<ClCompile Include="le_eis_srv.c" />
|
||||
<ClCompile Include="le_elite_srv.c" />
|
||||
<ClCompile Include="le_gap.c" />
|
||||
<ClCompile Include="le_gatt.c" />
|
||||
<ClCompile Include="le_srv.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="j_scop.c" />
|
||||
<ClCompile Include="pel.c" />
|
||||
<ClCompile Include="pel10_io.c" />
|
||||
<ClCompile Include="sw_drv.c" />
|
||||
<ClCompile Include="syscalls.c" />
|
||||
<None Include="nRF52811_XXAA_s140.lds" />
|
||||
<None Include="nRF52840_XXAA_S140_reserve.lds" />
|
||||
<None Include="nrf5x.props" />
|
||||
@@ -328,8 +368,40 @@
|
||||
<ClInclude Include="..\bmd380_sdk\integration\nrfx\nrfx_config.h" />
|
||||
<ClInclude Include="..\bmd380_sdk\integration\nrfx\nrfx_glue.h" />
|
||||
<ClInclude Include="..\bmd380_sdk\integration\nrfx\nrfx_log.h" />
|
||||
<ClInclude Include="adc_drv.h" />
|
||||
<ClInclude Include="adc_drv_if.h" />
|
||||
<ClInclude Include="adgs1412.h" />
|
||||
<ClInclude Include="ads8691.h" />
|
||||
<ClInclude Include="apa102_2020.h" />
|
||||
<ClInclude Include="app_config.h" />
|
||||
<ClInclude Include="block_dev_drv_if.h" />
|
||||
<ClInclude Include="btn.h" />
|
||||
<ClInclude Include="cpg.h" />
|
||||
<ClInclude Include="cpg10_dev_mode.h" />
|
||||
<ClInclude Include="cpg10_io.h" />
|
||||
<ClInclude Include="dac_drv.h" />
|
||||
<ClInclude Include="dac_drv_if.h" />
|
||||
<ClInclude Include="edc.h" />
|
||||
<ClInclude Include="edc20_io.h" />
|
||||
<ClInclude Include="eis.h" />
|
||||
<ClInclude Include="elite.h" />
|
||||
<ClInclude Include="elite_adc.h" />
|
||||
<ClInclude Include="elite_dac.h" />
|
||||
<ClInclude Include="elite_correction.h" />
|
||||
<ClInclude Include="elite_board.h" />
|
||||
<ClInclude Include="elite_dev.h" />
|
||||
<ClInclude Include="FreeRTOSConfig.h" />
|
||||
<ClInclude Include="elite_def.h" />
|
||||
<ClInclude Include="builtin_saadc.h" />
|
||||
<ClInclude Include="fs.h" />
|
||||
<ClInclude Include="gd25d10c.h" />
|
||||
<ClInclude Include="led_drv.h" />
|
||||
<ClInclude Include="led_drv_if.h" />
|
||||
<ClInclude Include="max5136.h" />
|
||||
<ClInclude Include="pel.h" />
|
||||
<ClInclude Include="pel10_io.h" />
|
||||
<ClInclude Include="sw_drv.h" />
|
||||
<ClInclude Include="sw_drv_if.h" />
|
||||
<ClInclude Include="sdk_config.h" />
|
||||
<ClInclude Include="radio_config.h" />
|
||||
<ClInclude Include="sdio_config.h" />
|
||||
@@ -586,5 +658,9 @@
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\common\ble_gatt_db.h" />
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\common\ble_sensor_location.h" />
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\common\ble_srv_common.h" />
|
||||
<ClCompile Include="littlefs\lfs.c" />
|
||||
<ClCompile Include="littlefs\lfs_util.c" />
|
||||
<ClInclude Include="littlefs\lfs.h" />
|
||||
<ClInclude Include="littlefs\lfs_util.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -232,41 +232,11 @@
|
||||
<Filter Include="Header files\ble\common">
|
||||
<UniqueIdentifier>{defffc43-551c-4791-967b-7d0aee507516}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source files\ble\nrf_ble_gatt">
|
||||
<UniqueIdentifier>{345707cc-7a27-4c28-94b4-19df7d90e78d}</UniqueIdentifier>
|
||||
<Filter Include="Source files\littlefs">
|
||||
<UniqueIdentifier>{7f850d36-a444-417b-bf03-8433324adaa4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header files\ble\nrf_ble_gatt">
|
||||
<UniqueIdentifier>{b6e27cec-5179-4ec4-8f4d-e7e9fbaabae8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header files\ble\ble_services">
|
||||
<UniqueIdentifier>{4153528a-d996-4c55-be9f-917ce26d6277}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source files\ble\ble_services">
|
||||
<UniqueIdentifier>{7abc8adc-4234-4ec2-a927-53d29690cfc0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source files\ble\ble_services\ble_dis">
|
||||
<UniqueIdentifier>{2cf242dc-b5b5-4aa3-b56f-92c1afd295a1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header files\ble\ble_services\ble_dis">
|
||||
<UniqueIdentifier>{e8688895-c809-46b5-a2ab-2bd49da33d45}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header files\atomic_flags">
|
||||
<UniqueIdentifier>{104f5151-8aba-4322-889f-18db11a159d5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source files\atomic_flags">
|
||||
<UniqueIdentifier>{8d9d4979-4f73-44d8-a1a3-2ffab500203f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header files\ble\ble_services\ble_dfu">
|
||||
<UniqueIdentifier>{66efbcba-2f2c-4f6b-88b7-373adf4cac3c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source files\ble\ble_services\ble_dfu">
|
||||
<UniqueIdentifier>{67ca4d15-7a65-482f-a7eb-a6f92d2e1bb4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source files\pwr_mgmt">
|
||||
<UniqueIdentifier>{0dee1448-4304-4fc9-ae41-f733003a27bf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header files\pwr_mgmt">
|
||||
<UniqueIdentifier>{9d008a9d-bd88-4a95-8bda-04ef32a7ce4b}</UniqueIdentifier>
|
||||
<Filter Include="Header files\littlefs">
|
||||
<UniqueIdentifier>{0203873a-9b27-4c14-8951-9bfadceafef5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -1356,37 +1326,121 @@
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\common\ble_srv_common.h">
|
||||
<Filter>Header files\ble\common</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="le_gatt.c">
|
||||
<ClCompile Include="..\bmd380_sdk\components\libraries\atomic_flags\nrf_atflags.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\ble_services\ble_dfu\ble_dfu.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\ble_services\ble_dfu\ble_dfu_unbonded.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\ble_services\ble_dis\ble_dis.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\nrf_ble_gatt\nrf_ble_gatt.c">
|
||||
<Filter>Source files\ble\nrf_ble_gatt</Filter>
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\ble_services\ble_dis\ble_dis.c">
|
||||
<Filter>Source files\ble\ble_services\ble_dis</Filter>
|
||||
<ClCompile Include="le_dfu.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="le_gatt.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="le_srv.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="le_eis_srv.c">
|
||||
<ClCompile Include="syscalls.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\libraries\atomic_flags\nrf_atflags.c">
|
||||
<Filter>Source files\atomic_flags</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="eis_regular_data.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\ble_services\ble_dfu\ble_dfu_unbonded.c">
|
||||
<Filter>Source files\ble\ble_services\ble_dfu</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\ble\ble_services\ble_dfu\ble_dfu.c">
|
||||
<Filter>Source files\ble\ble_services\ble_dfu</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\bmd380_sdk\components\libraries\pwr_mgmt\nrf_pwr_mgmt.c">
|
||||
<Filter>Source files\pwr_mgmt</Filter>
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="le_dfu.c">
|
||||
<ClCompile Include="le_elite_srv.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="apa102_2020.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="led_drv.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="max5136.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dac_drv.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="adc_drv.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ads8691.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="adgs1412.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="builtin_saadc.c.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sw_drv.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gd25d10c.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="littlefs\lfs.c">
|
||||
<Filter>Source files\littlefs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="littlefs\lfs_util.c">
|
||||
<Filter>Source files\littlefs</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="littlefs\lfs.h">
|
||||
<Filter>Header files\littlefs</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="littlefs\lfs_util.h">
|
||||
<Filter>Header files\littlefs</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="fs.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="j_scop.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="edc20.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="edc20_io.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="elite.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="elite_adc.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="elite_board.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="elite_correction.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="elite_dac.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pel10_io.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="btn.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="elite_dev.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pel.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="edc20_cycle_iv_mode.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -1639,20 +1693,110 @@
|
||||
<ClInclude Include="..\bmd380_sdk\components\softdevice\common\nrf_sdh_soc.h">
|
||||
<Filter>Header files\softdevice\common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\nrf_ble_gatt\nrf_ble_gatt.h">
|
||||
<Filter>Header files\ble\nrf_ble_gatt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\ble_services\ble_dis\ble_dis.h">
|
||||
<Filter>Header files\ble\ble_services\ble_dis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\libraries\atomic_flags\nrf_atflags.h">
|
||||
<Filter>Header files\atomic_flags</Filter>
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\ble_services\ble_dfu\ble_dfu.h">
|
||||
<Filter>Header files\ble\ble_services\ble_dfu</Filter>
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\ble_services\ble_dis\ble_dis.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\nrf_ble_gatt\nrf_ble_gatt.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bmd380_sdk\components\libraries\pwr_mgmt\nrf_pwr_mgmt.h">
|
||||
<Filter>Header files\pwr_mgmt</Filter>
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="apa102_2020.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="led_drv.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="led_drv_if.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dac_drv_if.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="max5136.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dac_drv.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="adc_drv.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="adc_drv_if.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ads8691.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="adgs1412.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="builtin_saadc.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sw_drv.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sw_drv_if.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gd25d10c.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="block_dev_drv_if.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fs.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="board_pulse_e_load01.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="edc.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="edc20_io.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="eis.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite_adc.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite_board.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite_correction.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite_dac.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite_def.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pel10_io.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="btn.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="elite_dev.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pel.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "nrfx_gpiote.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
|
||||
#include "elite_board.h"
|
||||
#include "led_drv.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_BTN_ENABLED)
|
||||
|
||||
#define TIME_DEBOUNCE pdMS_TO_TICKS(25)
|
||||
#define TIME_CLICK_INTERVAL pdMS_TO_TICKS(200)
|
||||
#define TIME_PRESS_LONG pdMS_TO_TICKS(1500)
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static TaskHandle_t btn_task_handle = NULL;
|
||||
|
||||
static void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t xPin, nrf_gpiote_polarity_t ePolarity)
|
||||
{
|
||||
uint32_t pins = nrf_gpio_pin_read(SHUT_DOWN_PIN);
|
||||
if (__get_IPSR() != 0)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(btn_task_handle, pins, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
else
|
||||
{
|
||||
xTaskNotify(btn_task_handle, xPin, eSetValueWithOverwrite);
|
||||
}
|
||||
}
|
||||
|
||||
static bool wait_pressed(TickType_t xTimeout)
|
||||
{
|
||||
uint32_t pins;
|
||||
do {
|
||||
if (!xTaskNotifyWait(0, 0, &pins, xTimeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
} while (xTaskNotifyWait(0, 0, &pins, TIME_DEBOUNCE));
|
||||
} while (pins);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool wait_released(TickType_t xTimeout)
|
||||
{
|
||||
uint32_t pins;
|
||||
do {
|
||||
if (!xTaskNotifyWait(0, 0, &pins, xTimeout))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
} while (xTaskNotifyWait(0, 0, &pins, TIME_DEBOUNCE));
|
||||
} while (!pins);
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
typedef enum
|
||||
{
|
||||
BTN_EVENT_SHORTx1,
|
||||
BTN_EVENT_SHORTx2,
|
||||
BTN_EVENT_SHORTx3,
|
||||
BTN_EVENT_LONG,
|
||||
} BtnEvent_t;
|
||||
|
||||
static BtnEvent_t btn_event(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
// drop previous/undefined clicks
|
||||
while (wait_pressed(TIME_CLICK_INTERVAL))
|
||||
{
|
||||
wait_released(portMAX_DELAY);
|
||||
}
|
||||
// wait for clicks
|
||||
wait_pressed(portMAX_DELAY);
|
||||
if (!wait_released(TIME_PRESS_LONG))
|
||||
{
|
||||
return BTN_EVENT_LONG;
|
||||
}
|
||||
for (BtnEvent_t e = BTN_EVENT_SHORTx1; e < BTN_EVENT_LONG; e++)
|
||||
{
|
||||
if (!wait_pressed(TIME_CLICK_INTERVAL))
|
||||
{
|
||||
return e;
|
||||
}
|
||||
if (!wait_released(TIME_PRESS_LONG))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btn_event_shortx1_cb(void)
|
||||
{
|
||||
NRF_LOG_INFO("BTN_EVENT_SHORTx1");
|
||||
const struct led_color color[6] = { LED_RED, LED_ORANGE, LED_YELLOW, LED_GREEN, LED_BLUE, LED_PURPLE };
|
||||
static int idx = 0;
|
||||
led_set(color[idx++ % COUNTOF(color)]);
|
||||
}
|
||||
|
||||
static void btn_event_shortx2_cb(void)
|
||||
{
|
||||
NRF_LOG_INFO("BTN_EVENT_SHORTx2");
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
led_set(LED_OFF);
|
||||
vTaskDelay(pdMS_TO_TICKS(250));
|
||||
led_set(LED_BLUE);
|
||||
vTaskDelay(pdMS_TO_TICKS(250));
|
||||
}
|
||||
led_set(LED_IDEL_DISCONNECT);
|
||||
}
|
||||
|
||||
static void btn_event_shortx3_cb(void)
|
||||
{
|
||||
NRF_LOG_INFO("BTN_EVENT_SHORTx3");
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
led_set(LED_OFF);
|
||||
vTaskDelay(pdMS_TO_TICKS(250));
|
||||
led_set(LED_CYAN);
|
||||
vTaskDelay(pdMS_TO_TICKS(250));
|
||||
led_set(LED_IDEL_DISCONNECT);
|
||||
}
|
||||
led_set(LED_IDEL_DISCONNECT);
|
||||
}
|
||||
|
||||
static void btn_event_long(void)
|
||||
{
|
||||
NRF_LOG_INFO("BTN_EVENT_LONG");
|
||||
led_set(LED_ORANGE);
|
||||
if (!wait_released(TIME_PRESS_LONG))
|
||||
{
|
||||
led_set(LED_OFF);
|
||||
elite_board_power_off();
|
||||
}
|
||||
led_set(LED_IDEL_DISCONNECT);
|
||||
}
|
||||
|
||||
static void btn_task(void *pvArg)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
switch (btn_event())
|
||||
{
|
||||
case BTN_EVENT_SHORTx1:
|
||||
btn_event_shortx1_cb();
|
||||
break;
|
||||
case BTN_EVENT_SHORTx2:
|
||||
btn_event_shortx2_cb();
|
||||
break;
|
||||
case BTN_EVENT_SHORTx3:
|
||||
btn_event_shortx3_cb();
|
||||
break;
|
||||
case BTN_EVENT_LONG:
|
||||
btn_event_long();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btn_init(void)
|
||||
{
|
||||
nrfx_gpiote_in_config_t config = {
|
||||
.hi_accuracy = 1,
|
||||
.is_watcher = 0,
|
||||
.pull = NRF_GPIO_PIN_NOPULL,
|
||||
.sense = NRF_GPIOTE_POLARITY_TOGGLE,
|
||||
.skip_gpio_setup = 0
|
||||
};
|
||||
|
||||
nrfx_gpiote_init();
|
||||
|
||||
nrfx_gpiote_in_init(SHUT_DOWN_PIN, &config, nrfx_gpiote_evt_handler);
|
||||
|
||||
nrfx_gpiote_in_event_enable(SHUT_DOWN_PIN, true);
|
||||
|
||||
xTaskCreate(btn_task, "btn", 256, NULL, 3, &btn_task_handle);
|
||||
}
|
||||
|
||||
#endif /* ! DEF_BTN_ENABLED */
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef __BTN_H__
|
||||
#define __BTN_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
#if (DEF_BTN_ENABLED)
|
||||
void btn_init(void);
|
||||
#else
|
||||
#define btn_init()
|
||||
#endif /* DEF_BTN_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __BTN_H__ */
|
||||
+341
@@ -0,0 +1,341 @@
|
||||
#include "builtin_saadc.h"
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_saadc.h"
|
||||
|
||||
#define VERF (0.60)
|
||||
|
||||
static uint32_t m_gain = NRF_SAADC_GAIN1_6;
|
||||
static int read(uint32_t channel, int32_t *adc_val);
|
||||
static int init(void)
|
||||
{
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/* config resolution */
|
||||
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit;
|
||||
/* auto calibration ssadc */
|
||||
NRF_SAADC->EVENTS_CALIBRATEDONE = 0;
|
||||
NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_CALIBRATEDONE == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reset(void)
|
||||
{
|
||||
// Do nothing...
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float adc_convert_milivolt(uint16_t range_sel, int32_t val_14bit, bool is_diff)
|
||||
{
|
||||
float volt;
|
||||
float gain;
|
||||
float vref;
|
||||
uint32_t m = is_diff ? 1 : 0;
|
||||
|
||||
switch (range_sel)
|
||||
{
|
||||
case NRF_SAADC_GAIN1_6:
|
||||
gain = 1.0 / 6.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN1_5:
|
||||
gain = 1.0 / 5.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN1_4:
|
||||
gain = 1.0 / 4.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN1_3:
|
||||
gain = 1.0 / 3.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN1_2:
|
||||
gain = 1.0 / 2.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN1:
|
||||
gain = 1.0 / 1.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN2:
|
||||
gain = 2.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
case NRF_SAADC_GAIN4:
|
||||
gain = 4.0;
|
||||
vref = VERF;
|
||||
break;
|
||||
}
|
||||
|
||||
// differential V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 1) - V(N)
|
||||
// single end V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 0)
|
||||
|
||||
volt = ((float)val_14bit * 1000.0) * (vref / gain) / (0x01 << (14 - m));
|
||||
|
||||
return volt;
|
||||
}
|
||||
|
||||
static int read(uint32_t channel, int32_t *adc_val)
|
||||
{
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/*
|
||||
ref: p.381, nrf52840_PS_v1.1.pdf
|
||||
Note: Oversampling should only be used when a single input channel is enabled, as averaging is
|
||||
performed over all enabled channels.
|
||||
*/
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED;
|
||||
/* config analog input */
|
||||
NRF_SAADC->CH[0].PSELP = NRF_SAADC_INPUT_AIN0 + channel;
|
||||
NRF_SAADC->CH[0].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[0].CONFIG =
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) |
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) |
|
||||
(m_gain << SAADC_CH_CONFIG_GAIN_Pos) |
|
||||
(NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) |
|
||||
(NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) |
|
||||
(NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(NRF_SAADC_BURST_DISABLED << SAADC_CH_CONFIG_BURST_Pos);
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* read single channel */
|
||||
uint16_t val = 0;
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val;
|
||||
NRF_SAADC->RESULT.MAXCNT = 1;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_END == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* copy value */
|
||||
*adc_val = val;
|
||||
adc_convert_milivolt(m_gain, *adc_val, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_channels(uint32_t *p_channel, int32_t *adc_val, uint32_t count)
|
||||
{
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/*
|
||||
ref: p.381, nrf52840_PS_v1.1.pdf
|
||||
Note: Oversampling should only be used when a single input channel is enabled, as averaging is
|
||||
performed over all enabled channels.
|
||||
*/
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED;
|
||||
/* config analog inputs */
|
||||
for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++)
|
||||
{
|
||||
if (i < count)
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_channel[i];
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG =
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) |
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) |
|
||||
(m_gain << SAADC_CH_CONFIG_GAIN_Pos) |
|
||||
(NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) |
|
||||
(NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) |
|
||||
(NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(NRF_SAADC_BURST_DISABLED << SAADC_CH_CONFIG_BURST_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG = 0;
|
||||
}
|
||||
}
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* start convert */
|
||||
uint16_t val[16] = { 0 };
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val[0];
|
||||
NRF_SAADC->RESULT.MAXCNT = count;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_END == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* copy values */
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
adc_val[i] = val[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_channels_ex(uint32_t *p_channel, int32_t *adc_val, uint32_t count, void (*preliminary_callback)(void))
|
||||
{
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/*
|
||||
ref: p.381, nrf52840_PS_v1.1.pdf
|
||||
Note: Oversampling should only be used when a single input channel is enabled, as averaging is
|
||||
performed over all enabled channels.
|
||||
*/
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED;
|
||||
/* config analog inputs */
|
||||
for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++)
|
||||
{
|
||||
if (i < count)
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_channel[i];
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG =
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) |
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) |
|
||||
(m_gain << SAADC_CH_CONFIG_GAIN_Pos) |
|
||||
(NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) |
|
||||
(NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) |
|
||||
(NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(NRF_SAADC_BURST_DISABLED << SAADC_CH_CONFIG_BURST_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG = 0;
|
||||
}
|
||||
}
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* disable irq */
|
||||
__disable_irq();
|
||||
/* do preliminary job */
|
||||
if (preliminary_callback)
|
||||
{
|
||||
preliminary_callback();
|
||||
}
|
||||
/* start convert */
|
||||
int16_t val[COUNTOF(NRF_SAADC->CH)] = { 0 };
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val[0];
|
||||
NRF_SAADC->RESULT.MAXCNT = count;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
/* enabl irq */
|
||||
__enable_irq();
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_END == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* copy values */
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
adc_val[i] = val[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gain(adc_gain_t gain)
|
||||
{
|
||||
int ret;
|
||||
switch (gain)
|
||||
{
|
||||
case GAIN_1P000:
|
||||
m_gain = NRF_SAADC_GAIN1_6;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_1P200:
|
||||
m_gain = NRF_SAADC_GAIN1_5;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_1P500:
|
||||
m_gain = NRF_SAADC_GAIN1_4;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_2P000:
|
||||
m_gain = NRF_SAADC_GAIN1_3;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_3P000:
|
||||
m_gain = NRF_SAADC_GAIN1_2;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_6P000:
|
||||
m_gain = NRF_SAADC_GAIN1;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_12P000:
|
||||
m_gain = NRF_SAADC_GAIN2;
|
||||
ret = 0;
|
||||
break;
|
||||
case GAIN_24P000:
|
||||
m_gain = NRF_SAADC_GAIN4;
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
m_gain = SAADC_CH_CONFIG_GAIN_Gain1_6;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_multiple_milivolt_ex(uint32_t *p_channels, float *p_val, uint32_t count, void(*preliminary_action))
|
||||
{
|
||||
int32_t int_val[16];
|
||||
double f_val[16];
|
||||
|
||||
if (read_channels_ex(p_channels, int_val, count, preliminary_action) != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
p_val[i] = adc_convert_milivolt(m_gain, int_val[i], false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const adc_drv_if_t builtin_saadc = {
|
||||
.init = init,
|
||||
.reset = reset,
|
||||
.read = read,
|
||||
.gain = gain,
|
||||
.read_multiple_channels = read_channels,
|
||||
.read_multiple_channels_ex = read_channels_ex,
|
||||
.read_multiple_milivolt_ex = read_multiple_milivolt_ex,
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef __BUILTIN_SAADC_H__
|
||||
#define __BUILTIN_SAADC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "adc_drv_if.h"
|
||||
|
||||
extern const adc_drv_if_t builtin_saadc;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __BUILTIN_SAADC_H__ */
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "cpg10_dev_mode.h"
|
||||
#include "pel.h"
|
||||
#include "pel10_io.h"
|
||||
|
||||
#include "elite_def.h"
|
||||
|
||||
#include "nrf_delay.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
|
||||
#define VERSION_DATE_YEAR 24
|
||||
#define VERSION_DATE_MONTH 5
|
||||
#define VERSION_DATE_DAY 21
|
||||
#define VERSION_DATE_HOUR 18
|
||||
#define VERSION_DATE_MINUTE 39
|
||||
static void cis_version(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
uint8_t cis_ver[] = {
|
||||
CIS_VERSION,
|
||||
VERSION_DATE_YEAR,
|
||||
VERSION_DATE_MONTH,
|
||||
VERSION_DATE_DAY,
|
||||
VERSION_DATE_HOUR,
|
||||
VERSION_DATE_MINUTE,
|
||||
};
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)cis_ver, sizeof(cis_ver));
|
||||
}
|
||||
|
||||
static void vis_rst(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
}
|
||||
|
||||
void dev_mode(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint16_t magic : 16;
|
||||
uint8_t dev_opcode;
|
||||
uint8_t function_opcode;
|
||||
uint8_t param[];
|
||||
} *p_ins = (void *)ins;
|
||||
|
||||
switch (p_ins->dev_opcode)
|
||||
{
|
||||
case 0x90:
|
||||
dev_mode_set_cpg10_electrodes(ins);
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
dev_mode_gpio_function(ins);
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
// spi
|
||||
break;
|
||||
|
||||
case 0xA2:
|
||||
// i2c
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const elite_instance_t cpg_elite_instance = {
|
||||
.cis_func = {
|
||||
[CIS_VERSION] = cis_version,
|
||||
},
|
||||
.vis_func = {
|
||||
[VIS_RST] = vis_rst,
|
||||
},
|
||||
.ris_func = {
|
||||
[DEV_MODE] = dev_mode,
|
||||
}
|
||||
};
|
||||
|
||||
const elite_instance_t *cpg_init(void)
|
||||
{
|
||||
return &cpg_elite_instance;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __CPG_H__
|
||||
#define __CPG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
const elite_instance_t *cpg_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __CPG_H__ */
|
||||
@@ -0,0 +1,264 @@
|
||||
#include "cpg10_dev_mode.h"
|
||||
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
|
||||
// The GPIO corresponding to the pin
|
||||
const uint32_t pin_to_gpio_table[] = {
|
||||
[6] = NRF_GPIO_PIN_MAP(0, 22),
|
||||
[8] = NRF_GPIO_PIN_MAP(0, 25),
|
||||
[9] = NRF_GPIO_PIN_MAP(0, 19),
|
||||
[10] = NRF_GPIO_PIN_MAP(0, 21),
|
||||
[11] = NRF_GPIO_PIN_MAP(1, 00),
|
||||
[12] = NRF_GPIO_PIN_MAP(0, 18),
|
||||
[13] = NRF_GPIO_PIN_MAP(0, 17),
|
||||
[14] = NRF_GPIO_PIN_MAP(0, 20),
|
||||
[16] = NRF_GPIO_PIN_MAP(0, 14),
|
||||
[17] = NRF_GPIO_PIN_MAP(0, 13),
|
||||
[18] = NRF_GPIO_PIN_MAP(0, 11),
|
||||
[20] = NRF_GPIO_PIN_MAP(0, 15),
|
||||
[25] = NRF_GPIO_PIN_MAP(1, 8),
|
||||
[26] = NRF_GPIO_PIN_MAP(0, 12),
|
||||
[27] = NRF_GPIO_PIN_MAP(0, 7),
|
||||
[28] = NRF_GPIO_PIN_MAP(1, 9),
|
||||
[29] = NRF_GPIO_PIN_MAP(0, 8),
|
||||
[30] = NRF_GPIO_PIN_MAP(0, 6),
|
||||
[31] = NRF_GPIO_PIN_MAP(0, 5),
|
||||
[32] = NRF_GPIO_PIN_MAP(0, 27),
|
||||
[33] = NRF_GPIO_PIN_MAP(0, 26),
|
||||
[34] = NRF_GPIO_PIN_MAP(0, 4),
|
||||
[36] = NRF_GPIO_PIN_MAP(0, 1),
|
||||
[37] = NRF_GPIO_PIN_MAP(0, 29),
|
||||
[38] = NRF_GPIO_PIN_MAP(0, 0),
|
||||
[39] = NRF_GPIO_PIN_MAP(0, 31),
|
||||
[40] = NRF_GPIO_PIN_MAP(1, 15),
|
||||
[41] = NRF_GPIO_PIN_MAP(0, 2),
|
||||
[42] = NRF_GPIO_PIN_MAP(0, 30),
|
||||
[43] = NRF_GPIO_PIN_MAP(0, 28),
|
||||
[44] = NRF_GPIO_PIN_MAP(1, 12),
|
||||
[45] = NRF_GPIO_PIN_MAP(1, 14),
|
||||
[46] = NRF_GPIO_PIN_MAP(0, 3),
|
||||
[47] = NRF_GPIO_PIN_MAP(1, 13),
|
||||
[48] = NRF_GPIO_PIN_MAP(1, 3),
|
||||
[49] = NRF_GPIO_PIN_MAP(1, 10),
|
||||
[50] = NRF_GPIO_PIN_MAP(1, 6),
|
||||
[51] = NRF_GPIO_PIN_MAP(1, 11),
|
||||
[52] = NRF_GPIO_PIN_MAP(0, 10),
|
||||
[53] = NRF_GPIO_PIN_MAP(0, 9),
|
||||
[59] = NRF_GPIO_PIN_MAP(1, 2),
|
||||
[60] = NRF_GPIO_PIN_MAP(0, 24),
|
||||
[61] = NRF_GPIO_PIN_MAP(0, 23),
|
||||
[62] = NRF_GPIO_PIN_MAP(0, 16),
|
||||
};
|
||||
|
||||
static uint32_t bmd380pins_convert_to_gpio(uint32_t pin)
|
||||
{
|
||||
uint32_t gpio;
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 6:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 20:
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
case 36:
|
||||
case 37:
|
||||
case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 50:
|
||||
case 51:
|
||||
case 52:
|
||||
case 53:
|
||||
case 59:
|
||||
case 60:
|
||||
case 61:
|
||||
case 62:
|
||||
gpio = pin_to_gpio_table[pin];
|
||||
break;
|
||||
default:
|
||||
gpio = UNDEF_GPIO;
|
||||
NRF_LOG_INFO("UNDEF_GPIO: pin %d can't convert to gpio number", pin);
|
||||
break;
|
||||
}
|
||||
|
||||
return gpio;
|
||||
}
|
||||
|
||||
static void set_bmd380_pin_signal(uint32_t pin, uint32_t high_low)
|
||||
{
|
||||
uint32_t gpio = bmd380pins_convert_to_gpio(pin);
|
||||
|
||||
if (gpio != UNDEF_GPIO)
|
||||
{
|
||||
nrf_gpio_pin_write(gpio, high_low);
|
||||
NRF_LOG_INFO("set pin %d (gpio %d) = %d", pin, gpio, high_low);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
dev_mode_gpio_function
|
||||
(1)0x3000FFA000ppss
|
||||
-func: set_bmd380_pin_signal
|
||||
-pp: pin number 06h-3Fh
|
||||
06h: P0.22_GPIO
|
||||
08h: P0.25_GPIO
|
||||
......
|
||||
3Eh:P0.16_GPIO
|
||||
-ss: signal 00h-01h
|
||||
00h: low
|
||||
01h: high
|
||||
*/
|
||||
void dev_mode_gpio_function(uint8_t *ins)
|
||||
{
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint16_t magic : 16;
|
||||
uint8_t dev_opcode;
|
||||
uint8_t gpio_function_opcode;
|
||||
uint8_t param[];
|
||||
} *p_ins = (void *)ins;
|
||||
|
||||
switch (p_ins->gpio_function_opcode)
|
||||
{
|
||||
case 0x00: {
|
||||
uint32_t pin = p_ins->param[0];
|
||||
uint32_t high_low = p_ins->param[1];
|
||||
set_bmd380_pin_signal(pin, high_low);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ELECTRODES_A1HB1L 0
|
||||
#define ELECTRODES_A1LB1H 1
|
||||
#define ELECTRODES_A2HB2L 2
|
||||
#define ELECTRODES_A2LB2H 3
|
||||
#define ELECTRODES_A3HB3L 4
|
||||
#define ELECTRODES_A3LB3H 5
|
||||
#define ELECTRODES_A4HB4L 6
|
||||
#define ELECTRODES_A4LB4H 7
|
||||
static void cpg10_electrodes(uint32_t electrodes_mode)
|
||||
{
|
||||
switch (electrodes_mode)
|
||||
{
|
||||
case ELECTRODES_A1HB1L:
|
||||
nrf_gpio_pin_write(VB1H_PIN, 1);
|
||||
nrf_gpio_pin_write(VA1L_PIN, 0);
|
||||
nrf_gpio_pin_write(VA1H_PIN, 0);
|
||||
nrf_gpio_pin_write(VB1L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A1LB1H:
|
||||
nrf_gpio_pin_write(VA1H_PIN, 1);
|
||||
nrf_gpio_pin_write(VB1L_PIN, 0);
|
||||
nrf_gpio_pin_write(VB1H_PIN, 0);
|
||||
nrf_gpio_pin_write(VA1L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A2HB2L:
|
||||
nrf_gpio_pin_write(VB2H_PIN, 1);
|
||||
nrf_gpio_pin_write(VA2L_PIN, 0);
|
||||
nrf_gpio_pin_write(VA2H_PIN, 0);
|
||||
nrf_gpio_pin_write(VB2L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A2LB2H:
|
||||
nrf_gpio_pin_write(VA2H_PIN, 1);
|
||||
nrf_gpio_pin_write(VB2L_PIN, 0);
|
||||
nrf_gpio_pin_write(VB2H_PIN, 0);
|
||||
nrf_gpio_pin_write(VA2L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A3HB3L:
|
||||
nrf_gpio_pin_write(VB3H_PIN, 1);
|
||||
nrf_gpio_pin_write(VA3L_PIN, 0);
|
||||
nrf_gpio_pin_write(VA3H_PIN, 0);
|
||||
nrf_gpio_pin_write(VB3L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A3LB3H:
|
||||
nrf_gpio_pin_write(VA3H_PIN, 1);
|
||||
nrf_gpio_pin_write(VB3L_PIN, 0);
|
||||
nrf_gpio_pin_write(VB3H_PIN, 0);
|
||||
nrf_gpio_pin_write(VA3L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A4HB4L:
|
||||
nrf_gpio_pin_write(VB4H_PIN, 1);
|
||||
nrf_gpio_pin_write(VA4L_PIN, 0);
|
||||
nrf_gpio_pin_write(VA4H_PIN, 0);
|
||||
nrf_gpio_pin_write(VB4L_PIN, 1);
|
||||
break;
|
||||
|
||||
case ELECTRODES_A4LB4H:
|
||||
nrf_gpio_pin_write(VA4H_PIN, 1);
|
||||
nrf_gpio_pin_write(VB4L_PIN, 0);
|
||||
nrf_gpio_pin_write(VB4H_PIN, 0);
|
||||
nrf_gpio_pin_write(VA4L_PIN, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
dev_mode_set_cpg10_electrodes
|
||||
(1)0x3000FF90nn
|
||||
-func: dev_mode_set_cpg10_electrodes
|
||||
-nn: electrodes mode 01h-09h
|
||||
01h: ELECTRODES_A1HB1L
|
||||
02h: ELECTRODES_A1HB1L
|
||||
03h: ELECTRODES_A1LB1H
|
||||
04h: ELECTRODES_A2HB2L
|
||||
05h: ELECTRODES_A2LB2H
|
||||
06h: ELECTRODES_A3HB3L
|
||||
07h: ELECTRODES_A3LB3H
|
||||
08h: ELECTRODES_A4HB4L
|
||||
09h: ELECTRODES_A4LB4H
|
||||
*/
|
||||
void dev_mode_set_cpg10_electrodes(uint8_t *ins)
|
||||
{
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint16_t magic : 16;
|
||||
uint8_t dev_opcode;
|
||||
uint8_t electrodes_opcode;
|
||||
uint8_t param[];
|
||||
} *p_ins = (void *)ins;
|
||||
|
||||
cpg10_electrodes(p_ins->electrodes_opcode);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef __CPG10_DEV_MODE_H__
|
||||
#define __CPG10_DEV_MODE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "app_button.h"
|
||||
#include "elite_board.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
void dev_mode_set_cpg10_electrodes(uint8_t *ins);
|
||||
void dev_mode_gpio_function(uint8_t *ins);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __CPG10_DEV_MODE_H__ */
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
|
||||
void spim_xfer(uint32_t cs_pin,
|
||||
nrf_spim_mode_t spi_mode,
|
||||
uint8_t *p_tx_buffer,
|
||||
uint16_t tx_buffer_length,
|
||||
uint8_t *p_rx_buf,
|
||||
uint16_t rx_buffer_length)
|
||||
{
|
||||
__disable_irq();
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
switch (spi_mode)
|
||||
{
|
||||
default:
|
||||
case NRF_SPIM_MODE_0:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_1:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_2:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_3:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
NRF_SPIM3->TXD.MAXCNT = tx_buffer_length;
|
||||
NRF_SPIM3->TXD.PTR = (uint32_t)p_tx_buffer;
|
||||
|
||||
NRF_SPIM3->RXD.MAXCNT = rx_buffer_length;
|
||||
NRF_SPIM3->RXD.PTR = (uint32_t)p_rx_buf;
|
||||
|
||||
nrf_gpio_pin_clear(cs_pin);
|
||||
|
||||
NRF_SPIM3->EVENTS_END = 0;
|
||||
NRF_SPIM3->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SPIM3->EVENTS_END == 0);
|
||||
|
||||
nrf_gpio_pin_set(cs_pin);
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void cpg10_io_init(void)
|
||||
{
|
||||
const uint32_t pel_pins_default_high[] = {
|
||||
VA1H_PIN,
|
||||
VA2H_PIN,
|
||||
VA3H_PIN,
|
||||
VA4H_PIN,
|
||||
VB1H_PIN,
|
||||
VB2H_PIN,
|
||||
VB3H_PIN,
|
||||
VB4H_PIN,
|
||||
LED_R_PIN,
|
||||
LED_G_PIN,
|
||||
LED_B_PIN
|
||||
};
|
||||
|
||||
const uint32_t pel_pins_default_low[] = {
|
||||
ADPT0_S4_PIN,
|
||||
ADPT0_S3_PIN,
|
||||
ADPT0_S2_PIN,
|
||||
ADPT0_S1_PIN,
|
||||
ADPT_LE_PIN,
|
||||
ADPT_CLR_PIN,
|
||||
TW_SCKI_0_PIN,
|
||||
TW_SCKI_1_PIN,
|
||||
HV_EN_PIN,
|
||||
ADPT1_S1_PIN,
|
||||
VA1L_PIN,
|
||||
VA2L_PIN,
|
||||
VA3L_PIN,
|
||||
VA4L_PIN,
|
||||
VB1L_PIN,
|
||||
VB2L_PIN,
|
||||
VB3L_PIN,
|
||||
VB4L_PIN,
|
||||
ADPT1_S4_PIN,
|
||||
ADPT1_S3_PIN,
|
||||
ADPT1_S2_PIN
|
||||
};
|
||||
|
||||
for (int i = 0; i < COUNTOF(pel_pins_default_high); i++)
|
||||
{
|
||||
nrf_gpio_pin_set(pel_pins_default_high[i]);
|
||||
nrf_gpio_cfg_output(pel_pins_default_high[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < COUNTOF(pel_pins_default_low); i++)
|
||||
{
|
||||
nrf_gpio_pin_clear(pel_pins_default_low[i]);
|
||||
nrf_gpio_cfg_output(pel_pins_default_low[i]);
|
||||
}
|
||||
|
||||
nrf_gpio_cfg_input(AIN0_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
nrf_gpio_cfg_input(AIN1_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
|
||||
// Config spi module
|
||||
nrf_gpio_pin_set(CS_MEM_PIN);
|
||||
nrf_gpio_cfg_output(CS_MEM_PIN);
|
||||
nrf_gpio_pin_clear(SPIM_MOSI_PIN);
|
||||
nrf_gpio_cfg_output(SPIM_MOSI_PIN);
|
||||
nrf_gpio_pin_clear(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg_output(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg_input(SPIM_MISO_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
NRF_SPIM3->ORC = 0x00000000;
|
||||
NRF_SPIM3->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M32;
|
||||
NRF_SPIM3->CSNPOL = SPIM_CSNPOL_CSNPOL_LOW;
|
||||
NRF_SPIM3->IFTIMING.CSNDUR = 8;
|
||||
NRF_SPIM3->PSEL.CSN = CS_MEM_PIN;
|
||||
NRF_SPIM3->PSEL.SCK = SPIM_CLK_PIN;
|
||||
NRF_SPIM3->PSEL.MOSI = SPIM_MOSI_PIN;
|
||||
NRF_SPIM3->PSEL.MISO = SPIM_MISO_PIN;
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
}
|
||||
|
||||
#endif
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#ifndef __CPG10_IO_H__
|
||||
#define __CPG10_IO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
|
||||
#define UNDEF_GPIO 0xFFFFFFFF
|
||||
#define ADPT0_S4_PIN NRF_GPIO_PIN_MAP(0, 22)
|
||||
#define ADPT0_S3_PIN NRF_GPIO_PIN_MAP(0, 25)
|
||||
#define ADPT0_S2_PIN NRF_GPIO_PIN_MAP(0, 19)
|
||||
#define ADPT0_S1_PIN NRF_GPIO_PIN_MAP(0, 21)
|
||||
#define ADPT_LE_PIN NRF_GPIO_PIN_MAP(0, 17)
|
||||
#define ADPT_CLR_PIN NRF_GPIO_PIN_MAP(0, 20)
|
||||
#define TW_SCKI_0_PIN NRF_GPIO_PIN_MAP(0, 14)
|
||||
#define TW_SCKI_1_PIN NRF_GPIO_PIN_MAP(0, 13)
|
||||
#define HV_EN_PIN NRF_GPIO_PIN_MAP(0, 11)
|
||||
#define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 12)
|
||||
#define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 7)
|
||||
#define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
|
||||
#define ADPT1_S1_PIN NRF_GPIO_PIN_MAP(0, 6)
|
||||
#define CS_MEM_PIN NRF_GPIO_PIN_MAP(0, 27)
|
||||
#define VA1H_PIN NRF_GPIO_PIN_MAP(0, 26)
|
||||
#define VA1L_PIN NRF_GPIO_PIN_MAP(0, 4)
|
||||
#define VA2H_PIN NRF_GPIO_PIN_MAP(0, 1)
|
||||
#define VA2L_PIN NRF_GPIO_PIN_MAP(0, 29)
|
||||
#define VA3H_PIN NRF_GPIO_PIN_MAP(0, 0)
|
||||
#define VA3L_PIN NRF_GPIO_PIN_MAP(0, 31)
|
||||
#define VA4H_PIN NRF_GPIO_PIN_MAP(1, 15)
|
||||
#define VA4L_PIN NRF_GPIO_PIN_MAP(0, 2)
|
||||
#define AIN0_PIN NRF_GPIO_PIN_MAP(0, 30)
|
||||
#define AIN1_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
#define VB1H_PIN NRF_GPIO_PIN_MAP(1, 12)
|
||||
#define VB1L_PIN NRF_GPIO_PIN_MAP(1, 14)
|
||||
#define VB2H_PIN NRF_GPIO_PIN_MAP(0, 3)
|
||||
#define VB2L_PIN NRF_GPIO_PIN_MAP(1, 13)
|
||||
#define VB3H_PIN NRF_GPIO_PIN_MAP(1, 3)
|
||||
#define VB3L_PIN NRF_GPIO_PIN_MAP(1, 10)
|
||||
#define VB4H_PIN NRF_GPIO_PIN_MAP(1, 6)
|
||||
#define VB4L_PIN NRF_GPIO_PIN_MAP(1, 11)
|
||||
#define LED_R_PIN NRF_GPIO_PIN_MAP(0, 10)
|
||||
#define LED_G_PIN NRF_GPIO_PIN_MAP(0, 9)
|
||||
#define LED_B_PIN NRF_GPIO_PIN_MAP(1, 2)
|
||||
#define ADPT1_S4_PIN NRF_GPIO_PIN_MAP(0, 24)
|
||||
#define ADPT1_S3_PIN NRF_GPIO_PIN_MAP(0, 23)
|
||||
#define ADPT1_S2_PIN NRF_GPIO_PIN_MAP(0, 16)
|
||||
|
||||
void spim_xfer(uint32_t cs_pin,
|
||||
nrf_spim_mode_t spi_mode,
|
||||
uint8_t *p_tx_buffer,
|
||||
uint16_t tx_buffer_length,
|
||||
uint8_t *p_rx_buf,
|
||||
uint16_t rx_buffer_length);
|
||||
|
||||
void cpg10_io_init(void);
|
||||
|
||||
#endif /* ! DEF_ELITE_MODEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __CPG10_IO_H__ */
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "dac_drv.h"
|
||||
|
||||
#if (DEF_MAX5136_ENABLED)
|
||||
extern dac_drv_if_t max5316_drv;
|
||||
static const dac_drv_if_t *p_inst = &max5316_drv;
|
||||
#else
|
||||
static dac_drv_if_t *p_inst = NULL;
|
||||
#endif /* ! DEF_MAX5136_ENABLED */
|
||||
|
||||
#if (DEF_DAC_DRV_ENABLED)
|
||||
|
||||
int dac_init(void)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return DAC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->init();
|
||||
}
|
||||
|
||||
int dac_write(uint32_t channel_mask, int32_t dac_val)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return DAC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->write_mode(channel_mask, dac_val);
|
||||
}
|
||||
|
||||
int dac_load(uint32_t channel_mask)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return DAC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->ldac_mode(channel_mask);
|
||||
}
|
||||
|
||||
int dac_write_through(uint32_t channel_mask, int32_t dac_val)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return DAC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->write_through_mode(channel_mask, dac_val);
|
||||
}
|
||||
|
||||
#endif /* ! DEF_DAC_DRV_ENABLED */
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef __DAC_DRV_H__
|
||||
#define __DAC_DRV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "dac_drv_if.h"
|
||||
|
||||
#define DAC_DRV_ERROR (-1)
|
||||
#define DAC_DRV_SUCCESS (0)
|
||||
|
||||
#define DAC_CH0 (0x01 << 0)
|
||||
#define DAC_CH1 (0x01 << 1)
|
||||
#define DAC_CH2 (0x01 << 2)
|
||||
#define DAC_CH3 (0x01 << 3)
|
||||
|
||||
#if (DEF_DAC_DRV_ENABLED)
|
||||
int dac_init(void);
|
||||
int dac_load(uint32_t channel_mask);
|
||||
|
||||
/*
|
||||
single channel output example:
|
||||
...
|
||||
dac_write(DAC_CH0, 128);
|
||||
dac_load(DAC_CH0);
|
||||
...
|
||||
|
||||
muti-channel output example:
|
||||
...
|
||||
dac_write(DAC_CH0 | DAC_CH1, 128);
|
||||
dac_load(DAC_CH0 | DAC_CH1);
|
||||
...
|
||||
*/
|
||||
int dac_write(uint32_t channel_mask, int32_t dac_val);
|
||||
|
||||
/*
|
||||
single channel output example:
|
||||
...
|
||||
dac_write_through(DAC_CH0, 128);
|
||||
...
|
||||
|
||||
muti-channel output example:
|
||||
...
|
||||
dac_write_through(DAC_CH0 | DAC_CH1, 128);
|
||||
...
|
||||
*/
|
||||
int dac_write_through(uint32_t channel_mask, int32_t dac_val);
|
||||
#else
|
||||
#define dac_init();
|
||||
#define dac_load(x);
|
||||
#define dac_write(x, y);
|
||||
#define dac_write_through(x, y);
|
||||
#endif /* ! DEF_DAC_DRV_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __DAC_DRV_H__ */
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef __DAC_DRV_IF_H__
|
||||
#define __DAC_DRV_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DAC0 (0x01 << 0)
|
||||
#define DAC1 (0x01 << 1)
|
||||
#define DAC2 (0x01 << 2)
|
||||
#define DAC3 (0x01 << 3)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int (*init)(void);
|
||||
int (*write_mode)(uint32_t channel_mask, int32_t volts);
|
||||
int (*ldac_mode)(uint32_t channel_mask);
|
||||
int (*write_through_mode)(uint32_t channel_mask, int32_t volts);
|
||||
int (*power_control_mode)(uint32_t channel_mask, uint32_t ready_enable);
|
||||
int (*reset)(void);
|
||||
} dac_drv_if_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __DAC_DRV_IF_H__ */
|
||||
@@ -0,0 +1,142 @@
|
||||
#ifndef __EDC_H__
|
||||
#define __EDC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "dac_drv.h"
|
||||
#include "elite_def.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** Iin, Vin, Vout **/
|
||||
#define RIS_ADC_IIN 0x00
|
||||
#define RIS_ADC_VIN 0x01
|
||||
#define RIS_DAC_VOUT 0x02
|
||||
#define RIS_HIGH_Z 0x03
|
||||
#define RIS_ADC_VOUT 0x04
|
||||
#define RIS_ADC_BAT 0x05
|
||||
|
||||
// ADC Iin gain level !!! move to ADC.h in future
|
||||
#define I_GAIN_3M 0x00 // lv0,largest gain
|
||||
#define I_GAIN_100K 0x01 // lv1
|
||||
#define I_GAIN_3K 0x02 // lv2
|
||||
#define I_GAIN_100R 0x03 // lv3,the least gain
|
||||
#define I_GAIN_AUTO 0x04
|
||||
|
||||
// ADC Vin gain level !!! move to ADC.h in future
|
||||
#define VIN_GAIN_1M 0x00
|
||||
#define VIN_GAIN_30K 0x01
|
||||
#define VIN_GAIN_1K 0x02
|
||||
#define VIN_GAIN_AUTO 0x03
|
||||
|
||||
// DAC Vout gain level !!! move to DAC.h in future
|
||||
#define VOUT_GAIN_240K 0x00
|
||||
#define VOUT_GAIN_15K 0x01
|
||||
#define VOUT_GAIN_AUTO 0x02
|
||||
|
||||
/* DAC reset parameter */
|
||||
#define DAC_ZERO 25000 // DAC_ZERO is about 0V
|
||||
|
||||
// Step time macro
|
||||
#define STEPTIME_HALF_SEC 5000
|
||||
#define STEPTIME_ONE_SEC 10000
|
||||
#define STEPTIME_TWO_SEC 20000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*init)(void);
|
||||
elite_instance_t *p_elite_instance;
|
||||
struct
|
||||
{
|
||||
uint32_t chip_id;
|
||||
uint32_t eliteFxn;
|
||||
|
||||
// time relation
|
||||
uint32_t VsetRateIndex;
|
||||
uint32_t VsetRate;
|
||||
uint32_t sampleRate;
|
||||
uint32_t notifyRate;
|
||||
uint32_t period;
|
||||
|
||||
int32_t Vset;
|
||||
uint32_t VoltConstant;
|
||||
uint32_t directionInit;
|
||||
uint32_t step;
|
||||
uint32_t Ve1;
|
||||
uint32_t Ve2;
|
||||
int32_t Vinit;
|
||||
int32_t Vmax;
|
||||
int32_t Vmin;
|
||||
|
||||
uint32_t steptime;
|
||||
|
||||
uint32_t IinADCAutoGainEn;
|
||||
uint32_t VinADCAutoGainEn;
|
||||
uint32_t VoutAutoGainEn;
|
||||
uint32_t IinADCGainLv;
|
||||
uint32_t VinADCGainLv;
|
||||
uint32_t VoutGainLv;
|
||||
uint32_t gain_switch_on;
|
||||
uint32_t AdcChannel;
|
||||
bool hign_z_en;
|
||||
|
||||
uint32_t cycleNumber;
|
||||
uint32_t charge;
|
||||
int32_t constantCurrent;
|
||||
// uint32_t cc_resistance;
|
||||
uint32_t cc_cp_speed;
|
||||
|
||||
// uni pulse mode
|
||||
int32_t v0;
|
||||
uint32_t t_pulse[4];
|
||||
int32_t v_initial[4];
|
||||
int32_t v_slope[4];
|
||||
int32_t v_step[4];
|
||||
uint32_t t_pulse_min[4];
|
||||
uint32_t t_pulse_max[4];
|
||||
int32_t v_stop;
|
||||
int32_t v_up;
|
||||
int32_t v_low;
|
||||
bool v_invert_option;
|
||||
bool v_stop_direction;
|
||||
int32_t v_1;
|
||||
int32_t v_2;
|
||||
|
||||
int32_t Vout;
|
||||
|
||||
// not use
|
||||
int32_t Currentmax;
|
||||
uint32_t VoViSwitch;
|
||||
} instru;
|
||||
} edc20_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float coeff;
|
||||
float offset;
|
||||
} edc20_cal_data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
float coeff;
|
||||
float offset;
|
||||
} dac_c;
|
||||
struct
|
||||
{
|
||||
float coeff;
|
||||
float offset;
|
||||
float Voffset;
|
||||
} dac_f[3];
|
||||
} edc20_dac_cal_data_t;
|
||||
|
||||
extern edc20_t edc;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __EDC_H__ */
|
||||
@@ -0,0 +1,500 @@
|
||||
#include "edc.h"
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "dac_drv.h"
|
||||
|
||||
#include "nrf.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "elite_board.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
|
||||
#define OUT_0 DAC0
|
||||
#define OUT_1 DAC1
|
||||
|
||||
typedef struct __PACKED
|
||||
{
|
||||
uint32_t notify_time;
|
||||
int32_t ch1_data;
|
||||
int32_t ch2_data;
|
||||
int32_t ch3_data;
|
||||
uint16_t cycle;
|
||||
uint8_t finish_flag;
|
||||
uint32_t bat_volt;
|
||||
uint8_t packet_seq;
|
||||
int32_t ch4_data;
|
||||
int32_t ch5_data;
|
||||
int32_t ch6_data;
|
||||
} payload_t;
|
||||
|
||||
typedef struct __PACKED
|
||||
{
|
||||
uint8_t mem_board_id;
|
||||
payload_t payload;
|
||||
uint8_t : 8;
|
||||
uint8_t : 8;
|
||||
uint8_t : 8;
|
||||
} elite_notify_packet_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t id;
|
||||
uint32_t mS_period;
|
||||
elite_dac_config_t config;
|
||||
} iv_cycle_mode_param_t;
|
||||
|
||||
const edc20_dac_cal_data_t edc20_dac_cal_data = {
|
||||
.dac_c = { 2.9701475, 121.9763670 },
|
||||
.dac_f = {
|
||||
[0] = { 65.7454092, -290.3872456, -36.65060000 },
|
||||
[1] = { 27.4300538, -100.6332479, -37.39872222 },
|
||||
[2] = { 7.61192880, -0.568019000, -40.99282222 } }
|
||||
};
|
||||
#define FS_1000mV 1000
|
||||
#define FS_2800mV 2800
|
||||
#define FS_8000mV 8000
|
||||
const float edc20_range_mV[] = {
|
||||
[0] = FS_1000mV,
|
||||
[1] = FS_2800mV,
|
||||
[2] = FS_8000mV,
|
||||
};
|
||||
|
||||
static SemaphoreHandle_t semphr_start = NULL;
|
||||
|
||||
static TaskHandle_t task_handle = NULL;
|
||||
|
||||
static bool running = false;
|
||||
|
||||
extern ret_code_t le_event_notify(uint8_t *p_value, uint16_t len);
|
||||
|
||||
static ret_code_t _send_start_packet(elite_notify_packet_t *p_buf, uint32_t loops)
|
||||
{
|
||||
memset(&p_buf->payload, 0x00, sizeof(p_buf->payload));
|
||||
for (uint32_t i = 0; i < loops; i++)
|
||||
{
|
||||
ret_code_t ret = le_event_notify((void *)p_buf, sizeof(*p_buf));
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
static ret_code_t _send_data_packet(elite_notify_packet_t *p_notify_buf, bool is_last_notify)
|
||||
{
|
||||
static int32_t ch1 = 0;
|
||||
static int32_t ch2 = 0;
|
||||
static int32_t ch3 = 0;
|
||||
|
||||
ch1 += 100;
|
||||
ch2++;
|
||||
ch3 = ch2;
|
||||
|
||||
p_notify_buf->payload.notify_time = xTaskGetTickCount();
|
||||
p_notify_buf->payload.ch1_data = ch1;
|
||||
p_notify_buf->payload.ch2_data = ch2;
|
||||
p_notify_buf->payload.ch3_data = ch3;
|
||||
p_notify_buf->payload.bat_volt = 3600;
|
||||
p_notify_buf->payload.packet_seq++;
|
||||
p_notify_buf->payload.finish_flag = is_last_notify;
|
||||
|
||||
return le_event_notify((void *)p_notify_buf, sizeof(*p_notify_buf));
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float dir;
|
||||
float mV_output;
|
||||
float mV_max;
|
||||
float mV_min;
|
||||
float mV_start;
|
||||
float mV_stop;
|
||||
float step;
|
||||
uint32_t cycle_cnt;
|
||||
uint32_t cycle_max;
|
||||
uint32_t fullscale;
|
||||
struct
|
||||
{
|
||||
float eta_c;
|
||||
float eta_f;
|
||||
float Voffset;
|
||||
float Vc;
|
||||
float Nc;
|
||||
float Nc0;
|
||||
float Nf;
|
||||
};
|
||||
} cycle_iv_dac_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t period;
|
||||
} cycle_iv_adc_t;
|
||||
|
||||
static uint32_t mV_out_0(cycle_iv_dac_t *p)
|
||||
{
|
||||
for (uint32_t i = 0; i < COUNTOF(edc20_range_mV); i++)
|
||||
{
|
||||
if ((p->mV_max - p->mV_min) <= edc20_range_mV[i])
|
||||
{
|
||||
p->fullscale = edc20_range_mV[i];
|
||||
p->eta_c = edc20_dac_cal_data.dac_c.coeff;
|
||||
p->eta_f = edc20_dac_cal_data.dac_f[i].coeff;
|
||||
p->Voffset = edc20_dac_cal_data.dac_f[i].Voffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->Vc = (p->mV_max + p->mV_min) / 2;
|
||||
p->Nc = round((p->Vc - p->Voffset) * p->eta_c) + 32768;
|
||||
p->Nc0 = round((0 - p->Voffset) * p->eta_c) + 32768;
|
||||
return p->Nc;
|
||||
}
|
||||
|
||||
static uint32_t mV_out_1(cycle_iv_dac_t *p)
|
||||
{
|
||||
p->Nf = round((p->mV_output - p->Vc - p->Voffset - (p->Nc0 - 32768) / p->eta_c) * p->eta_f) + 32768;
|
||||
return p->Nf;
|
||||
}
|
||||
|
||||
static uint32_t cal_dac_timer_interval(elite_dac_config_t *p_config, cycle_iv_dac_t *p_cycle_iv_dac)
|
||||
{
|
||||
uint32_t intvl;
|
||||
float step_time = p_config->uS_step;
|
||||
for (intvl = 100; intvl < 1000000; intvl *= 10)
|
||||
{
|
||||
p_cycle_iv_dac->step = (p_config->mV_step * intvl) / step_time;
|
||||
if (p_cycle_iv_dac->step >= 0.001)
|
||||
{
|
||||
return intvl;
|
||||
}
|
||||
}
|
||||
return intvl;
|
||||
}
|
||||
|
||||
static void dac_select_circuit(cycle_iv_dac_t *p)
|
||||
{
|
||||
float scan_range = p->mV_max - p->mV_min;
|
||||
|
||||
if (scan_range <= FS_1000mV)
|
||||
{
|
||||
circuit_selection_dac_fine_tune_f0();
|
||||
}
|
||||
else if (scan_range <= FS_2800mV)
|
||||
{
|
||||
circuit_selection_dac_fine_tune_f1();
|
||||
}
|
||||
else if (scan_range <= FS_8000mV)
|
||||
{
|
||||
circuit_selection_dac_fine_tune_f2();
|
||||
}
|
||||
}
|
||||
|
||||
void _callback(void *p_arg)
|
||||
{
|
||||
cycle_iv_dac_t *p = p_arg;
|
||||
|
||||
if (p->mV_output <= p->mV_min)
|
||||
{
|
||||
p->mV_output = p->mV_min;
|
||||
p->dir = 1;
|
||||
}
|
||||
|
||||
if (p->mV_output >= p->mV_max)
|
||||
{
|
||||
p->mV_output = p->mV_max;
|
||||
p->dir = -1;
|
||||
}
|
||||
|
||||
dac_write_through(OUT_1, mV_out_1(p));
|
||||
|
||||
if (p->mV_output == p->mV_start)
|
||||
{
|
||||
p->cycle_cnt++;
|
||||
if (p->cycle_cnt > p->cycle_max)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
p->mV_output += p->dir * p->step;
|
||||
}
|
||||
|
||||
static void edc20_cycle_iv_mode_task(void *p_arg)
|
||||
{
|
||||
elite_notify_packet_t packet_buf;
|
||||
cycle_iv_dac_t dac_param;
|
||||
cycle_iv_adc_t adc_param;
|
||||
iv_cycle_mode_param_t mode_param;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
|
||||
/* copy iv cycle parameter */
|
||||
memcpy(&mode_param, p_arg, sizeof(mode_param));
|
||||
|
||||
memset(&packet_buf, 0x00, sizeof(packet_buf));
|
||||
memset(&dac_param, 0x00, sizeof(dac_param));
|
||||
memset(&adc_param, 0x00, sizeof(adc_param));
|
||||
|
||||
taskEXIT_CRITICAL();
|
||||
|
||||
if (1)
|
||||
{
|
||||
char info[256];
|
||||
snprintf(info, 256, "%s() @ %p start", __FUNCTION__, xTaskGetCurrentTaskHandle());
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%8ld", "id", mode_param.id);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%7.0fmV", "V_start", mode_param.config.mV_start);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%7.0fmV", "V_stop", mode_param.config.mV_stop);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%7.0fmV", "uV_step", mode_param.config.mV_step);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%8ldus", "uS_step_time", mode_param.config.uS_step);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%8ld", "cycles", mode_param.config.cycles);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%8ldms", "mS_period", mode_param.mS_period);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
}
|
||||
|
||||
/* set memborad id */
|
||||
packet_buf.mem_board_id = mode_param.id;
|
||||
|
||||
/* send start packet 4 times */
|
||||
_send_start_packet(&packet_buf, 4);
|
||||
|
||||
dac_param.mV_output = mode_param.config.mV_start;
|
||||
dac_param.mV_max = MAX(mode_param.config.mV_start, mode_param.config.mV_stop);
|
||||
dac_param.mV_min = MIN(mode_param.config.mV_start, mode_param.config.mV_stop);
|
||||
dac_param.mV_start = mode_param.config.mV_start;
|
||||
dac_param.mV_stop = mode_param.config.mV_stop;
|
||||
dac_param.dir = dac_param.mV_output == dac_param.mV_min ? 1 : -1;
|
||||
dac_param.cycle_cnt = 0;
|
||||
dac_param.cycle_max = mode_param.config.cycles;
|
||||
dac_param.fullscale = 0;
|
||||
|
||||
if (1)
|
||||
{
|
||||
NRF_LOG_INFO("%s", "");
|
||||
mV_out_0(&dac_param);
|
||||
char info[256];
|
||||
snprintf(info, 256, "%16s:%10.3f", "eta_c", dac_param.eta_c);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%10.3f", "eta_f", dac_param.eta_f);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%10.3f", "Voffset", dac_param.Voffset);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%10.3f", "Vc", dac_param.Vc);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%10.3f", "Nc", dac_param.Nc);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
snprintf(info, 256, "%16s:%10.3f", "Nc0", dac_param.Nc0);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
|
||||
dac_param.mV_output = dac_param.mV_start;
|
||||
mV_out_1(&dac_param);
|
||||
snprintf(info, 256, "%16s:%10.3f", "V1 Nf", dac_param.Nf);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
|
||||
dac_param.mV_output = dac_param.mV_stop;
|
||||
mV_out_1(&dac_param);
|
||||
snprintf(info, 256, "%16s:%10.3f", "V2 Nf", dac_param.Nf);
|
||||
NRF_LOG_INFO("%s", info);
|
||||
}
|
||||
|
||||
dac_write_through(OUT_0, mV_out_0(&dac_param));
|
||||
|
||||
dac_param.mV_output = dac_param.mV_start;
|
||||
dac_write_through(OUT_1, mV_out_1(&dac_param));
|
||||
|
||||
dac_select_circuit(&dac_param);
|
||||
|
||||
/* start DAC timer */
|
||||
edc20_dac_tim_start(cal_dac_timer_interval(&mode_param.config, &dac_param), _callback, &dac_param);
|
||||
|
||||
/* start ADC timer */
|
||||
edc20_adc_tim_start(&mode_param.config);
|
||||
|
||||
/* get current tick */
|
||||
TickType_t tick = xTaskGetTickCount();
|
||||
|
||||
uint32_t notify_delay = pdMS_TO_TICKS(mode_param.mS_period);
|
||||
|
||||
/* start data update process */
|
||||
running = true;
|
||||
|
||||
while (running)
|
||||
{
|
||||
ret_code_t ret = _send_data_packet(&packet_buf, false);
|
||||
switch (ret)
|
||||
{
|
||||
case NRF_SUCCESS:
|
||||
case NRF_ERROR_RESOURCES:
|
||||
vTaskDelayUntil(&tick, notify_delay);
|
||||
break;
|
||||
default:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
edc20_dac_tim_stop();
|
||||
edc20_adc_tim_stop();
|
||||
dac_init();
|
||||
|
||||
if (1)
|
||||
{
|
||||
char info[256];
|
||||
snprintf(info, 256, "%s() @ %p stop", __FUNCTION__, xTaskGetCurrentTaskHandle());
|
||||
NRF_LOG_INFO("%s", info);
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void edc20_cycle_iv_mode_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define VDIRECTION(v1, v2) ((v1 > v2) ? 0 : 1)
|
||||
// Step time macro
|
||||
#define STEPTIME_HALF_SEC 5000
|
||||
#define STEPTIME_ONE_SEC 10000
|
||||
#define STEPTIME_TWO_SEC 20000
|
||||
static uint32_t step2VsetRate(uint32_t step)
|
||||
{
|
||||
/*step = 100 mv, index = 0, n = 2
|
||||
10 mv, index = 1, n = 10
|
||||
1 mv, index = 2, n = 100
|
||||
0.1 mv, index = 3, n = 1000
|
||||
0.01mv, index = 4, n = 10000 */
|
||||
|
||||
if (step >= 10000)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (step >= 1000)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (step >= 100)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else if (step >= 10)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
else if (step >= 1)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_step_time(uint8_t StepTime)
|
||||
{
|
||||
switch (StepTime)
|
||||
{
|
||||
case 0: { // 0.5 sec
|
||||
return STEPTIME_HALF_SEC;
|
||||
}
|
||||
case 1: { // 1 sec
|
||||
return STEPTIME_ONE_SEC;
|
||||
}
|
||||
case 2: { // 2 sec
|
||||
return STEPTIME_TWO_SEC;
|
||||
}
|
||||
default: { // 1 sec
|
||||
return STEPTIME_ONE_SEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define STEP_TO_VSETRATE(step) step2VsetRate(step)
|
||||
const uint32_t VsetRateTable[5] = { 2, 10, 100, 1000, 10000 };
|
||||
|
||||
static uint32_t convt_uS_step(uint32_t idx)
|
||||
{
|
||||
switch (idx)
|
||||
{
|
||||
case 0: { // 0.5 sec
|
||||
return 500000;
|
||||
}
|
||||
case 1: { // 1 sec
|
||||
return 1000000;
|
||||
}
|
||||
case 2: { // 2 sec
|
||||
return 2000000;
|
||||
}
|
||||
default: { // 1 sec
|
||||
return 1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void edc20_cycle_iv_mode_start(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
/*
|
||||
instru.eliteFxn = CURVE_IV_CY;
|
||||
instru.Ve1 = ((uint16_t)(ins[3]) << 8) | (uint16_t)(ins[4]);
|
||||
instru.Ve2 = ((uint16_t)(ins[5]) << 8) | (uint16_t)(ins[6]);
|
||||
instru.Vinit = (int32_t)instru.Ve1;
|
||||
instru.Vmax = (int32_t)VMAX(instru.Ve1,instru.Ve2);
|
||||
instru.Vmin = (int32_t)VMIN(instru.Ve1,instru.Ve2);
|
||||
instru.directionInit = VDIRECTION(instru.Ve1,instru.Ve2);
|
||||
instru.steptime = get_step_time(ins[9]); //5000;10000;20000;
|
||||
instru.step = ((uint32_t)(ins[7]) << 8) | (uint32_t)(ins[8]);//1~1000 = 0.1mv ~ 100mv
|
||||
instru.step = instru.step * 100000 / instru.steptime;
|
||||
STEP_TO_VSETRATE(instru.step);
|
||||
instru.VsetRate = VsetRateTable[instru.VsetRateIndex];//N
|
||||
instru.cycleNumber = ((uint16_t)(ins[10]) << 8) | (uint16_t)(ins[11]);
|
||||
instru.hign_z_en = ins[13] & 0x0F;
|
||||
instru.notifyRate = ((uint32_t)ins[14] << 8) | (uint32_t)ins[15];
|
||||
instru.notifyRate = 10000 / instru.notifyRate * 10;
|
||||
*/
|
||||
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint8_t : 8;
|
||||
uint8_t : 8;
|
||||
uint16_t volt_start; // unit: 100uV, -5V = 0, 0V = 25000, 5V = 50000
|
||||
uint16_t volt_stop; // unit: 100uV, -5V = 0, 0V = 25000, 5V = 50000
|
||||
uint16_t step; // unit: 100uV
|
||||
uint8_t step_time; // enum: 0 = 5000us, 1 = 10000us, 2 = 20000us
|
||||
uint16_t cycles; // 0 ~ 500000
|
||||
uint8_t : 8;
|
||||
uint8_t hi_z_en; // lower nibble
|
||||
uint16_t sample_rate; // unit: 0.1Hz
|
||||
} *p = (void *)ins;
|
||||
|
||||
iv_cycle_mode_param_t mode_param = {
|
||||
.id = p->id,
|
||||
.mS_period = 1000 * 10 / __REVSH(p->sample_rate),
|
||||
.config.mV_start = ((__REVSH(p->volt_start) & 0xFFFF) / 10 - 2500) * 2,
|
||||
.config.mV_stop = ((__REVSH(p->volt_stop) & 0xFFFF) / 10 - 2500) * 2,
|
||||
.config.mV_step = (uint32_t)__REVSH(p->step) / 10,
|
||||
.config.uS_step = convt_uS_step(p->step_time),
|
||||
.config.cycles = (__REVSH(p->cycles) & 0xFFFF)
|
||||
};
|
||||
|
||||
xTaskCreate(edc20_cycle_iv_mode_task, "iv_mode", 2048, (void *)&mode_param, 3, &task_handle);
|
||||
|
||||
portYIELD();
|
||||
}
|
||||
|
||||
#endif /* ! DEF_ELITE_MODEL */
|
||||
+721
@@ -0,0 +1,721 @@
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "nrf_drv_spi.h"
|
||||
#include "nrf_drv_twi.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_timer.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#include "adc_drv.h"
|
||||
#include "dac_drv.h"
|
||||
#include "sw_drv.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
|
||||
//==========================================================
|
||||
// gpio
|
||||
//==========================================================
|
||||
void gpio_init(void)
|
||||
{
|
||||
nrf_gpio_pin_set(POWER_5V_EN_PIN);
|
||||
nrf_gpio_pin_set(POWER_12V_EN_PIN);
|
||||
nrf_gpio_pin_set(OFF_PIN);
|
||||
|
||||
nrf_gpio_pin_clear(Vout_FB_PIN);
|
||||
nrf_gpio_pin_clear(Vout_IN_PIN);
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Vin2_PIN);
|
||||
nrf_gpio_pin_clear(Vin1_PIN);
|
||||
nrf_gpio_pin_clear(CV_CTRL_PIN);
|
||||
nrf_gpio_pin_clear(ADCA2_PIN);
|
||||
nrf_gpio_pin_clear(ADCA1_PIN);
|
||||
nrf_gpio_pin_clear(ADCA0_PIN);
|
||||
nrf_gpio_pin_clear(RST_SW_PIN);
|
||||
|
||||
nrf_gpio_cfg_output(POWER_5V_EN_PIN);
|
||||
nrf_gpio_cfg_output(POWER_12V_EN_PIN);
|
||||
nrf_gpio_cfg_output(OFF_PIN);
|
||||
nrf_gpio_cfg_output(Vout_FB_PIN);
|
||||
nrf_gpio_cfg_output(Vout_IN_PIN);
|
||||
nrf_gpio_cfg_output(Iin4_TEST_PIN);
|
||||
nrf_gpio_cfg_output(Iin3_SEL_PIN);
|
||||
nrf_gpio_cfg_output(Iin3_PIN);
|
||||
nrf_gpio_cfg_output(Iin2_PIN);
|
||||
nrf_gpio_cfg_output(Iin1_PIN);
|
||||
nrf_gpio_cfg_output(Vin2_PIN);
|
||||
nrf_gpio_cfg_output(Vin1_PIN);
|
||||
nrf_gpio_cfg_output(CV_CTRL_PIN);
|
||||
nrf_gpio_cfg_output(ADCA2_PIN);
|
||||
nrf_gpio_cfg_output(ADCA1_PIN);
|
||||
nrf_gpio_cfg_output(ADCA0_PIN);
|
||||
nrf_gpio_cfg_output(RST_SW_PIN);
|
||||
nrf_gpio_cfg_output(CS_SW_PIN);
|
||||
nrf_gpio_cfg_output(CS_MEM_PIN);
|
||||
nrf_gpio_cfg_output(CS_ADC_PIN);
|
||||
nrf_gpio_cfg_output(CS_DAC_PIN);
|
||||
|
||||
nrf_gpio_cfg_input(VBAT_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
nrf_gpio_cfg_input(SHUT_DOWN_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
nrf_gpio_cfg_input(INT9466_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
|
||||
// Config spi cs pin
|
||||
|
||||
uint32_t cs_pins[] = {
|
||||
CS_SW_PIN, CS_MEM_PIN, CS_ADC_PIN, CS_DAC_PIN
|
||||
};
|
||||
|
||||
for (int i = 0; i < COUNTOF(cs_pins); i++)
|
||||
{
|
||||
nrf_gpio_pin_set(cs_pins[i]);
|
||||
nrf_gpio_cfg(
|
||||
cs_pins[i],
|
||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_H0H1,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
}
|
||||
|
||||
// Config spi mosi pin
|
||||
nrf_gpio_pin_set(SPIM_MOSI_PIN);
|
||||
nrf_gpio_cfg(
|
||||
SPIM_MOSI_PIN,
|
||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_H0H1,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
|
||||
// Config spi miso pin
|
||||
nrf_gpio_cfg_input(SPIM_MISO_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
|
||||
// Config spi clk pin
|
||||
nrf_gpio_pin_clear(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg(
|
||||
SPIM_CLK_PIN,
|
||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_H0H1,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
}
|
||||
|
||||
// circuit_select combination
|
||||
void circuit_selection_vin_0(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Vin1_PIN);
|
||||
nrf_gpio_pin_clear(Vin2_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_vin_1(void)
|
||||
{
|
||||
nrf_gpio_pin_set(Vin1_PIN);
|
||||
nrf_gpio_pin_clear(Vin2_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_vin_2(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Vin1_PIN);
|
||||
nrf_gpio_pin_set(Vin2_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_Iin_0(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_Iin_1(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_set(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_Iin_2(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_set(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_Iin_3(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_set(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_set(Iin3_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_Iin_4(void)
|
||||
{
|
||||
nrf_gpio_pin_set(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_dac_coarse_tune_c(void)
|
||||
{
|
||||
sw_t sw;
|
||||
uint32_t sw_cnt;
|
||||
|
||||
sw_count(&sw_cnt);
|
||||
sw_read(&sw);
|
||||
sw.val = 0b10000000;
|
||||
NRF_LOG_INFO("sw.val= %08X", sw.val);
|
||||
NRF_LOG_INFO("sw.sw7~sw4=%X %X %X %X", sw.sw7, sw.sw6, sw.sw5, sw.sw4);
|
||||
NRF_LOG_INFO("sw.sw3~sw0=%X %X %X %X", sw.sw3, sw.sw2, sw.sw1, sw.sw0);
|
||||
sw_write(sw);
|
||||
|
||||
nrf_gpio_pin_set(Vout_FB_PIN);
|
||||
nrf_gpio_pin_clear(Vout_IN_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_dac_fine_tune_f0(void)
|
||||
{
|
||||
sw_t sw;
|
||||
uint32_t sw_cnt;
|
||||
|
||||
sw_count(&sw_cnt);
|
||||
sw_read(&sw);
|
||||
sw.val = 0b10000100;
|
||||
NRF_LOG_INFO("sw.val= %08X", sw.val);
|
||||
NRF_LOG_INFO("sw.sw7~sw4=%X %X %X %X", sw.sw7, sw.sw6, sw.sw5, sw.sw4);
|
||||
NRF_LOG_INFO("sw.sw3~sw0=%X %X %X %X", sw.sw3, sw.sw2, sw.sw1, sw.sw0);
|
||||
sw_write(sw);
|
||||
|
||||
nrf_gpio_pin_set(Vout_FB_PIN);
|
||||
nrf_gpio_pin_clear(Vout_IN_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_dac_fine_tune_f1(void)
|
||||
{
|
||||
sw_t sw;
|
||||
uint32_t sw_cnt;
|
||||
|
||||
sw_count(&sw_cnt);
|
||||
sw_read(&sw);
|
||||
sw.val = 0b10001000;
|
||||
NRF_LOG_INFO("sw.val= %08X", sw.val);
|
||||
NRF_LOG_INFO("sw.sw7~sw4=%X %X %X %X", sw.sw7, sw.sw6, sw.sw5, sw.sw4);
|
||||
NRF_LOG_INFO("sw.sw3~sw0=%X %X %X %X", sw.sw3, sw.sw2, sw.sw1, sw.sw0);
|
||||
sw_write(sw);
|
||||
|
||||
nrf_gpio_pin_set(Vout_FB_PIN);
|
||||
nrf_gpio_pin_clear(Vout_IN_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_dac_fine_tune_f2(void)
|
||||
{
|
||||
sw_t sw;
|
||||
uint32_t sw_cnt;
|
||||
|
||||
sw_count(&sw_cnt);
|
||||
sw_read(&sw);
|
||||
sw.val = 0b10000000;
|
||||
NRF_LOG_INFO("sw.val= %08X", sw.val);
|
||||
NRF_LOG_INFO("sw.sw7~sw4=%X %X %X %X", sw.sw7, sw.sw6, sw.sw5, sw.sw4);
|
||||
NRF_LOG_INFO("sw.sw3~sw0=%X %X %X %X", sw.sw3, sw.sw2, sw.sw1, sw.sw0);
|
||||
sw_write(sw);
|
||||
|
||||
nrf_gpio_pin_set(Vout_FB_PIN);
|
||||
nrf_gpio_pin_clear(Vout_IN_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_dac_circuit_open(void)
|
||||
{
|
||||
sw_t sw;
|
||||
uint32_t sw_cnt;
|
||||
|
||||
sw_count(&sw_cnt);
|
||||
sw_read(&sw);
|
||||
sw.sw4 = 0;
|
||||
sw.sw5 = 0;
|
||||
sw.sw6 = 0;
|
||||
sw.sw7 = 0;
|
||||
NRF_LOG_INFO("sw.val= %08X", sw.val);
|
||||
NRF_LOG_INFO("sw.sw7~sw4=%X %X %X %X", sw.sw7, sw.sw6, sw.sw5, sw.sw4);
|
||||
NRF_LOG_INFO("sw.sw3~sw0=%X %X %X %X", sw.sw3, sw.sw2, sw.sw1, sw.sw0);
|
||||
sw_write(sw);
|
||||
}
|
||||
|
||||
void circuit_selection_cv3_config(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Vout_FB_PIN);
|
||||
nrf_gpio_pin_set(Vout_IN_PIN);
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
nrf_gpio_pin_set(CV_CTRL_PIN);
|
||||
}
|
||||
|
||||
void circuit_selection_cc_config(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(Vout_FB_PIN);
|
||||
nrf_gpio_pin_set(Vout_IN_PIN);
|
||||
nrf_gpio_pin_clear(Iin4_TEST_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_SEL_PIN);
|
||||
nrf_gpio_pin_clear(Iin1_PIN);
|
||||
nrf_gpio_pin_clear(Iin2_PIN);
|
||||
nrf_gpio_pin_clear(Iin3_PIN);
|
||||
nrf_gpio_pin_clear(CV_CTRL_PIN);
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
// i2c
|
||||
//==========================================================
|
||||
static const nrf_drv_twi_t twi0 = NRF_DRV_TWI_INSTANCE(0);
|
||||
static SemaphoreHandle_t i2c_sem = NULL;
|
||||
static SemaphoreHandle_t i2c_mutex = NULL;
|
||||
static QueueHandle_t i2c_evt_queue = NULL;
|
||||
|
||||
static void nrf_drv_twi_evt_handler(nrf_drv_twi_evt_t const *p_event, void *p_context)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xQueueSendFromISR(i2c_evt_queue, p_event, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void twi_init(void)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
|
||||
i2c_sem = xSemaphoreCreateBinary();
|
||||
i2c_mutex = xSemaphoreCreateMutex();
|
||||
i2c_evt_queue = xQueueCreate(2, sizeof(nrf_drv_twi_evt_t));
|
||||
|
||||
const nrf_drv_twi_config_t twi0_config = {
|
||||
.scl = I2C0_SCL,
|
||||
.sda = I2C0_SDA,
|
||||
.frequency = NRF_DRV_TWI_FREQ_100K,
|
||||
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
|
||||
.clear_bus_init = true
|
||||
};
|
||||
|
||||
err_code = nrf_drv_twi_init(&twi0, &twi0_config, nrf_drv_twi_evt_handler, NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
nrf_drv_twi_enable(&twi0);
|
||||
}
|
||||
|
||||
void twi0_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t data_len)
|
||||
{
|
||||
xSemaphoreTake(i2c_mutex, portMAX_DELAY);
|
||||
|
||||
static uint8_t i2c_buf[255];
|
||||
static nrf_drv_twi_evt_t evt;
|
||||
ret_code_t err_code;
|
||||
|
||||
memcpy(i2c_buf, ®_addr, sizeof(reg_addr));
|
||||
memcpy(i2c_buf + sizeof(reg_addr), data, data_len);
|
||||
|
||||
err_code = nrf_drv_twi_tx(&twi0, slave_addr, i2c_buf, data_len + 1, false);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
xQueueReceive(i2c_evt_queue, &evt, portMAX_DELAY);
|
||||
|
||||
switch (evt.type)
|
||||
{
|
||||
/* Transfer completed event. */
|
||||
case NRF_DRV_TWI_EVT_DONE:
|
||||
// TODO...
|
||||
break;
|
||||
/* Error event: NACK received after sending the address. */
|
||||
case NRF_DRV_TWI_EVT_ADDRESS_NACK:
|
||||
// TODO...
|
||||
__BKPT(255);
|
||||
break;
|
||||
/* Error event: NACK received after sending a data byte. */
|
||||
case NRF_DRV_TWI_EVT_DATA_NACK:
|
||||
// TODO...
|
||||
__BKPT(255);
|
||||
break;
|
||||
default:
|
||||
__BKPT(255);
|
||||
break;
|
||||
}
|
||||
|
||||
xSemaphoreGive(i2c_mutex);
|
||||
|
||||
NRF_LOG_INFO("i2c(W): slave_addr=0x%02x", slave_addr);
|
||||
NRF_LOG_HEXDUMP_INFO(i2c_buf, data_len + 1);
|
||||
}
|
||||
|
||||
void twi0_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_rx_buf, uint8_t rx_buffer_length)
|
||||
{
|
||||
xSemaphoreTake(i2c_mutex, portMAX_DELAY);
|
||||
|
||||
nrf_drv_twi_evt_t evt;
|
||||
ret_code_t err_code;
|
||||
|
||||
err_code = nrf_drv_twi_tx(&twi0, slave_addr, ®_addr, sizeof(reg_addr), false);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
xQueueReceive(i2c_evt_queue, &evt, portMAX_DELAY);
|
||||
|
||||
switch (evt.type)
|
||||
{
|
||||
/* Transfer completed event. */
|
||||
case NRF_DRV_TWI_EVT_DONE:
|
||||
// TODO...
|
||||
break;
|
||||
/* Error event: NACK received after sending the address. */
|
||||
case NRF_DRV_TWI_EVT_ADDRESS_NACK:
|
||||
// TODO...
|
||||
__BKPT(255);
|
||||
break;
|
||||
/* Error event: NACK received after sending a data byte. */
|
||||
case NRF_DRV_TWI_EVT_DATA_NACK:
|
||||
// TODO...
|
||||
__BKPT(255);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
err_code = nrf_drv_twi_rx(&twi0, slave_addr, p_rx_buf, rx_buffer_length);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
xQueueReceive(i2c_evt_queue, &evt, portMAX_DELAY);
|
||||
|
||||
switch (evt.type)
|
||||
{
|
||||
/* Transfer completed event. */
|
||||
case NRF_DRV_TWI_EVT_DONE:
|
||||
// TODO...
|
||||
break;
|
||||
/* Error event: NACK received after sending the address. */
|
||||
case NRF_DRV_TWI_EVT_ADDRESS_NACK:
|
||||
// TODO...
|
||||
__BKPT(255);
|
||||
break;
|
||||
/* Error event: NACK received after sending a data byte. */
|
||||
case NRF_DRV_TWI_EVT_DATA_NACK:
|
||||
// TODO...
|
||||
__BKPT(255);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
xSemaphoreGive(i2c_mutex);
|
||||
|
||||
NRF_LOG_INFO("i2c(R): slave_addr=0x%02x reg_addr=0x%02x", slave_addr, reg_addr);
|
||||
NRF_LOG_HEXDUMP_INFO(p_rx_buf, rx_buffer_length);
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
// spi
|
||||
//==========================================================
|
||||
static const nrf_drv_spi_t spim1 = NRF_DRV_SPI_INSTANCE(1); /**< SPI instance. */
|
||||
static SemaphoreHandle_t spim1_sem = NULL;
|
||||
|
||||
static void nrf_drv_spim1_evt_handler(nrf_drv_spi_evt_t const *p_event, void *p_context)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
switch (p_event->type)
|
||||
{
|
||||
case NRF_DRV_SPI_EVENT_DONE:
|
||||
xSemaphoreGiveFromISR(spim1_sem, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void spi_init(void)
|
||||
{
|
||||
spim1_sem = xSemaphoreCreateBinary();
|
||||
|
||||
nrf_drv_spi_config_t spi1_config = NRF_DRV_SPI_DEFAULT_CONFIG;
|
||||
spi1_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
|
||||
spi1_config.miso_pin = NRF_DRV_SPI_PIN_NOT_USED;
|
||||
spi1_config.mosi_pin = SPI1_MOSI_PIN;
|
||||
spi1_config.sck_pin = SPI1_CLK_PIN;
|
||||
spi1_config.mode = NRF_DRV_SPI_MODE_0;
|
||||
spi1_config.frequency = NRF_DRV_SPI_FREQ_8M;
|
||||
APP_ERROR_CHECK(nrf_drv_spi_init(&spim1, &spi1_config, nrf_drv_spim1_evt_handler, NULL));
|
||||
|
||||
// Config spi module
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
NRF_SPIM3->ORC = 0x00000000;
|
||||
NRF_SPIM3->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M32;
|
||||
NRF_SPIM3->CSNPOL = SPIM_CSNPOL_CSNPOL_LOW;
|
||||
NRF_SPIM3->IFTIMING.CSNDUR = 8;
|
||||
NRF_SPIM3->PSEL.SCK = SPIM_CLK_PIN;
|
||||
NRF_SPIM3->PSEL.MOSI = SPIM_MOSI_PIN;
|
||||
NRF_SPIM3->PSEL.MISO = SPIM_MISO_PIN;
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
}
|
||||
|
||||
void spi1_write(uint8_t *p_tx_buffer, uint16_t tx_buffer_length)
|
||||
{
|
||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spim1, p_tx_buffer, tx_buffer_length, NULL, 0));
|
||||
xSemaphoreTake(spim1_sem, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void spim_xfer(uint32_t cs_pin, nrf_spim_mode_t spi_mode, uint8_t *p_tx_buffer, uint16_t tx_buffer_length, uint8_t *p_rx_buf, uint16_t rx_buffer_length)
|
||||
{
|
||||
__disable_irq();
|
||||
|
||||
/* set spi mode and order */
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
switch (spi_mode)
|
||||
{
|
||||
default:
|
||||
case NRF_SPIM_MODE_0:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_1:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_2:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_3:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
NRF_SPIM3->PSEL.CSN = cs_pin;
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
if (p_tx_buffer != NULL)
|
||||
{
|
||||
NRF_SPIM3->TXD.PTR = (uint32_t)p_tx_buffer;
|
||||
NRF_SPIM3->TXD.MAXCNT = tx_buffer_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_SPIM3->TXD.MAXCNT = 0;
|
||||
}
|
||||
if (p_rx_buf != NULL)
|
||||
{
|
||||
NRF_SPIM3->RXD.PTR = (uint32_t)p_rx_buf;
|
||||
NRF_SPIM3->RXD.MAXCNT = rx_buffer_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_SPIM3->RXD.MAXCNT = 0;
|
||||
}
|
||||
|
||||
/* workaround for ADC acquisition time */
|
||||
nrf_gpio_pin_set(CS_ADC_PIN);
|
||||
|
||||
NRF_SPIM3->EVENTS_END = 0;
|
||||
NRF_SPIM3->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SPIM3->EVENTS_END == 0);
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
NRF_SPIM3->PSEL.CSN = 0xFFFFFFFF;
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
/* workaround for ADC acquisition time */
|
||||
nrf_gpio_pin_clear(CS_ADC_PIN);
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
// timer
|
||||
//==========================================================
|
||||
|
||||
#if (DEF_DAC_DRV_ENABLED)
|
||||
|
||||
#define ELITE_DAC_TMR NRF_TIMER2
|
||||
|
||||
static void (*dac_tmr_cb)(void *p_arg) = NULL;
|
||||
static void *dac_tmr_p_arg = NULL;
|
||||
|
||||
void TIMER2_IRQHandler(void)
|
||||
{
|
||||
if (ELITE_DAC_TMR->EVENTS_COMPARE[0])
|
||||
{
|
||||
ELITE_DAC_TMR->EVENTS_COMPARE[0] = 0;
|
||||
if (dac_tmr_cb)
|
||||
{
|
||||
dac_tmr_cb(dac_tmr_p_arg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
void edc20_dac_tim_start(uint32_t period, void (*callback)(void *p_arg), void *p_arg)
|
||||
{
|
||||
NRF_LOG_INFO("%s()", __FUNCTION__);
|
||||
|
||||
__disable_irq();
|
||||
|
||||
sd_nvic_DisableIRQ(TIMER2_IRQn);
|
||||
sd_nvic_ClearPendingIRQ(TIMER2_IRQn);
|
||||
ELITE_DAC_TMR->SHORTS = 0;
|
||||
ELITE_DAC_TMR->TASKS_STOP = 1;
|
||||
|
||||
dac_tmr_p_arg = p_arg;
|
||||
dac_tmr_cb = callback;
|
||||
|
||||
ELITE_DAC_TMR->PRESCALER = NRF_TIMER_FREQ_1MHz;
|
||||
ELITE_DAC_TMR->MODE = NRF_TIMER_MODE_TIMER;
|
||||
ELITE_DAC_TMR->BITMODE = NRF_TIMER_BIT_WIDTH_32;
|
||||
ELITE_DAC_TMR->INTENSET = NRF_TIMER_INT_COMPARE0_MASK;
|
||||
ELITE_DAC_TMR->CC[0] = period;
|
||||
ELITE_DAC_TMR->SHORTS = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK;
|
||||
sd_nvic_SetPriority(TIMER2_IRQn, _PRIO_APP_HIGH);
|
||||
sd_nvic_EnableIRQ(TIMER2_IRQn);
|
||||
|
||||
ELITE_DAC_TMR->TASKS_CLEAR = 1;
|
||||
ELITE_DAC_TMR->TASKS_START = 1;
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void edc20_dac_tim_stop(void)
|
||||
{
|
||||
NRF_LOG_INFO("%s()", __FUNCTION__);
|
||||
|
||||
__disable_irq();
|
||||
|
||||
dac_tmr_cb = NULL;
|
||||
dac_tmr_p_arg = NULL;
|
||||
|
||||
sd_nvic_DisableIRQ(TIMER2_IRQn);
|
||||
sd_nvic_ClearPendingIRQ(TIMER2_IRQn);
|
||||
ELITE_DAC_TMR->TASKS_STOP = 1;
|
||||
ELITE_DAC_TMR->SHORTS = 0;
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
#endif /* ! DEF_DAC_DRV_ENABLED */
|
||||
|
||||
#if (DEF_ADC_DRV_ENABLED)
|
||||
|
||||
#define ELITE_ADC_TMR NRF_TIMER3
|
||||
|
||||
void TIMER3_IRQHandler(void)
|
||||
{
|
||||
if (ELITE_ADC_TMR->EVENTS_COMPARE[0])
|
||||
{
|
||||
ELITE_ADC_TMR->EVENTS_COMPARE[0] = 0;
|
||||
|
||||
float mv;
|
||||
extern int adc_read_milivolt(uint32_t channel, float *mv);
|
||||
adc_read_milivolt(2, &mv);
|
||||
|
||||
float v = mv / 1000.0 - 5;
|
||||
|
||||
#if (DEF_RTT_JSCOP_ENABLED)
|
||||
extern void j_scope_update(float f);
|
||||
j_scope_update(v * 5);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ELITE_ADC_TMR->EVENTS_COMPARE[1])
|
||||
{
|
||||
ELITE_ADC_TMR->EVENTS_COMPARE[1] = 0;
|
||||
int32_t val;
|
||||
adc_read(1, &val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ELITE_ADC_TMR->EVENTS_COMPARE[2])
|
||||
{
|
||||
ELITE_ADC_TMR->EVENTS_COMPARE[2] = 0;
|
||||
int32_t val;
|
||||
adc_read(2, &val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void edc20_adc_tim_start(elite_dac_config_t *p_config)
|
||||
{
|
||||
NRF_LOG_INFO("%s()", __FUNCTION__);
|
||||
|
||||
/*
|
||||
ADC Sample rate 10KHz
|
||||
*/
|
||||
ELITE_ADC_TMR->PRESCALER = NRF_TIMER_FREQ_1MHz;
|
||||
ELITE_ADC_TMR->MODE = NRF_TIMER_MODE_TIMER;
|
||||
ELITE_ADC_TMR->BITMODE = NRF_TIMER_BIT_WIDTH_32;
|
||||
ELITE_ADC_TMR->INTENSET = NRF_TIMER_INT_COMPARE0_MASK;
|
||||
ELITE_ADC_TMR->CC[0] = 1000;
|
||||
ELITE_ADC_TMR->SHORTS = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK;
|
||||
sd_nvic_SetPriority(TIMER3_IRQn, _PRIO_APP_HIGH);
|
||||
sd_nvic_EnableIRQ(TIMER3_IRQn);
|
||||
}
|
||||
|
||||
void edc20_adc_tim_stop(void)
|
||||
{
|
||||
NRF_LOG_INFO("%s()", __FUNCTION__);
|
||||
}
|
||||
|
||||
#endif /* ! DEF_ADC_DRV_ENABLED */
|
||||
|
||||
void edc20_io_init(void)
|
||||
{
|
||||
gpio_init();
|
||||
twi_init();
|
||||
spi_init();
|
||||
}
|
||||
|
||||
void edc20_io_power_off(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(OFF_PIN);
|
||||
nrf_gpio_pin_clear(POWER_12V_EN_PIN);
|
||||
nrf_gpio_pin_clear(POWER_5V_EN_PIN);
|
||||
for (;;)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
void edc20_io_power_on(void)
|
||||
{
|
||||
uint32_t cnt = 0;
|
||||
for (int i = 0; i < 1000 / 50; i++)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
if (nrf_gpio_pin_read(SHUT_DOWN_PIN))
|
||||
{
|
||||
cnt++;
|
||||
if (cnt == 2)
|
||||
{
|
||||
edc20_io_power_off();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ! DEF_ELITE_MODEL */
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
#ifndef __EDC20_IO_H__
|
||||
#define __EDC20_IO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf_drv_spi.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
#define ADCA2_PIN NRF_GPIO_PIN_MAP(0, 25)
|
||||
#define ADCA1_PIN NRF_GPIO_PIN_MAP(0, 19)
|
||||
#define ADCA0_PIN NRF_GPIO_PIN_MAP(0, 21)
|
||||
#define RST_SW_PIN NRF_GPIO_PIN_MAP(0, 17)
|
||||
#define POWER_5V_EN_PIN NRF_GPIO_PIN_MAP(0, 24)
|
||||
#define POWER_12V_EN_PIN NRF_GPIO_PIN_MAP(0, 23)
|
||||
#define OFF_PIN NRF_GPIO_PIN_MAP(0, 15)
|
||||
#define SHUT_DOWN_PIN NRF_GPIO_PIN_MAP(1, 8)
|
||||
#define INT9466_PIN NRF_GPIO_PIN_MAP(0, 27)
|
||||
#define Vout_FB_PIN NRF_GPIO_PIN_MAP(0, 26)
|
||||
#define Vout_IN_PIN NRF_GPIO_PIN_MAP(0, 4)
|
||||
#define LEDTH_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
#define Iin4_TEST_PIN NRF_GPIO_PIN_MAP(1, 12)
|
||||
#define Iin3_SEL_PIN NRF_GPIO_PIN_MAP(1, 14)
|
||||
#define VBAT_PIN NRF_GPIO_PIN_MAP(0, 3)
|
||||
#define Iin3_PIN NRF_GPIO_PIN_MAP(1, 13)
|
||||
#define Iin2_PIN NRF_GPIO_PIN_MAP(1, 3)
|
||||
#define Iin1_PIN NRF_GPIO_PIN_MAP(1, 10)
|
||||
#define Vin2_PIN NRF_GPIO_PIN_MAP(1, 6)
|
||||
#define Vin1_PIN NRF_GPIO_PIN_MAP(1, 11)
|
||||
#define CV_CTRL_PIN NRF_GPIO_PIN_MAP(0, 16)
|
||||
|
||||
#define I2C0_SDA NRF_GPIO_PIN_MAP(0, 11)
|
||||
#define I2C0_SCL NRF_GPIO_PIN_MAP(0, 22)
|
||||
|
||||
#define SPI1_CLK_PIN NRF_GPIO_PIN_MAP(0, 13)
|
||||
#define SPI1_MOSI_PIN NRF_GPIO_PIN_MAP(0, 14)
|
||||
|
||||
#define CS_SW_PIN NRF_GPIO_PIN_MAP(0, 20)
|
||||
#define CS_MEM_PIN NRF_GPIO_PIN_MAP(0, 8)
|
||||
#define CS_ADC_PIN NRF_GPIO_PIN_MAP(0, 6)
|
||||
#define CS_DAC_PIN NRF_GPIO_PIN_MAP(0, 5)
|
||||
#define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 12)
|
||||
#define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 7)
|
||||
#define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float mV_start;
|
||||
float mV_stop;
|
||||
float mV_step;
|
||||
uint32_t uS_step;
|
||||
uint32_t cycles;
|
||||
bool hi_z_en;
|
||||
} elite_dac_config_t;
|
||||
|
||||
void gpio_init(void);
|
||||
void circuit_selection_vin_0(void);
|
||||
void circuit_selection_vin_1(void);
|
||||
void circuit_selection_vin_2(void);
|
||||
void circuit_selection_Iin_0(void);
|
||||
void circuit_selection_Iin_1(void);
|
||||
void circuit_selection_Iin_2(void);
|
||||
void circuit_selection_Iin_3(void);
|
||||
void circuit_selection_Iin_4(void);
|
||||
void circuit_selection_dac_coarse_tune_c(void);
|
||||
void circuit_selection_dac_fine_tune_f0(void);
|
||||
void circuit_selection_dac_fine_tune_f1(void);
|
||||
void circuit_selection_dac_fine_tune_f2(void);
|
||||
void circuit_selection_cv3_config(void);
|
||||
void circuit_selection_cc_config(void);
|
||||
void circuit_selection_dac_circuit_open(void);
|
||||
|
||||
void twi_init(void);
|
||||
void twi0_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t data_len);
|
||||
void twi0_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_rx_buf, uint8_t rx_buffer_length);
|
||||
|
||||
void spi_init(void);
|
||||
void spi1_write(uint8_t *p_tx_buffer, uint16_t tx_buffer_length);
|
||||
void spim_xfer(uint32_t cs_pin, nrf_spim_mode_t mode, uint8_t *p_tx_buffer, uint16_t tx_buffer_length, uint8_t *p_rx_buf, uint16_t rx_buffer_length);
|
||||
void spi2_set_mode(nrf_drv_spi_mode_t mode);
|
||||
|
||||
void edc20_io_init(void);
|
||||
void edc20_io_power_off(void);
|
||||
void edc20_io_power_on(void);
|
||||
|
||||
void edc20_dac_tim_start(uint32_t period, void (*callback)(void *p_arg), void *p_arg);
|
||||
void edc20_dac_tim_stop(void);
|
||||
|
||||
void edc20_adc_tim_start(elite_dac_config_t *p_config);
|
||||
void edc20_adc_tim_stop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __EDC20_IO_H__ */
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef __EIS_H__
|
||||
#define __EIS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "elite_def.h"
|
||||
|
||||
extern elite_instance_t eis_2_0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __EIS_H__ */
|
||||
@@ -1,261 +0,0 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "apply_old_config.h"
|
||||
#include "sdk_config.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "nrf_log_default_backends.h"
|
||||
|
||||
#include "nrf_sdh.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
#include "nrf_sdh_freertos.h"
|
||||
|
||||
#include "ble_srv_common.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
static QueueHandle_t regular_data_q = NULL;
|
||||
static SemaphoreHandle_t regular_data_sem = NULL;
|
||||
|
||||
typedef struct __PACKED
|
||||
{
|
||||
uint32_t timestamp;
|
||||
uint8_t id;
|
||||
uint8_t type : 4;
|
||||
uint8_t : 4;
|
||||
union
|
||||
{
|
||||
double double_val;
|
||||
float flaot_val;
|
||||
uint64_t u64_val;
|
||||
uint32_t u32_val;
|
||||
uint16_t u16_val;
|
||||
uint8_t u8_val;
|
||||
int64_t i64_val;
|
||||
int32_t i32_val;
|
||||
int16_t i16_val;
|
||||
int8_t i8_val;
|
||||
} content;
|
||||
uint8_t padding[2];
|
||||
} channel_data_t;
|
||||
|
||||
#define REGULAR_I8_TYPE 0
|
||||
#define REGULAR_I16_TYPE 1
|
||||
#define REGULAR_I32_TYPE 2
|
||||
#define REGULAR_I64_TYPE 3
|
||||
#define REGULAR_U8_TYPE 4
|
||||
#define REGULAR_U16_TYPE 5
|
||||
#define REGULAR_U32_TYPE 6
|
||||
#define REGULAR_U64_TYPE 7
|
||||
#define REGULAR_FLOAT_TYPE 8
|
||||
#define REGULAR_DOUBLE_TYPE 9
|
||||
#define REGULAR_MAX_TYPE 10
|
||||
|
||||
const uint32_t channel_size_table[REGULAR_MAX_TYPE] = {
|
||||
[REGULAR_I8_TYPE] = offsetof(channel_data_t, content) + sizeof(int8_t),
|
||||
[REGULAR_I16_TYPE] = offsetof(channel_data_t, content) + sizeof(int16_t),
|
||||
[REGULAR_I32_TYPE] = offsetof(channel_data_t, content) + sizeof(int32_t),
|
||||
[REGULAR_I64_TYPE] = offsetof(channel_data_t, content) + sizeof(int64_t),
|
||||
[REGULAR_U8_TYPE] = offsetof(channel_data_t, content) + sizeof(uint8_t),
|
||||
[REGULAR_U16_TYPE] = offsetof(channel_data_t, content) + sizeof(uint16_t),
|
||||
[REGULAR_U32_TYPE] = offsetof(channel_data_t, content) + sizeof(uint32_t),
|
||||
[REGULAR_U64_TYPE] = offsetof(channel_data_t, content) + sizeof(uint64_t),
|
||||
[REGULAR_FLOAT_TYPE] = offsetof(channel_data_t, content) + sizeof(float),
|
||||
[REGULAR_DOUBLE_TYPE] = offsetof(channel_data_t, content) + sizeof(double),
|
||||
};
|
||||
|
||||
void pseudo_sensorAA_read(channel_data_t *p_channel_data)
|
||||
{
|
||||
static uint32_t val = 0;
|
||||
p_channel_data->timestamp = xTaskGetTickCount();
|
||||
p_channel_data->id = 0xAA;
|
||||
p_channel_data->type = REGULAR_U32_TYPE;
|
||||
p_channel_data->content.u32_val = val++;
|
||||
}
|
||||
|
||||
void pseudo_sensorBB_read(channel_data_t *p_channel_data)
|
||||
{
|
||||
static uint32_t val = 0;
|
||||
p_channel_data->timestamp = xTaskGetTickCount();
|
||||
p_channel_data->id = 0xBB;
|
||||
p_channel_data->type = REGULAR_U32_TYPE;
|
||||
p_channel_data->content.u32_val = val--;
|
||||
}
|
||||
|
||||
static void pseudo_data_task(void *pArg)
|
||||
{
|
||||
void (*pfCallback)(channel_data_t *p_channel_data) = pArg;
|
||||
for (;;)
|
||||
{
|
||||
channel_data_t ch_data;
|
||||
memset(&ch_data, 0x00, sizeof(ch_data));
|
||||
pfCallback(&ch_data);
|
||||
if (xQueueSend(regular_data_q, &ch_data, pdMS_TO_TICKS(50)) == pdFAIL)
|
||||
{
|
||||
__BKPT(255);
|
||||
}
|
||||
else
|
||||
{
|
||||
portYIELD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static union
|
||||
{
|
||||
uint8_t raw[256];
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t len;
|
||||
uint8_t seq;
|
||||
uint16_t : 16;
|
||||
uint32_t time;
|
||||
uint8_t channel_len; /* channel len => group length */
|
||||
} header;
|
||||
} payload;
|
||||
|
||||
static void regular_data_msg_task(void *pArg)
|
||||
{
|
||||
|
||||
for (;;)
|
||||
{
|
||||
channel_data_t ch_data;
|
||||
|
||||
uint32_t offset = sizeof(payload.header);
|
||||
/*
|
||||
Receive a message on the regular_data_q queue.
|
||||
Block for forever if a message is not immediately available.
|
||||
*/
|
||||
if (xQueueReceive(regular_data_q, &ch_data, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
uint32_t channel_size = channel_size_table[ch_data.type % REGULAR_MAX_TYPE];
|
||||
memcpy(&payload.raw[offset], &ch_data, channel_size);
|
||||
offset += channel_size;
|
||||
/* set channel len = 1 */
|
||||
payload.header.channel_len = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
extern uint16_t le_gatt_mtu(void);
|
||||
uint16_t att_mtu = le_gatt_mtu() - 3;
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
Receive a message on the regular_data_q queue.
|
||||
Block for 50ms if a message is not immediately available.
|
||||
if there is no new message after 50ms, breaks out of the loop.
|
||||
*/
|
||||
if (xQueueReceive(regular_data_q, &ch_data, pdMS_TO_TICKS(50)) == pdTRUE)
|
||||
{
|
||||
/* set channel data total length. */
|
||||
uint32_t channel_size = channel_size_table[ch_data.type % REGULAR_MAX_TYPE];
|
||||
/* copy channel data to payload buffer. */
|
||||
memcpy(&payload.raw[offset], &ch_data, channel_size);
|
||||
offset += channel_size;
|
||||
/* increase channel len */
|
||||
payload.header.channel_len++;
|
||||
/* if payload length is almost full, breaks out of the loop. */
|
||||
if (offset > (att_mtu - (sizeof(ch_data) - 2) - 1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern bool le_regular_data_notify_is_enable(void);
|
||||
if (le_regular_data_notify_is_enable())
|
||||
{
|
||||
extern ret_code_t le_regular_data_notify(uint8_t * p_value, uint16_t len);
|
||||
/* update payload length & sequence number */
|
||||
payload.header.len = offset + 1;
|
||||
payload.header.seq++;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
/* update payload notify time */
|
||||
payload.header.time = xTaskGetTickCount();
|
||||
/* calculate checksum */
|
||||
uint8_t chksum = 0;
|
||||
for (uint32_t i = 0; i < offset; i++)
|
||||
{
|
||||
chksum += payload.raw[i];
|
||||
}
|
||||
/* append checksum */
|
||||
payload.raw[offset] = chksum;
|
||||
/* try to send notify */
|
||||
ret_code_t err_code = le_regular_data_notify(payload.raw, offset + 1);
|
||||
/* if notify success, breaks out of the loop. */
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* if timeout, breaks out of the loop. */
|
||||
if (xSemaphoreTake(regular_data_sem, pdMS_TO_TICKS(50)) == false)
|
||||
{
|
||||
NRF_LOG_INFO("regulat data underrun.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eis_regular_data_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
{
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
payload.header.seq = 0xFF;
|
||||
xQueueReset(regular_data_q);
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
break;
|
||||
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
|
||||
xSemaphoreGive(regular_data_sem);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void eis_regular_data_init(void)
|
||||
{
|
||||
regular_data_q = xQueueCreate(64, sizeof(channel_data_t));
|
||||
if (regular_data_q == NULL)
|
||||
{
|
||||
// Will not get here unless there is insufficient RAM.
|
||||
__BKPT(255);
|
||||
}
|
||||
|
||||
regular_data_sem = xSemaphoreCreateBinary();
|
||||
if (regular_data_sem == NULL)
|
||||
{
|
||||
// Will not get here unless there is insufficient RAM.
|
||||
__BKPT(255);
|
||||
}
|
||||
|
||||
xTaskCreate(regular_data_msg_task, "regular_msg", 192, NULL, 5, NULL);
|
||||
xTaskCreate(pseudo_data_task, "pseudo_AA", 192, pseudo_sensorAA_read, 2, NULL);
|
||||
xTaskCreate(pseudo_data_task, "pseudo_BB", 192, pseudo_sensorBB_read, 2, NULL);
|
||||
NRF_SDH_BLE_OBSERVER(m_eis_regular_data_observer, 3, eis_regular_data_handler, NULL);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#include "elite.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_DEV)
|
||||
#include "elite_dev.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#include "edc.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
#include "pel.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
#include "cpg.h"
|
||||
#else
|
||||
#error "Unknown DEF_ELITE_MODEL"
|
||||
#endif
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "nrf_log_default_backends.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "message_buffer.h"
|
||||
#include "stream_buffer.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const elite_instance_t *p_instance = NULL;
|
||||
|
||||
MessageBufferHandle_t instr_msg = NULL;
|
||||
|
||||
static void decode_ris_ins(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
uint8_t oper = ins[2];
|
||||
if (p_instance->ris_func[oper])
|
||||
{
|
||||
p_instance->ris_func[oper](ins, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_LOG_INFO("unknown ris instruction");
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_vis_ins(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
uint8_t oper = ins[1] & 0xF0; // this is don't care in RISASD;//
|
||||
if (p_instance->vis_func[oper])
|
||||
{
|
||||
p_instance->vis_func[oper](ins, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_LOG_INFO("unknown vis instruction");
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_cis_ins(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
uint8_t oper = ins[1] & 0xF0;
|
||||
if (p_instance->cis_func[oper])
|
||||
{
|
||||
p_instance->cis_func[oper](ins, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_LOG_INFO("unknown vis instruction");
|
||||
}
|
||||
}
|
||||
|
||||
static void elite_instr_task(void *p_arg)
|
||||
{
|
||||
static size_t instr_size = 0;
|
||||
static uint8_t instr[256];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
instr_size = xMessageBufferReceive(instr_msg, instr, sizeof(instr), portMAX_DELAY);
|
||||
|
||||
if (instr_size)
|
||||
{
|
||||
uint16_t ins_type = instr[0] & 0b11110000;
|
||||
uint16_t chip_id = instr[0] & 0b00001111;
|
||||
switch (ins_type)
|
||||
{
|
||||
case INS_TYPE_RIS:
|
||||
decode_ris_ins(instr, instr_size);
|
||||
break;
|
||||
case INS_TYPE_VIS:
|
||||
decode_vis_ins(instr, instr_size);
|
||||
break;
|
||||
case INS_TYPE_CIS:
|
||||
decode_cis_ins(instr, instr_size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void elite_init(void)
|
||||
{
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_DEV)
|
||||
p_instance = dev_init();
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
edc.init();
|
||||
p_instance = edc.p_elite_instance;
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
p_instance = pel_init();
|
||||
#elif (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
p_instance = cpg_init();
|
||||
#else
|
||||
#error "Unknown DEF_ELITE_MODEL"
|
||||
#endif
|
||||
|
||||
instr_msg = xMessageBufferCreate(1024);
|
||||
xTaskCreate(elite_instr_task, "elite_instr", 2048, NULL, 3, NULL);
|
||||
}
|
||||
|
||||
void elite_instr_send(void *p, size_t size)
|
||||
{
|
||||
/* reply the instruction */
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate(p, size);
|
||||
|
||||
xMessageBufferSend(instr_msg, p, size, portMAX_DELAY);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef __ELITE_H__
|
||||
#define __ELITE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "elite_def.h"
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void elite_init(void);
|
||||
void elite_instr_send(void *p, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_H__ */
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "elite_adc.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
|
||||
void IinADCGainCtrl(uint8_t IinADCLevel) { NRF_LOG_INFO("%s", __FUNCTION__); }
|
||||
void VinADCGainCtrl(uint8_t VinADCLevel) { NRF_LOG_INFO("%s", __FUNCTION__); }
|
||||
void AutoGainChangeIin(int32_t RealCurrent, uint16_t plot_type, uint16_t *no_rec_time) { NRF_LOG_INFO("%s", __FUNCTION__); }
|
||||
void AutoGainChangeVin(int32_t RealVin) { NRF_LOG_INFO("%s", __FUNCTION__); }
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#ifndef __ELITE_ADC_H__
|
||||
#define __ELITE_ADC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void IinADCGainCtrl(uint8_t IinADCLevel);
|
||||
void VinADCGainCtrl(uint8_t VinADCLevel);
|
||||
void AutoGainChangeIin(int32_t RealCurrent, uint16_t plot_type, uint16_t *no_rec_time);
|
||||
void AutoGainChangeVin(int32_t RealVin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_ADC_H__ */
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "elite_board.h"
|
||||
|
||||
void elite_board_init(void)
|
||||
{
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
edc20_io_init();
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
pel10_io_init();
|
||||
#elif (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
cpg10_io_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void elite_board_power_off(void)
|
||||
{
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
edc20_io_power_off();
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
#elif (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
#endif
|
||||
}
|
||||
|
||||
void elite_drv_init(void)
|
||||
{
|
||||
btn_init();
|
||||
led_init();
|
||||
led_set(LED_IDEL_DISCONNECT);
|
||||
sw_init();
|
||||
adc_init();
|
||||
dac_init();
|
||||
fs_init();
|
||||
|
||||
#if (DEF_FS_ENABLED && DEF_FS_RTT_DIR)
|
||||
if (1)
|
||||
{
|
||||
static file_t hFile;
|
||||
char write[64];
|
||||
char read[64];
|
||||
|
||||
memset(write, 0x00, sizeof(write));
|
||||
snprintf(write, sizeof(write), "Hellow %s Build: %s %s", ELITE_DEVICE_NAME, __TIME__, __DATE__);
|
||||
|
||||
fs_file_open(&hFile, "default.txt", FS_O_CREAT | FS_O_RDWR | FS_O_TRUNC);
|
||||
fs_file_write(&hFile, write, strlen(write));
|
||||
fs_file_close(&hFile);
|
||||
|
||||
memset(read, 0x00, sizeof(read));
|
||||
|
||||
fs_file_open(&hFile, "default.txt", FS_O_RDONLY);
|
||||
fs_file_read(&hFile, read, sizeof(read));
|
||||
fs_file_close(&hFile);
|
||||
NRF_LOG_INFO("%s", read);
|
||||
|
||||
fs_dir("/");
|
||||
}
|
||||
#endif /* ! DEF_FS_ENABLE */
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef __ELITE_BOARD_H__
|
||||
#define __ELITE_BOARD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "adc_drv.h"
|
||||
#include "app_config.h"
|
||||
#include "btn.h"
|
||||
#include "dac_drv.h"
|
||||
#include "fs.h"
|
||||
#include "led_drv.h"
|
||||
#include "sw_drv.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_DEV)
|
||||
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#include "edc20_io.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
#include "pel10_io.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_10)
|
||||
#include "cpg10_io.h"
|
||||
#else
|
||||
#error "Not implemented xxx_io.h"
|
||||
#endif
|
||||
|
||||
void elite_board_init(void);
|
||||
void elite_board_power_off(void);
|
||||
void elite_drv_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_BOARD_H__ */
|
||||
+3349
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
||||
#ifndef __ELITE_CORRECTION_H__
|
||||
#define __ELITE_CORRECTION_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BOARD_EE_EF 1
|
||||
|
||||
struct formula_ctx_t
|
||||
{
|
||||
long long coeff;
|
||||
long long offset;
|
||||
};
|
||||
|
||||
struct correction_ctx_t
|
||||
{
|
||||
struct formula_ctx_t ADC_volt[3];
|
||||
struct formula_ctx_t ADC_current[4];
|
||||
struct formula_ctx_t Usercode2DAC[2];
|
||||
struct formula_ctx_t ADC_Vout_volt[1];
|
||||
uint16_t Gain0Boundary[2];
|
||||
uint16_t Gain1Boundary[4];
|
||||
uint16_t Gain2Boundary[2];
|
||||
};
|
||||
|
||||
int32_t DecodeADCValue(uint8_t adc_gain, uint8_t adc_channel, uint16_t adc_rxbuf);
|
||||
uint16_t Usercode_Correction_to_DAC(uint8_t dac_gain, uint16_t usercode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_CORRECTION_H__ */
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
#include "elite_dac.h"
|
||||
#include "edc.h"
|
||||
|
||||
static bool DACReset;
|
||||
|
||||
void VoutGainControl(uint8_t VOUTLevel)
|
||||
{
|
||||
switch (VOUTLevel)
|
||||
{
|
||||
case 0:
|
||||
// VOUT gain level = 0, using 240K resister
|
||||
break;
|
||||
case 1:
|
||||
// VOUT gain level = 1, using 15K resister
|
||||
break;
|
||||
case 2:
|
||||
// VOUT gain level = 2, using 15K resister
|
||||
break;
|
||||
default:
|
||||
// default using 15K resister
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t User2Real(uint16_t usr_code)
|
||||
{
|
||||
/* transfer usr_code to real voltage value (mV) */
|
||||
return (int32_t)((usr_code - 25000) / 5);
|
||||
}
|
||||
|
||||
void AutoGainChangeVout(uint32_t *p_VoutGainLv, int32_t usr_code)
|
||||
{
|
||||
int32_t RealVolt = (usr_code - 25000) * 200; // (usr_code - 25000) / 5 * 1000 [1uV]
|
||||
// switch to 1 level volt(small) 15K
|
||||
// switch to 2 level volt(large) 240K
|
||||
|
||||
if (*p_VoutGainLv == VOUT_GAIN_15K)
|
||||
{
|
||||
if (RealVolt > DAC_VOUT_GAIN_LARGE_BOUNDARY || RealVolt < -1 * DAC_VOUT_GAIN_LARGE_BOUNDARY)
|
||||
{
|
||||
// switch to 2 level volt(large)
|
||||
*p_VoutGainLv = VOUT_GAIN_240K;
|
||||
VoutGainControl(edc.instru.VoutGainLv);
|
||||
}
|
||||
}
|
||||
else if (*p_VoutGainLv == VOUT_GAIN_240K)
|
||||
{
|
||||
if (RealVolt < DAC_VOUT_GAIN_SMALL_BOUNDARY && RealVolt > -1 * DAC_VOUT_GAIN_SMALL_BOUNDARY)
|
||||
{
|
||||
// switch to 1 level volt(small)
|
||||
*p_VoutGainLv = VOUT_GAIN_15K;
|
||||
VoutGainControl(edc.instru.VoutGainLv);
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#ifndef __ELITE_DAC_H__
|
||||
#define __ELITE_DAC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DACCLS 0x02
|
||||
#define DACOUT 0x31
|
||||
|
||||
// DAC Vout theoretical boundary <300, 100~ (mV)
|
||||
#define DAC_VOUT_GAIN_SMALL_BOUNDARY 100000 // 25500(usercode) = 100 mV
|
||||
#define DAC_VOUT_GAIN_LARGE_BOUNDARY 300000 // 26500(usercode) = 300 mV
|
||||
#define DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE 26500 // 26500(usercode) = 300 mV
|
||||
#define DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE 23500 // 23500(usercode) = -300 mV
|
||||
|
||||
void VoutGainControl(uint8_t VOUTLevel);
|
||||
int32_t User2Real(uint16_t UserCode);
|
||||
void AutoGainChangeVout(uint32_t *p_VoutGainLv, int32_t usr_code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_DAC_H__ */
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
#ifndef __ELITE_DEF_H__
|
||||
#define __ELITE_DEF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// define BT instruction
|
||||
#define INS_TYPE_RIS 0x30
|
||||
#define INS_TYPE_VIS 0xC0
|
||||
#define INS_TYPE_CIS 0x70
|
||||
|
||||
// VIS (virtual instruction)
|
||||
#define VIS_RST 0xF0
|
||||
#define VIS_ASK 0x30
|
||||
#define VIS_STI 0xC0
|
||||
#define VIS_INT 0x60
|
||||
#define VIS_DEVICE_SHINY 0x10
|
||||
#define VIS_SHINY_DIS 0x20
|
||||
|
||||
// RIS (real instruction)
|
||||
enum all_mode_e
|
||||
{
|
||||
CURVE_IV = 0x01, // I-V Curve
|
||||
CURVE_IV_CY = 0x02, // Cycle I-V
|
||||
CURVE_VO = 0x03, // Function Generator
|
||||
CURVE_RT = 0x04, // R-T Graph
|
||||
CURVE_VT = 0x05, // V-T Graph
|
||||
CURVE_IT = 0x06, // I-T Graph
|
||||
CURVE_CC = 0x07, // Constant Current (CC)
|
||||
CURVE_OCP = 0x08, // Open Circuit Potential (OCP)
|
||||
CURVE_CV = 0x09, // Cyclic Voltammetry (CV)
|
||||
CURVE_LSV = 0x0A, // Linear Sweep Voltammetry (LSV)
|
||||
CURVE_CA = 0x0B, // Chronoamperometric Graph (CA)
|
||||
CURVE_CP = 0x0C, // Chronopotentiometry (CP)
|
||||
CURVE_UNI_PULSE = 0x0D, // Pulse Sensing (universal pulse)
|
||||
CURVE_DPV = 0x0E, // Differential Pulse Voltammetry (DPV)
|
||||
CURVE_DPV_ADVANCE = 0x0F,
|
||||
CURVE_DPV_SMPRATE = 0x10,
|
||||
CURVE_DPV_ADVANCE_SMPRATE = 0x11,
|
||||
CURVE_EIS = 0x12,
|
||||
CURVE_CF = 0x13, // Constant Frequency(CF)
|
||||
CURVE_CALI = 0xF1,
|
||||
SET_SAMPLE_RATE = 0xE0,
|
||||
DEV_MODE = 0xFF, // Develop Mode
|
||||
};
|
||||
|
||||
// CIS (control instruction)
|
||||
#define CIS_VERSION 0x40
|
||||
#define CIS_VOLT 0x10
|
||||
#define CIS_TEMPERATURE 0x80
|
||||
#define CIS_LED_TEST 0x70
|
||||
#define CIS_CALI 0x30
|
||||
#define CIS_CALI2 0x90
|
||||
|
||||
#define CTL_WRT 0x20
|
||||
#define CTL_RD 0x21
|
||||
#define CTL_RD_DFTR 0x78
|
||||
#define CTL_RD_DFTI 0x7C
|
||||
#define CTL_RD_ADC 0x7A
|
||||
#define CTL_RESET 0x11
|
||||
|
||||
// mode parameter
|
||||
|
||||
#define VMAX(v1, v2) ((v1 >= v2) ? v1 : v2)
|
||||
#define VMIN(v1, v2) ((v1 < v2) ? v1 : v2)
|
||||
#define VDIRECTION(v1, v2) ((v1 > v2) ? 0 : 1)
|
||||
#define AFTER_READ_I 0
|
||||
#define AFTER_READ_V 1
|
||||
#define PARA_1 0x01
|
||||
#define PARA_2 0x02
|
||||
#define PARA_3 0x03
|
||||
#define PARA_4 0x04
|
||||
#define PARA_5 0x05
|
||||
#define PARA_6 0x06
|
||||
#define PARA_7 0x07
|
||||
#define PARA_8 0x08
|
||||
#define PARA_9 0x09
|
||||
#define PARA_10 0x0A
|
||||
#define PARA_11 0x0B
|
||||
#define PARA_12 0x0C
|
||||
#define PARA_13 0x0D
|
||||
#define PARA_14 0x0E
|
||||
#define PARA_15 0x0F
|
||||
#define PARA_16 0x10
|
||||
#define PARA_17 0x11
|
||||
|
||||
// Elite LED
|
||||
#define COLOR_BLACK 0x00
|
||||
#define COLOR_RED 0x01
|
||||
#define COLOR_ORANGE 0x02
|
||||
#define COLOR_YELLOW 0x03
|
||||
#define COLOR_GREEN 0x04
|
||||
#define COLOR_BLUE 0x05
|
||||
#define COLOR_CYAN 0x06
|
||||
#define COLOR_MAGENTA 0x07
|
||||
#define COLOR_PURPLE 0x08
|
||||
#define COLOR_WHITE 0x09
|
||||
#define COLOR_YELLOWGREEN 0x0A
|
||||
|
||||
#define BT_WAIT 0x01
|
||||
#define NO_EVENT 0x02
|
||||
#define PRE_WORK 0x03
|
||||
#define WORKING 0x04
|
||||
#define POST_WORK 0x05
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*cis_func[256])(uint8_t *ins, uint16_t size);
|
||||
void (*vis_func[256])(uint8_t *ins, uint16_t size);
|
||||
void (*ris_func[256])(uint8_t *ins, uint16_t size);
|
||||
} elite_instance_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_DEF_H__ */
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
#include "elite_dev.h"
|
||||
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_DEV)
|
||||
|
||||
#define VERSION_DATE_YEAR 24
|
||||
#define VERSION_DATE_MONTH 7
|
||||
#define VERSION_DATE_DAY 2
|
||||
#define VERSION_DATE_HOUR 11
|
||||
#define VERSION_DATE_MINUTE 32
|
||||
static void cis_version(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
uint8_t cis_ver[] = {
|
||||
CIS_VERSION,
|
||||
VERSION_DATE_YEAR,
|
||||
VERSION_DATE_MONTH,
|
||||
VERSION_DATE_DAY,
|
||||
VERSION_DATE_HOUR,
|
||||
VERSION_DATE_MINUTE,
|
||||
};
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)cis_ver, sizeof(cis_ver));
|
||||
}
|
||||
|
||||
static void vis_rst(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
}
|
||||
|
||||
#define UNDEF_GPIO 0xFFFFFFFF
|
||||
|
||||
// The GPIO corresponding to the pin
|
||||
const uint32_t pin_to_gpio_table[] = {
|
||||
[6] = NRF_GPIO_PIN_MAP(0, 22),
|
||||
[8] = NRF_GPIO_PIN_MAP(0, 25),
|
||||
[9] = NRF_GPIO_PIN_MAP(0, 19),
|
||||
[10] = NRF_GPIO_PIN_MAP(0, 21),
|
||||
[11] = NRF_GPIO_PIN_MAP(1, 00),
|
||||
[12] = NRF_GPIO_PIN_MAP(0, 18),
|
||||
[13] = NRF_GPIO_PIN_MAP(0, 17),
|
||||
[14] = NRF_GPIO_PIN_MAP(0, 20),
|
||||
[16] = NRF_GPIO_PIN_MAP(0, 14),
|
||||
[17] = NRF_GPIO_PIN_MAP(0, 13),
|
||||
[18] = NRF_GPIO_PIN_MAP(0, 11),
|
||||
[20] = NRF_GPIO_PIN_MAP(0, 15),
|
||||
[25] = NRF_GPIO_PIN_MAP(1, 8),
|
||||
[26] = NRF_GPIO_PIN_MAP(0, 12),
|
||||
[27] = NRF_GPIO_PIN_MAP(0, 7),
|
||||
[28] = NRF_GPIO_PIN_MAP(1, 9),
|
||||
[29] = NRF_GPIO_PIN_MAP(0, 8),
|
||||
[30] = NRF_GPIO_PIN_MAP(0, 6),
|
||||
[31] = NRF_GPIO_PIN_MAP(0, 5),
|
||||
[32] = NRF_GPIO_PIN_MAP(0, 27),
|
||||
[33] = NRF_GPIO_PIN_MAP(0, 26),
|
||||
[34] = NRF_GPIO_PIN_MAP(0, 4),
|
||||
[36] = NRF_GPIO_PIN_MAP(0, 1),
|
||||
[37] = NRF_GPIO_PIN_MAP(0, 29),
|
||||
[38] = NRF_GPIO_PIN_MAP(0, 0),
|
||||
[39] = NRF_GPIO_PIN_MAP(0, 31),
|
||||
[40] = NRF_GPIO_PIN_MAP(1, 15),
|
||||
[41] = NRF_GPIO_PIN_MAP(0, 2),
|
||||
[42] = NRF_GPIO_PIN_MAP(0, 30),
|
||||
[43] = NRF_GPIO_PIN_MAP(0, 28),
|
||||
[44] = NRF_GPIO_PIN_MAP(1, 12),
|
||||
[45] = NRF_GPIO_PIN_MAP(1, 14),
|
||||
[46] = NRF_GPIO_PIN_MAP(0, 3),
|
||||
[47] = NRF_GPIO_PIN_MAP(1, 13),
|
||||
[48] = NRF_GPIO_PIN_MAP(1, 3),
|
||||
[49] = NRF_GPIO_PIN_MAP(1, 10),
|
||||
[50] = NRF_GPIO_PIN_MAP(1, 6),
|
||||
[51] = NRF_GPIO_PIN_MAP(1, 11),
|
||||
[52] = NRF_GPIO_PIN_MAP(0, 10),
|
||||
[53] = NRF_GPIO_PIN_MAP(0, 9),
|
||||
[59] = NRF_GPIO_PIN_MAP(1, 2),
|
||||
[60] = NRF_GPIO_PIN_MAP(0, 24),
|
||||
[61] = NRF_GPIO_PIN_MAP(0, 23),
|
||||
[62] = NRF_GPIO_PIN_MAP(0, 16),
|
||||
};
|
||||
|
||||
static uint32_t bmd380pins_convert_to_gpio(uint32_t pin)
|
||||
{
|
||||
uint32_t gpio;
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 6:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 20:
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
case 36:
|
||||
case 37:
|
||||
case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 50:
|
||||
case 51:
|
||||
case 52:
|
||||
case 53:
|
||||
case 59:
|
||||
case 60:
|
||||
case 61:
|
||||
case 62:
|
||||
gpio = pin_to_gpio_table[pin];
|
||||
break;
|
||||
default:
|
||||
gpio = UNDEF_GPIO;
|
||||
NRF_LOG_INFO("UNDEF_GPIO: pin %d can't convert to gpio number", pin);
|
||||
break;
|
||||
}
|
||||
|
||||
return gpio;
|
||||
}
|
||||
|
||||
static void set_bmd380_pin_signal(uint32_t pin, uint32_t high_low)
|
||||
{
|
||||
uint32_t gpio = bmd380pins_convert_to_gpio(pin);
|
||||
|
||||
if (gpio != UNDEF_GPIO)
|
||||
{
|
||||
nrf_gpio_cfg_output(gpio);
|
||||
nrf_gpio_pin_write(gpio, high_low);
|
||||
NRF_LOG_INFO("set pin %d (gpio %d) = %d", pin, gpio, high_low);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
dev_mode_gpio_function
|
||||
(1)0x3000FFA000ppss
|
||||
-func: set_bmd380_pin_signal
|
||||
-pp: pin number 06h-3Fh
|
||||
06h: P0.22_GPIO
|
||||
08h: P0.25_GPIO
|
||||
......
|
||||
3Eh: P0.16_GPIO
|
||||
-ss: signal 00h-01h
|
||||
00h: low
|
||||
01h: high
|
||||
|
||||
(2)0x3000FFA001ss
|
||||
-func: set_bmd380 all pin signal high/low
|
||||
-ss: signal 00h-01h
|
||||
00h: low
|
||||
01h: high
|
||||
*/
|
||||
void dev_mode_gpio_function(uint8_t *ins)
|
||||
{
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint16_t magic : 16;
|
||||
uint8_t dev_opcode;
|
||||
uint8_t gpio_function_opcode;
|
||||
uint8_t param[];
|
||||
} *p_ins = (void *)ins;
|
||||
|
||||
switch (p_ins->gpio_function_opcode)
|
||||
{
|
||||
case 0x00: {
|
||||
uint32_t pin = p_ins->param[0];
|
||||
uint32_t high_low = p_ins->param[1];
|
||||
set_bmd380_pin_signal(pin, high_low);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x01: {
|
||||
uint32_t high_low = p_ins->param[0];
|
||||
uint32_t set_pin[44] = {6, 8, 9, 10, 11, 12, 13, 14, 16, 17,
|
||||
18, 20, 25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
59, 60, 61, 62};
|
||||
|
||||
for (int i=0; i<sizeof(set_pin) / sizeof(set_pin[0]); i++)
|
||||
{
|
||||
set_bmd380_pin_signal(set_pin[i], high_low);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MAGIC_NUM 0xFF00
|
||||
static void dev_mode(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint16_t magic : 16;
|
||||
uint8_t opcode;
|
||||
uint8_t param[];
|
||||
} *p_ins = (void *)ins;
|
||||
|
||||
if (p_ins->magic != MAGIC_NUM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO...
|
||||
switch (p_ins->opcode)
|
||||
{
|
||||
case 0xA0:
|
||||
dev_mode_gpio_function(ins);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const elite_instance_t pel_elite_instance = {
|
||||
.cis_func = {
|
||||
[CIS_VERSION] = cis_version,
|
||||
},
|
||||
.vis_func = {
|
||||
[VIS_RST] = vis_rst,
|
||||
},
|
||||
.ris_func = {
|
||||
[DEV_MODE] = dev_mode,
|
||||
}
|
||||
};
|
||||
|
||||
const elite_instance_t *dev_init(void)
|
||||
{
|
||||
return &pel_elite_instance;
|
||||
}
|
||||
|
||||
#endif /* !DEF_ELITE_MODEL */
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
#ifndef __ELITE_DEV_H__
|
||||
#define __ELITE_DEV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite.h"
|
||||
|
||||
const elite_instance_t *dev_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __ELITE_DEV_H__ */
|
||||
@@ -0,0 +1,205 @@
|
||||
#include "fs.h"
|
||||
|
||||
#include "nrf.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_GD25D10C_ENABLED)
|
||||
#include "gd25d10c.h"
|
||||
static const block_dev_drv_if_t *p_inst = &gd25d110c;
|
||||
#endif /* ! DEF_GD25D10C_ENABLED */
|
||||
|
||||
#if (DEF_FS_ENABLED)
|
||||
static SemaphoreHandle_t m_sem = NULL;
|
||||
static struct lfs_config lfs_config;
|
||||
static lfs_t lfs;
|
||||
|
||||
static int lfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
|
||||
{
|
||||
if (c->context == NULL)
|
||||
{
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
p_inst->read_data(buffer, block * c->block_size + off, size);
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
|
||||
static int lfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
|
||||
{
|
||||
if (c->context == NULL)
|
||||
{
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
p_inst->page_prog((void *)buffer, block * c->block_size + off, size / c->prog_size);
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
|
||||
static int lfs_erase(const struct lfs_config *c, lfs_block_t block)
|
||||
{
|
||||
if (c->context == NULL)
|
||||
{
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
p_inst->sect_erase(block * c->block_size, 1);
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
|
||||
static int lfs_sync(const struct lfs_config *c)
|
||||
{
|
||||
if (c->context == NULL)
|
||||
{
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
|
||||
static int lfs_lock(const struct lfs_config *c)
|
||||
{
|
||||
if (c->context == NULL)
|
||||
{
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
xSemaphoreTake(m_sem, portMAX_DELAY);
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
|
||||
static int lfs_unlock(const struct lfs_config *c)
|
||||
{
|
||||
if (c->context == NULL)
|
||||
{
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
xSemaphoreGive(m_sem);
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
|
||||
void fs_init(void)
|
||||
{
|
||||
m_sem = xSemaphoreCreateMutex();
|
||||
|
||||
if (p_inst->init() == BLOCK_DEV_SUCCESS)
|
||||
{
|
||||
lfs_config.context = (void *)p_inst;
|
||||
|
||||
// block device operations
|
||||
lfs_config.read = lfs_read;
|
||||
lfs_config.prog = lfs_prog;
|
||||
lfs_config.erase = lfs_erase;
|
||||
lfs_config.sync = lfs_sync;
|
||||
lfs_config.lock = lfs_lock;
|
||||
lfs_config.unlock = lfs_unlock;
|
||||
|
||||
// block device configuration
|
||||
lfs_config.read_size = 1;
|
||||
lfs_config.prog_size = p_inst->page_size;
|
||||
lfs_config.block_size = p_inst->sect_size;
|
||||
lfs_config.block_count = p_inst->sect_count;
|
||||
lfs_config.block_cycles = 5000;
|
||||
lfs_config.cache_size = p_inst->page_size;
|
||||
lfs_config.lookahead_size = sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (lfs_mount(&lfs, &lfs_config) < 0)
|
||||
{
|
||||
if (lfs_format(&lfs, &lfs_config) < 0)
|
||||
{
|
||||
__BKPT(255);
|
||||
}
|
||||
if (lfs_mount(&lfs, &lfs_config) < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fs_file_open(file_t *hFile, char *filename, uint32_t attr)
|
||||
{
|
||||
int ret = lfs_file_open(&lfs, hFile, filename, attr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs_file_write(file_t *hFile, void *write, uint32_t size)
|
||||
{
|
||||
int ret = lfs_file_write(&lfs, hFile, write, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs_file_read(file_t *hFile, void *read, uint32_t size)
|
||||
{
|
||||
int ret = lfs_file_read(&lfs, hFile, read, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs_file_close(file_t *hFile)
|
||||
{
|
||||
int ret = lfs_file_close(&lfs, hFile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs_dir(char *path)
|
||||
{
|
||||
int ret = 0;
|
||||
int fileCount = 0;
|
||||
int dirCount = 0;
|
||||
int totalFileSize = 0;
|
||||
|
||||
char *str = pvPortMalloc(256);
|
||||
lfs_dir_t *dir = pvPortMalloc(sizeof(lfs_dir_t));
|
||||
struct lfs_info *info = pvPortMalloc(sizeof(struct lfs_info));
|
||||
|
||||
snprintf(str, 256, "Directory of %s", path);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
|
||||
ret = lfs_dir_open(&lfs, dir, path);
|
||||
|
||||
if (ret == LFS_ERR_OK)
|
||||
{
|
||||
do {
|
||||
ret = lfs_dir_read(&lfs, dir, info);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
snprintf(str,
|
||||
256,
|
||||
"%5s%10ld bytes %s",
|
||||
info->type == LFS_TYPE_REG ? " " : info->type == LFS_TYPE_DIR ? "<dir>" :
|
||||
"unkown",
|
||||
info->size,
|
||||
info->name);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
switch (info->type)
|
||||
{
|
||||
case LFS_TYPE_REG:
|
||||
fileCount++;
|
||||
totalFileSize += info->size;
|
||||
break;
|
||||
case LFS_TYPE_DIR:
|
||||
dirCount++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(str, 256, "%15d dir(s)", dirCount);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
snprintf(str, 256, "%15d file(s), total %d byets", fileCount, totalFileSize);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
}
|
||||
} while (ret > 0);
|
||||
|
||||
ret = lfs_dir_close(&lfs, dir);
|
||||
}
|
||||
|
||||
vPortFree(info);
|
||||
vPortFree(dir);
|
||||
vPortFree(str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !DEF_FS_ENABLED */
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef __FS_H__
|
||||
#define __FS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
|
||||
#include "lfs.h"
|
||||
#include "lfs_util.h"
|
||||
|
||||
typedef lfs_file_t file_t;
|
||||
|
||||
#define FS_O_RDONLY LFS_O_RDONLY // Open a file as read only
|
||||
#define FS_O_WRONLY LFS_O_WRONLY // Open a file as write only
|
||||
#define FS_O_RDWR LFS_O_RDWR // Open a file as read and write
|
||||
#define FS_O_CREAT LFS_O_CREAT // Create a file if it does not exist
|
||||
#define FS_O_EXCL LFS_O_EXCL // Fail if a file already exists
|
||||
#define FS_O_TRUNC LFS_O_TRUNC // Truncate the existing file to zero size
|
||||
#define FS_O_APPEND LFS_O_APPEND // Move to end of file on every write
|
||||
|
||||
#if (DEF_FS_ENABLED)
|
||||
void fs_init(void);
|
||||
int fs_file_open(file_t *hFile, char *filename, uint32_t attr);
|
||||
int fs_file_write(file_t *hFile, void *write, uint32_t size);
|
||||
int fs_file_read(file_t *hFile, void *read, uint32_t size);
|
||||
int fs_file_close(file_t *hFile);
|
||||
int fs_dir(char *path);
|
||||
#else
|
||||
#define fs_init()
|
||||
#define fs_file_write(x, y, z)
|
||||
#define fs_file_read(x, y, z)
|
||||
#define fs_file_close(x)
|
||||
#define fs_dir(x)
|
||||
#endif /* ! DEF_FS_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __FS_H__ */
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
#include "gd25d10c.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if (DEF_GD25D10C_ENABLED)
|
||||
|
||||
#define ERASE_BLOCK_SIZE (32 * 1024)
|
||||
#define ERASE_SECT_SIZE 4096
|
||||
#define PROG_PAGE_SIZE 256
|
||||
#define PAGE_PER_SECT 16
|
||||
#define PAGE_PER_BLOCK 128
|
||||
#define SECT_PER_BLOCK 8
|
||||
#define BLOCK_PER_DEV 4
|
||||
|
||||
#define CMD_READ 0x03
|
||||
#define CMD_WREN 0x06
|
||||
#define CMD_WRDI 0x04
|
||||
#define CMD_RDSR 0x05
|
||||
#define CMD_WRSR 0x01
|
||||
#define CMD_PP 0x02
|
||||
#define CMD_RDID 0x9F
|
||||
#define CMD_SE 0x20
|
||||
#define CMD_BE 0x52
|
||||
|
||||
#define WIP_BIT 0x01
|
||||
#define WEL_BIT 0x02
|
||||
|
||||
#define MANUFACTURER_ID 0xC8
|
||||
#define MEMORY_TYPE 0x40
|
||||
#define CAPACITY 0x11
|
||||
|
||||
#define EXPECT_ID ((MANUFACTURER_ID << 16) | (MEMORY_TYPE << 8) | (CAPACITY << 0))
|
||||
|
||||
uint8_t xfer_buf[4096 + 32];
|
||||
|
||||
static int read_data(uint8_t *p_dest, uint32_t addr, uint32_t size)
|
||||
{
|
||||
struct send
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t val;
|
||||
struct
|
||||
{
|
||||
uint32_t addr : 24;
|
||||
uint32_t cmd : 8;
|
||||
};
|
||||
};
|
||||
} *p_tx = (void *)xfer_buf;
|
||||
|
||||
struct recv
|
||||
{
|
||||
uint32_t dummy;
|
||||
uint8_t recv[0];
|
||||
} *p_rx = (void *)xfer_buf;
|
||||
|
||||
p_tx->cmd = CMD_READ;
|
||||
p_tx->addr = addr;
|
||||
p_tx->val = __REV(p_tx->val);
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), (void *)p_rx, offsetof(struct recv, recv) + size);
|
||||
memcpy(p_dest, &xfer_buf[sizeof(*p_tx)], size);
|
||||
return BLOCK_DEV_SUCCESS;
|
||||
}
|
||||
|
||||
static void write_enable(void)
|
||||
{
|
||||
uint32_t tx = 0;
|
||||
struct send
|
||||
{
|
||||
uint8_t cmd;
|
||||
} *p_tx = (void *)&tx;
|
||||
p_tx->cmd = CMD_WREN;
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), NULL, 0);
|
||||
}
|
||||
|
||||
static void write_disable(void)
|
||||
{
|
||||
uint32_t tx = 0;
|
||||
struct send
|
||||
{
|
||||
uint8_t cmd;
|
||||
} *p_tx = (void *)&tx;
|
||||
p_tx->cmd = CMD_WRDI;
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), NULL, 0);
|
||||
}
|
||||
|
||||
static uint32_t read_status(void)
|
||||
{
|
||||
uint32_t tx = 0, rx = 0;
|
||||
|
||||
struct send
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t dummy;
|
||||
} *p_tx = (void *)&tx;
|
||||
|
||||
struct recv
|
||||
{
|
||||
uint8_t dummy;
|
||||
uint8_t status;
|
||||
} *p_rx = (void *)℞
|
||||
|
||||
p_tx->cmd = CMD_RDSR;
|
||||
p_tx->dummy = 0xFF;
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), (void *)p_rx, offsetof(struct recv, status) + sizeof(p_rx->status));
|
||||
return p_rx->status;
|
||||
}
|
||||
|
||||
static void write_status(uint8_t stauts)
|
||||
{
|
||||
uint32_t tx = 0;
|
||||
struct send
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t stauts;
|
||||
} *p_tx = (void *)&tx;
|
||||
p_tx->cmd = CMD_RDSR;
|
||||
p_tx->stauts = stauts;
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), NULL, 0);
|
||||
}
|
||||
|
||||
static int page_prog(uint8_t *p_src, uint32_t addr, uint32_t page_cnt)
|
||||
{
|
||||
for (uint32_t i = 0; i < page_cnt; i++)
|
||||
{
|
||||
write_enable();
|
||||
|
||||
struct send
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t val;
|
||||
struct
|
||||
{
|
||||
uint32_t addr : 24;
|
||||
uint32_t cmd : 8;
|
||||
};
|
||||
};
|
||||
|
||||
uint8_t data[256];
|
||||
} *p_tx = (void *)xfer_buf;
|
||||
|
||||
p_tx->cmd = CMD_PP;
|
||||
p_tx->addr = addr + PROG_PAGE_SIZE * i;
|
||||
p_tx->val = __REV(p_tx->val);
|
||||
memcpy(p_tx->data, (void *)(&p_src[PROG_PAGE_SIZE * i]), PROG_PAGE_SIZE);
|
||||
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), NULL, 0);
|
||||
|
||||
do {
|
||||
} while ((read_status() & WIP_BIT));
|
||||
}
|
||||
return BLOCK_DEV_SUCCESS;
|
||||
}
|
||||
|
||||
int sect_erase(uint32_t addr, uint32_t sect_cnt)
|
||||
{
|
||||
for (uint32_t i = 0; i < sect_cnt; i++)
|
||||
{
|
||||
write_enable();
|
||||
|
||||
struct send
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t val;
|
||||
struct
|
||||
{
|
||||
uint32_t addr : 24;
|
||||
uint32_t cmd : 8;
|
||||
};
|
||||
};
|
||||
} *p_tx = (void *)xfer_buf;
|
||||
|
||||
p_tx->cmd = CMD_SE;
|
||||
p_tx->addr = addr + i * ERASE_SECT_SIZE;
|
||||
p_tx->val = __REV(p_tx->val);
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), NULL, 0);
|
||||
|
||||
do {
|
||||
} while ((read_status() & WIP_BIT));
|
||||
}
|
||||
return BLOCK_DEV_SUCCESS;
|
||||
}
|
||||
|
||||
int block_erase(uint32_t addr, uint32_t block_cnt)
|
||||
{
|
||||
|
||||
for (uint32_t i = 0; i < block_cnt; i++)
|
||||
{
|
||||
write_enable();
|
||||
|
||||
struct send
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t val;
|
||||
struct
|
||||
{
|
||||
uint32_t addr : 24;
|
||||
uint32_t cmd : 8;
|
||||
};
|
||||
};
|
||||
} *p_tx = (void *)xfer_buf;
|
||||
|
||||
p_tx->cmd = CMD_BE;
|
||||
p_tx->addr = addr + i * ERASE_BLOCK_SIZE;
|
||||
p_tx->val = __REV(p_tx->val);
|
||||
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), NULL, 0);
|
||||
|
||||
do {
|
||||
} while ((read_status() & WIP_BIT));
|
||||
}
|
||||
return BLOCK_DEV_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t dev_id(void)
|
||||
{
|
||||
uint32_t tx = 0, rx = 0;
|
||||
|
||||
struct send
|
||||
{
|
||||
uint32_t cmd : 8;
|
||||
uint32_t dummy : 24;
|
||||
} *p_tx = (void *)&tx;
|
||||
p_tx->cmd = CMD_RDID;
|
||||
p_tx->dummy = 0x000000;
|
||||
|
||||
struct recv
|
||||
{
|
||||
uint32_t dummy : 8;
|
||||
uint32_t manufacturer : 8;
|
||||
uint32_t memory_type : 8;
|
||||
uint32_t capacity : 8;
|
||||
} *p_rx = (void *)℞
|
||||
|
||||
spim_xfer(CS_MEM_PIN, NRF_SPIM_MODE_0, (void *)p_tx, sizeof(*p_tx), (void *)p_rx, sizeof(*p_rx));
|
||||
|
||||
return __REV(rx) & 0x00FFFFFF;
|
||||
}
|
||||
|
||||
static int init(void)
|
||||
{
|
||||
uint32_t id = dev_id();
|
||||
|
||||
if (EXPECT_ID == id)
|
||||
{
|
||||
return BLOCK_DEV_SUCCESS;
|
||||
}
|
||||
|
||||
return BLOCK_DEV_ERROR;
|
||||
}
|
||||
|
||||
static int reset(void)
|
||||
{
|
||||
// Do nothing
|
||||
return 0;
|
||||
}
|
||||
|
||||
const block_dev_drv_if_t gd25d110c = {
|
||||
.init = init,
|
||||
.reset = reset,
|
||||
.read_data = read_data,
|
||||
.page_prog = page_prog,
|
||||
.sect_erase = sect_erase,
|
||||
.block_erase = block_erase,
|
||||
.block_size = ERASE_BLOCK_SIZE,
|
||||
.sect_size = ERASE_SECT_SIZE,
|
||||
.sect_count = BLOCK_PER_DEV * SECT_PER_BLOCK,
|
||||
.page_size = PROG_PAGE_SIZE,
|
||||
.page_per_sect = (ERASE_SECT_SIZE / PROG_PAGE_SIZE)
|
||||
};
|
||||
|
||||
#endif /* ! DEF_GD25D10C_ENABLED */
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#ifndef __GD25D10C_H__
|
||||
#define __GD25D10C_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "block_dev_drv_if.h"
|
||||
|
||||
#if (DEF_GD25D10C_ENABLED)
|
||||
|
||||
extern const block_dev_drv_if_t gd25d110c;
|
||||
|
||||
#endif /* ! DEF_GD25D10C_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __GD25D10C_H__ */
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "app_config.h"
|
||||
|
||||
#include <SEGGER_RTT.h>
|
||||
|
||||
#if (DEF_RTT_JSCOP_ENABLED)
|
||||
|
||||
static char JS_RTT_UpBuffer[4096]; // J-Scope RTT Buffer
|
||||
static int JS_RTT_Channel = 1; // J-Scope RTT Channel
|
||||
|
||||
void j_scop_init(void)
|
||||
{
|
||||
//
|
||||
// Configure J-Scope RTT buffer for one unsigned int and one signed int
|
||||
//
|
||||
SEGGER_RTT_ConfigUpBuffer(JS_RTT_Channel, "JScope_f4", &JS_RTT_UpBuffer[0], sizeof(JS_RTT_UpBuffer), SEGGER_RTT_MODE_NO_BLOCK_SKIP);
|
||||
}
|
||||
|
||||
void j_scope_update(float f)
|
||||
{
|
||||
SEGGER_RTT_Write(JS_RTT_Channel, &f, sizeof(f));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,13 @@ extern "C"
|
||||
|
||||
BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */
|
||||
|
||||
#define BLE_ADV_UUID \
|
||||
{ \
|
||||
{ \
|
||||
ELITE_UUID, BLE_UUID_TYPE_BLE \
|
||||
} \
|
||||
}
|
||||
|
||||
static void le_adv_evt_handler(ble_adv_evt_t const adv_evt)
|
||||
{
|
||||
switch (adv_evt)
|
||||
@@ -59,33 +66,39 @@ void le_adv_init(uint8_t ble_conn_cfg_tag)
|
||||
{
|
||||
uint32_t err_code;
|
||||
ble_advertising_init_t init;
|
||||
|
||||
memset(&init, 0, sizeof(init));
|
||||
|
||||
struct
|
||||
{
|
||||
const uint8_t company_code[5];
|
||||
const uint8_t hw_ver[4];
|
||||
uint8_t company_code[2];
|
||||
uint8_t hw_ver[4];
|
||||
uint8_t build_time[2];
|
||||
uint8_t bat_str[3];
|
||||
uint16_t bat_volt;
|
||||
} __PACKED data = {
|
||||
.company_code = ELITE_COMPANY_CODE,
|
||||
.hw_ver = ELITE_HW_VER,
|
||||
.bat_volt = 100,
|
||||
.hw_ver = ELITE_HW_VER,
|
||||
.build_time = {24, 01},
|
||||
.bat_str = "BAT",
|
||||
.bat_volt = 0x0C1C,
|
||||
};
|
||||
|
||||
ble_advdata_manuf_data_t manuf_specific_data;
|
||||
manuf_specific_data.data.p_data = (uint8_t *)&data;
|
||||
manuf_specific_data.data.size = sizeof(data);
|
||||
manuf_specific_data.company_identifier = 0xFFFF;
|
||||
init.advdata.p_manuf_specific_data = &manuf_specific_data;
|
||||
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
|
||||
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
|
||||
manuf_specific_data.data.p_data = (uint8_t *)&data;
|
||||
manuf_specific_data.data.size = sizeof(data);
|
||||
memcpy(&manuf_specific_data.company_identifier, &ELITE_COMPANY_CODE[0], 2);
|
||||
memcpy(&data.company_code[0], &ELITE_COMPANY_CODE[2], 2);
|
||||
|
||||
ble_uuid_t m_adv_uuids[] = BLE_ADV_UUID;
|
||||
init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
|
||||
init.advdata.uuids_complete.p_uuids = m_adv_uuids;
|
||||
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
|
||||
init.srdata.p_manuf_specific_data = &manuf_specific_data;
|
||||
init.srdata.name_type = BLE_ADVDATA_FULL_NAME;
|
||||
|
||||
init.config.ble_adv_fast_enabled = true;
|
||||
init.config.ble_adv_fast_interval = MSEC_TO_UNITS(25, UNIT_0_625_MS);
|
||||
init.config.ble_adv_fast_timeout = MSEC_TO_UNITS(3000, UNIT_10_MS);
|
||||
init.config.ble_adv_slow_enabled = true;
|
||||
init.config.ble_adv_slow_interval = MSEC_TO_UNITS(250, UNIT_0_625_MS);
|
||||
init.config.ble_adv_slow_timeout = MSEC_TO_UNITS(0, UNIT_10_MS);
|
||||
init.config.ble_adv_fast_interval = MSEC_TO_UNITS(75, UNIT_0_625_MS);
|
||||
init.config.ble_adv_fast_timeout = MSEC_TO_UNITS(0, UNIT_10_MS);
|
||||
|
||||
init.evt_handler = le_adv_evt_handler;
|
||||
init.error_handler = le_adv_error_handler;
|
||||
|
||||
@@ -23,55 +23,58 @@ extern "C"
|
||||
|
||||
#include "ble_conn_state.h"
|
||||
|
||||
#include "ble_dis.h"
|
||||
#include "ble_dfu.h"
|
||||
#include "ble_dis.h"
|
||||
#include "nrf_ble_gatt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static void le_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event) {
|
||||
switch (event) {
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
|
||||
NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
|
||||
// Disconnect all other bonded devices that currently are connected.
|
||||
// This is required to receive a service changed indication
|
||||
// on bootup after a successful (or aborted) Device Firmware Update.
|
||||
extern void le_gap_disconnect(uint16_t conn_handle, void * p_context);
|
||||
uint32_t conn_count = ble_conn_state_for_each_connected(le_gap_disconnect, NULL);
|
||||
NRF_LOG_INFO("Disconnected %d links.", conn_count);
|
||||
break;
|
||||
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER:
|
||||
// YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
|
||||
// by delaying reset by reporting false in app_shutdown_handler
|
||||
NRF_LOG_INFO("Device will enter bootloader mode.");
|
||||
break;
|
||||
static void le_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
|
||||
NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
|
||||
// Disconnect all other bonded devices that currently are connected.
|
||||
// This is required to receive a service changed indication
|
||||
// on bootup after a successful (or aborted) Device Firmware Update.
|
||||
extern void le_gap_disconnect(uint16_t conn_handle, void *p_context);
|
||||
uint32_t conn_count = ble_conn_state_for_each_connected(le_gap_disconnect, NULL);
|
||||
NRF_LOG_INFO("Disconnected %d links.", conn_count);
|
||||
break;
|
||||
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
|
||||
NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
|
||||
// YOUR_JOB: Take corrective measures to resolve the issue
|
||||
// like calling APP_ERROR_CHECK to reset the device.
|
||||
break;
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER:
|
||||
// YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
|
||||
// by delaying reset by reporting false in app_shutdown_handler
|
||||
NRF_LOG_INFO("Device will enter bootloader mode.");
|
||||
break;
|
||||
|
||||
case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
|
||||
NRF_LOG_ERROR("Request to send a response to client failed.");
|
||||
// YOUR_JOB: Take corrective measures to resolve the issue
|
||||
// like calling APP_ERROR_CHECK to reset the device.
|
||||
APP_ERROR_CHECK(false);
|
||||
break;
|
||||
case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
|
||||
NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
|
||||
// YOUR_JOB: Take corrective measures to resolve the issue
|
||||
// like calling APP_ERROR_CHECK to reset the device.
|
||||
break;
|
||||
|
||||
default:
|
||||
NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
|
||||
break;
|
||||
case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
|
||||
NRF_LOG_ERROR("Request to send a response to client failed.");
|
||||
// YOUR_JOB: Take corrective measures to resolve the issue
|
||||
// like calling APP_ERROR_CHECK to reset the device.
|
||||
APP_ERROR_CHECK(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void le_dfu_init(void) {
|
||||
// ble dfu service
|
||||
void le_dfu_init(void)
|
||||
{
|
||||
// ble dfu service
|
||||
ble_dfu_buttonless_init_t dfus_init = { 0 };
|
||||
dfus_init.evt_handler = le_dfu_evt_handler;
|
||||
ret_code_t err_code = ble_dfu_buttonless_init(&dfus_init);
|
||||
dfus_init.evt_handler = le_dfu_evt_handler;
|
||||
ret_code_t err_code = ble_dfu_buttonless_init(&dfus_init);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
-290
@@ -1,290 +0,0 @@
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(BLE_EIS)
|
||||
|
||||
#include "app_error.h"
|
||||
#include "ble_conn_state.h"
|
||||
#include "ble_gatts.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "nrf_log_default_backends.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**< Used vendor specific UUID. */
|
||||
#define BLE_EIS_BASE_UUID \
|
||||
{ \
|
||||
{ \
|
||||
0x4D, 0x3C, 0x56, 0x45, 0x12, 0x8B, 0x44, 0x1D, 0x8D, 0x6F, 0xC5, 0x95, 0x00, 0x00, 0x9B, 0xD8 \
|
||||
} \
|
||||
}
|
||||
#define BLE_UUID_EIS_SERVICE 0x0001
|
||||
#define BLE_UUID_EIS_REGULAR_DATA_CHAR 0x0002
|
||||
#define BLE_UUID_EIS_LOW_FREQ_DATA_CHAR 0x0003
|
||||
#define BLE_UUID_EIS_AUXILIARY_DATA_CHAR 0x0004
|
||||
#define BLE_UUID_EIS_STATUS_CHAR 0x0005
|
||||
#define BLE_UUID_EIS_EVENT_CHAR 0x0006
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_handle;
|
||||
uint16_t service_handle;
|
||||
|
||||
ble_gatts_char_handles_t regular_data_handles;
|
||||
ble_gatts_char_handles_t low_freq_data_handles;
|
||||
ble_gatts_char_handles_t auxiliary_data_handles;
|
||||
ble_gatts_char_handles_t status_handles;
|
||||
ble_gatts_char_handles_t event_handles;
|
||||
bool regular_data_notify_enable;
|
||||
bool low_freq_data_notify_enable;
|
||||
bool auxiliary_data_notify_enable;
|
||||
bool status_notify_enable;
|
||||
bool event_notify_enable;
|
||||
} ble_eis_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t dummy;
|
||||
} ble_eis_init_t;
|
||||
|
||||
static ble_eis_t ble_eis = {
|
||||
.conn_handle = BLE_CONN_HANDLE_INVALID,
|
||||
.regular_data_notify_enable = false,
|
||||
.low_freq_data_notify_enable = false,
|
||||
.auxiliary_data_notify_enable = false,
|
||||
.status_notify_enable = false,
|
||||
.event_notify_enable = false,
|
||||
};
|
||||
|
||||
static void on_connect(ble_eis_t *p_eis, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
p_eis->conn_handle = p_ble_evt->evt.common_evt.conn_handle;
|
||||
}
|
||||
|
||||
static void on_disconnect(ble_eis_t *p_eis, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
p_eis->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
p_eis->regular_data_notify_enable = false;
|
||||
p_eis->low_freq_data_notify_enable = false;
|
||||
p_eis->auxiliary_data_notify_enable = false;
|
||||
p_eis->status_notify_enable = false;
|
||||
p_eis->event_notify_enable = false;
|
||||
}
|
||||
|
||||
static void eis_ccc_update(ble_eis_t *p_eis, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
ble_gatts_evt_write_t const *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
||||
if (p_evt_write->handle == p_eis->regular_data_handles.cccd_handle)
|
||||
{
|
||||
p_eis->regular_data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("regular_data_notify:%s", p_eis->regular_data_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
else if (p_evt_write->handle == p_eis->low_freq_data_handles.cccd_handle)
|
||||
{
|
||||
p_eis->low_freq_data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("low_freq_data_notify:%s", p_eis->low_freq_data_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
else if (p_evt_write->handle == p_eis->auxiliary_data_handles.cccd_handle)
|
||||
{
|
||||
p_eis->auxiliary_data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("auxiliary_data_notify:%s", p_eis->auxiliary_data_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
else if (p_evt_write->handle == p_eis->status_handles.cccd_handle)
|
||||
{
|
||||
p_eis->status_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("status_notify:%s", p_eis->status_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
else if (p_evt_write->handle == p_eis->event_handles.cccd_handle)
|
||||
{
|
||||
p_eis->event_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("event_notify:%s", p_eis->event_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void on_write(ble_eis_t *p_eis, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
ble_uuid_t uuid = p_ble_evt->evt.gatts_evt.params.write.uuid;
|
||||
switch (uuid.uuid)
|
||||
{
|
||||
case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
|
||||
eis_ccc_update(p_eis, p_ble_evt);
|
||||
break;
|
||||
case BLE_UUID_CHARACTERISTIC:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void on_hvx_tx_complete(ble_eis_t *p_eis, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
}
|
||||
|
||||
static void ble_eis_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
{
|
||||
ble_eis_t *p_eis = (ble_eis_t *)p_context;
|
||||
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
on_connect(p_eis, p_ble_evt);
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
on_disconnect(p_eis, p_ble_evt);
|
||||
break;
|
||||
case BLE_GATTS_EVT_WRITE:
|
||||
on_write(p_eis, p_ble_evt);
|
||||
break;
|
||||
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
|
||||
on_hvx_tx_complete(p_eis, p_ble_evt);
|
||||
break;
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_code_t add_characteristic(uint16_t uuid, uint8_t uuid_type, uint32_t val_len, void *p_val, ble_gatts_char_handles_t *p_handles)
|
||||
{
|
||||
|
||||
ble_add_char_params_t add_char_params;
|
||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||
add_char_params.uuid = uuid;
|
||||
add_char_params.uuid_type = uuid_type;
|
||||
add_char_params.max_len = val_len;
|
||||
add_char_params.init_len = 0;
|
||||
add_char_params.p_init_value = p_val;
|
||||
add_char_params.is_value_user = false;
|
||||
add_char_params.is_var_len = true;
|
||||
add_char_params.char_props.read = 1;
|
||||
add_char_params.char_props.notify = 1;
|
||||
add_char_params.read_access = SEC_OPEN;
|
||||
add_char_params.cccd_write_access = SEC_OPEN;
|
||||
ret_code_t err_code = characteristic_add(ble_eis.service_handle, &add_char_params, p_handles);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t ble_eis_init(ble_eis_init_t const *p_eis_init)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
ble_uuid128_t base_uuid = BLE_EIS_BASE_UUID;
|
||||
ble_uuid_t ble_uuid = {
|
||||
.type = BLE_UUID_TYPE_UNKNOWN,
|
||||
.uuid = BLE_UUID_EIS_SERVICE,
|
||||
};
|
||||
|
||||
// Adding vendor specific UUID to the SoftDevice
|
||||
err_code = sd_ble_uuid_vs_add(&base_uuid, &ble_uuid.type);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding proprietary service to the SoftDevice
|
||||
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &ble_eis.service_handle);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding regular data characteristic to the SoftDevice
|
||||
err_code = add_characteristic(BLE_UUID_EIS_REGULAR_DATA_CHAR,
|
||||
ble_uuid.type,
|
||||
NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3,
|
||||
NULL,
|
||||
&ble_eis.regular_data_handles);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding low freq data characteristic to the SoftDevice
|
||||
err_code = add_characteristic(BLE_UUID_EIS_LOW_FREQ_DATA_CHAR,
|
||||
ble_uuid.type,
|
||||
32,
|
||||
NULL,
|
||||
&ble_eis.low_freq_data_handles);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding auxiliary data characteristic to the SoftDevice
|
||||
err_code = add_characteristic(BLE_UUID_EIS_AUXILIARY_DATA_CHAR,
|
||||
ble_uuid.type,
|
||||
32,
|
||||
NULL,
|
||||
&ble_eis.auxiliary_data_handles);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding status characteristic to the SoftDevice
|
||||
err_code = add_characteristic(BLE_UUID_EIS_STATUS_CHAR,
|
||||
ble_uuid.type,
|
||||
32,
|
||||
NULL,
|
||||
&ble_eis.status_handles);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding event characteristic to the SoftDevice
|
||||
err_code = add_characteristic(BLE_UUID_EIS_EVENT_CHAR,
|
||||
ble_uuid.type,
|
||||
32,
|
||||
NULL,
|
||||
&ble_eis.event_handles);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Register a handler for BLE events.
|
||||
NRF_SDH_BLE_OBSERVER(m_eis_observer, EIS_BLE_OBSERVER_PRIO, ble_eis_evt_handler, &ble_eis);
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
void le_eis_init(void)
|
||||
{
|
||||
ble_eis_init_t eis_init;
|
||||
memset(&eis_init, 0x00, sizeof(eis_init));
|
||||
|
||||
ret_code_t err_code = ble_eis_init(&eis_init);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
extern void eis_regular_data_init(void);
|
||||
eis_regular_data_init();
|
||||
}
|
||||
|
||||
ret_code_t le_regular_data_notify(uint8_t *p_value, uint16_t len)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
|
||||
// update database.
|
||||
ble_gatts_value_t gatts_value = {
|
||||
.offset = 0,
|
||||
.len = len,
|
||||
.p_value = p_value,
|
||||
};
|
||||
err_code = sd_ble_gatts_value_set(BLE_CONN_HANDLE_INVALID, ble_eis.regular_data_handles.value_handle, &gatts_value);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
// send notify
|
||||
if (ble_eis.regular_data_notify_enable)
|
||||
{
|
||||
ble_gatts_hvx_params_t hvx_params = {
|
||||
.handle = ble_eis.regular_data_handles.value_handle,
|
||||
.type = BLE_GATT_HVX_NOTIFICATION,
|
||||
.offset = gatts_value.offset,
|
||||
.p_len = &gatts_value.len,
|
||||
.p_data = gatts_value.p_value,
|
||||
};
|
||||
if (ble_conn_state_status(ble_eis.conn_handle) == BLE_CONN_STATUS_CONNECTED)
|
||||
{
|
||||
err_code = sd_ble_gatts_hvx(ble_eis.conn_handle, &hvx_params);
|
||||
}
|
||||
}
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
bool le_regular_data_notify_is_enable(void)
|
||||
{
|
||||
return ble_eis.regular_data_notify_enable;
|
||||
}
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(BLE_EIS)
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
#include "sdk_common.h"
|
||||
|
||||
#include "app_error.h"
|
||||
#include "ble_conn_state.h"
|
||||
#include "ble_gatts.h"
|
||||
#include "ble_srv_common.h"
|
||||
#include "elite.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "nrf_log_default_backends.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if NRF_MODULE_ENABLED(BLE_ELITE_SRV)
|
||||
|
||||
#define BLE_UUID_ELITE_SERVICE 0xFFF0
|
||||
#define BLE_UUID_ELITE_DATA_CHAR 0xFFF1
|
||||
#define BLE_UUID_ELITE_INST_CHAR 0xFFF2
|
||||
#define BLE_UUID_ELITE_EVENT_CHAR 0xFFF3
|
||||
#define BLE_UUID_ELITE_BEGIN_CHAR BLE_UUID_ELITE_DATA_CHAR
|
||||
#define BLE_UUID_ELITE_END_CHAR (BLE_UUID_ELITE_EVENT_CHAR + 1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t conn_handle;
|
||||
uint16_t service_handle;
|
||||
ble_gatts_char_handles_t data_char_handle;
|
||||
ble_gatts_char_handles_t inst_char_handle;
|
||||
ble_gatts_char_handles_t event_char_handle;
|
||||
bool data_notify_enable;
|
||||
bool inst_notify_enable;
|
||||
bool event_notify_enable;
|
||||
} elite_context_t;
|
||||
|
||||
static elite_context_t elite_context = {
|
||||
.conn_handle = BLE_CONN_HANDLE_INVALID,
|
||||
.data_notify_enable = false,
|
||||
.inst_notify_enable = false,
|
||||
.event_notify_enable = false,
|
||||
};
|
||||
|
||||
static void on_connect(elite_context_t *p_context, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
p_context->conn_handle = p_ble_evt->evt.common_evt.conn_handle;
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
static void on_disconnect(elite_context_t *p_context, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
p_context->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
p_context->data_notify_enable = false;
|
||||
p_context->inst_notify_enable = false;
|
||||
p_context->event_notify_enable = false;
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
static void elite_srv_ccc_update(elite_context_t *p_context, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
ble_gatts_evt_write_t const *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
||||
if (p_evt_write->handle == p_context->data_char_handle.cccd_handle)
|
||||
{
|
||||
p_context->data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("data_notify:%s", p_context->data_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_evt_write->handle == p_context->inst_char_handle.cccd_handle)
|
||||
{
|
||||
p_context->inst_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("inst_notify_notify:%s", p_context->inst_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_evt_write->handle == p_context->event_char_handle.cccd_handle)
|
||||
{
|
||||
p_context->event_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
|
||||
NRF_LOG_INFO("event_notify:%s", p_context->event_notify_enable ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void on_write(elite_context_t *p_context, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
ble_uuid_t uuid = p_ble_evt->evt.gatts_evt.params.write.uuid;
|
||||
uint16_t handle = p_ble_evt->evt.gatts_evt.params.write.handle;
|
||||
ble_gatts_evt_write_t const *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
||||
switch (uuid.uuid)
|
||||
{
|
||||
case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
|
||||
elite_srv_ccc_update(p_context, p_ble_evt);
|
||||
break;
|
||||
|
||||
case BLE_UUID_ELITE_INST_CHAR:
|
||||
NRF_LOG_HEXDUMP_INFO(p_evt_write->data, p_evt_write->len);
|
||||
elite_instr_send((void *)p_evt_write->data, p_evt_write->len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void on_hvx_tx_complete(elite_context_t *p_context, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
}
|
||||
|
||||
static void on_ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
{
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
on_connect(p_context, p_ble_evt);
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
on_disconnect(p_context, p_ble_evt);
|
||||
break;
|
||||
case BLE_GATTS_EVT_WRITE:
|
||||
on_write(p_context, p_ble_evt);
|
||||
break;
|
||||
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
|
||||
on_hvx_tx_complete(p_context, p_ble_evt);
|
||||
break;
|
||||
default:
|
||||
// No implementation needed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_code_t add_characteristic(uint16_t uuid, uint8_t uuid_type, uint32_t val_max_len, void *p_init_val, uint32_t init_len, ble_gatts_char_handles_t *p_handles, bool enable_cccd)
|
||||
{
|
||||
ble_add_char_params_t add_char_params;
|
||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||
add_char_params.uuid = uuid;
|
||||
add_char_params.uuid_type = uuid_type;
|
||||
add_char_params.max_len = val_max_len;
|
||||
add_char_params.init_len = init_len;
|
||||
add_char_params.p_init_value = p_init_val;
|
||||
add_char_params.is_value_user = false;
|
||||
add_char_params.is_var_len = true;
|
||||
add_char_params.write_access = SEC_OPEN;
|
||||
add_char_params.char_props.write = 1;
|
||||
add_char_params.read_access = SEC_OPEN;
|
||||
add_char_params.char_props.read = 1;
|
||||
add_char_params.cccd_write_access = SEC_OPEN;
|
||||
add_char_params.char_props.notify = enable_cccd;
|
||||
ret_code_t err_code = characteristic_add(elite_context.service_handle, &add_char_params, p_handles);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t add_characteristic_ro(uint16_t uuid, uint8_t uuid_type, uint32_t val_max_len, void *p_init_val, uint32_t init_len, ble_gatts_char_handles_t *p_handles, bool enable_cccd)
|
||||
{
|
||||
ble_add_char_params_t add_char_params;
|
||||
memset(&add_char_params, 0, sizeof(add_char_params));
|
||||
add_char_params.uuid = uuid;
|
||||
add_char_params.uuid_type = uuid_type;
|
||||
add_char_params.max_len = val_max_len;
|
||||
add_char_params.init_len = init_len;
|
||||
add_char_params.p_init_value = p_init_val;
|
||||
add_char_params.is_value_user = true;
|
||||
add_char_params.is_var_len = true;
|
||||
add_char_params.read_access = SEC_OPEN;
|
||||
add_char_params.char_props.read = 1;
|
||||
add_char_params.cccd_write_access = SEC_OPEN;
|
||||
add_char_params.char_props.notify = enable_cccd;
|
||||
ret_code_t err_code = characteristic_add(elite_context.service_handle, &add_char_params, p_handles);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static uint32_t elite_srv_init(void)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
ble_uuid_t ble_uuid = {
|
||||
.type = BLE_UUID_TYPE_BLE,
|
||||
.uuid = BLE_UUID_ELITE_SERVICE,
|
||||
};
|
||||
|
||||
// Adding proprietary service to the SoftDevice
|
||||
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &elite_context.service_handle);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
uint8_t init_val[NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3];
|
||||
memset(init_val, 0x00, sizeof(init_val));
|
||||
|
||||
// Adding data characteristic to the SoftDevice
|
||||
err_code = add_characteristic_ro(BLE_UUID_ELITE_DATA_CHAR, ble_uuid.type, sizeof(init_val), init_val, sizeof(init_val), &elite_context.data_char_handle, true);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding instruction characteristic to the SoftDevice
|
||||
err_code = add_characteristic(BLE_UUID_ELITE_INST_CHAR, ble_uuid.type, sizeof(init_val), init_val, sizeof(init_val), &elite_context.inst_char_handle, true);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Adding event characteristic to the SoftDevice
|
||||
err_code = add_characteristic_ro(BLE_UUID_ELITE_EVENT_CHAR, ble_uuid.type, sizeof(init_val), init_val, sizeof(init_val), &elite_context.event_char_handle, true);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
// Register a handler for BLE events.
|
||||
NRF_SDH_BLE_OBSERVER(m_ble_elite_observer, BLE_ELITE_OBSERVER_PRIO, on_ble_evt_handler, &elite_context);
|
||||
|
||||
NRF_LOG_INFO("+---------------------+------+");
|
||||
NRF_LOG_INFO("| data_char_handle | 0x%02x |", elite_context.data_char_handle.value_handle);
|
||||
NRF_LOG_INFO("| inst_char_handle | 0x%02x |", elite_context.inst_char_handle.value_handle);
|
||||
NRF_LOG_INFO("| event_char_handle | 0x%02x |", elite_context.event_char_handle.value_handle);
|
||||
NRF_LOG_INFO("+---------------------+------+");
|
||||
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
void le_elite_srv_init(void)
|
||||
{
|
||||
ret_code_t err_code = elite_srv_init();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
elite_init();
|
||||
}
|
||||
|
||||
ret_code_t le_data_notify(uint8_t *p_value, uint16_t len)
|
||||
{
|
||||
ble_gatts_hvx_params_t hvx_params = {
|
||||
.handle = elite_context.data_char_handle.value_handle,
|
||||
.type = BLE_GATT_HVX_NOTIFICATION,
|
||||
.offset = 0,
|
||||
.p_len = &len,
|
||||
.p_data = p_value,
|
||||
};
|
||||
return sd_ble_gatts_hvx(elite_context.conn_handle, &hvx_params);
|
||||
}
|
||||
|
||||
ret_code_t le_data_upadate(uint8_t *p_value, uint16_t len)
|
||||
{
|
||||
static uint8_t values[1 + NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3];
|
||||
|
||||
values[0] = len < 20 ? 20 : len;
|
||||
|
||||
memcpy(&values[1], p_value, len);
|
||||
|
||||
// update database.
|
||||
ble_gatts_value_t gatts_value = {
|
||||
.offset = 0,
|
||||
.len = values[0] + 1,
|
||||
.p_value = values,
|
||||
};
|
||||
|
||||
uint32_t err_code = sd_ble_gatts_value_set(BLE_CONN_HANDLE_INVALID, elite_context.data_char_handle.value_handle, &gatts_value);
|
||||
|
||||
memset(&values[1], 0x00, len);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t le_event_notify(uint8_t *p_value, uint16_t len)
|
||||
{
|
||||
ble_gatts_hvx_params_t hvx_params = {
|
||||
.handle = elite_context.event_char_handle.value_handle,
|
||||
.type = BLE_GATT_HVX_NOTIFICATION,
|
||||
.offset = 0,
|
||||
.p_len = &len,
|
||||
.p_data = p_value,
|
||||
};
|
||||
return sd_ble_gatts_hvx(elite_context.conn_handle, &hvx_params);
|
||||
}
|
||||
|
||||
ret_code_t le_event_upadate(uint8_t *p_value, uint16_t len)
|
||||
{
|
||||
// update database.
|
||||
ble_gatts_value_t gatts_value = {
|
||||
.offset = 0,
|
||||
.len = len,
|
||||
.p_value = p_value,
|
||||
};
|
||||
return sd_ble_gatts_value_set(BLE_CONN_HANDLE_INVALID, elite_context.event_char_handle.value_handle, &gatts_value);
|
||||
}
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(BLE_ELITE)
|
||||
@@ -51,7 +51,7 @@ void le_gap_init(const char *device_name, uint16_t usAppearance)
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
void le_gap_disconnect(uint16_t conn_handle, void * p_context)
|
||||
void le_gap_disconnect(uint16_t conn_handle, void *p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_context);
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ extern "C"
|
||||
|
||||
#include "ble_conn_state.h"
|
||||
|
||||
#include "ble_dis.h"
|
||||
#include "ble_dfu.h"
|
||||
#include "ble_dis.h"
|
||||
#include "nrf_ble_gatt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -40,13 +40,17 @@ extern "C"
|
||||
static void le_dis_init(void)
|
||||
{
|
||||
ble_dis_init_t dis_init;
|
||||
ble_dis_sys_id_t sys_id;
|
||||
|
||||
memset(&dis_init, 0, sizeof(dis_init));
|
||||
memset(&sys_id, 0, sizeof(sys_id));
|
||||
|
||||
ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME);
|
||||
ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, FW_REV);
|
||||
ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, HW_REV);
|
||||
ble_srv_ascii_to_utf8(&dis_init.model_num_str, MODULE_NAME);
|
||||
ble_srv_ascii_to_utf8(&dis_init.serial_num_str, SER_NUM);
|
||||
dis_init.p_sys_id = &sys_id;
|
||||
dis_init.dis_char_rd_sec = SEC_OPEN;
|
||||
|
||||
ret_code_t err_code = ble_dis_init(&dis_init);
|
||||
@@ -60,6 +64,6 @@ void le_srv_init(void)
|
||||
extern void le_dfu_init(void);
|
||||
le_dfu_init();
|
||||
|
||||
extern void le_eis_init(void);
|
||||
le_eis_init();
|
||||
extern void le_elite_srv_init(void);
|
||||
le_elite_srv_init(); // customer service
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
#include "led_drv.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_APA102_2020_ENABLED)
|
||||
#include "apa102_2020.h"
|
||||
static const led_drv_if_t *p_inst = &apa102_drv;
|
||||
#else
|
||||
static led_drv_if_t *p_inst = NULL;
|
||||
#endif
|
||||
|
||||
#if (DEF_LED_DRV_ENABLED)
|
||||
|
||||
static bool btWaitLedFlag = 0;
|
||||
static bool noEventLedFlag = 0;
|
||||
static bool preWorkLedFlag = 0;
|
||||
static bool workingLedFlag = 0;
|
||||
static bool postWorkLedFlag = 0;
|
||||
|
||||
int32_t led_mode(uint16_t mode_status)
|
||||
{
|
||||
btWaitLedFlag = 0;
|
||||
noEventLedFlag = 0;
|
||||
preWorkLedFlag = 0;
|
||||
workingLedFlag = 0;
|
||||
postWorkLedFlag = 0;
|
||||
|
||||
switch (mode_status)
|
||||
{
|
||||
case BT_WAIT:
|
||||
btWaitLedFlag = 1;
|
||||
NRF_LOG_INFO("%s(BT_WAIT) is unimplemented.", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case NO_EVENT:
|
||||
noEventLedFlag = 1;
|
||||
NRF_LOG_INFO("%s(NO_EVENT) is unimplemented.", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case PRE_WORK:
|
||||
preWorkLedFlag = 1;
|
||||
NRF_LOG_INFO("%s(PRE_WORK) is unimplemented.", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case WORKING:
|
||||
workingLedFlag = 1;
|
||||
NRF_LOG_INFO("%s(WORKING) is unimplemented.", __FUNCTION__);
|
||||
break;
|
||||
|
||||
case POST_WORK:
|
||||
postWorkLedFlag = 1;
|
||||
NRF_LOG_INFO("%s(POST_WORK) is unimplemented.", __FUNCTION__);
|
||||
break;
|
||||
|
||||
default:
|
||||
NRF_LOG_INFO("%s(default) is unimplemented.", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t led_set(struct led_color color)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return LED_DRV_ERROR;
|
||||
}
|
||||
|
||||
if (p_inst->set != NULL)
|
||||
{
|
||||
for (int i = 0; i < DEF_LED_COUNT; i++)
|
||||
{
|
||||
p_inst->set(i, color, 1);
|
||||
}
|
||||
return LED_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
return LED_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t led_single_led_set(uint32_t idx, struct led_color color, uint8_t brightness)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return LED_DRV_ERROR;
|
||||
}
|
||||
|
||||
if (p_inst->set != NULL)
|
||||
{
|
||||
p_inst->set(idx, color, brightness);
|
||||
return LED_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
return LED_DRV_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t led_init(void)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return LED_DRV_ERROR;
|
||||
}
|
||||
|
||||
return p_inst->init(DEF_LED_COUNT);
|
||||
}
|
||||
|
||||
int32_t led_as_rainbow(void)
|
||||
{
|
||||
uint8_t color_idx;
|
||||
struct led_color color[6] = { LED_RED, LED_ORANGE, LED_YELLOW, LED_GREEN, LED_BLUE, LED_PURPLE };
|
||||
|
||||
for (int i = 0; i < DEF_LED_COUNT; i++)
|
||||
{
|
||||
color_idx = i % COUNT_ARRAY_SIZE(color);
|
||||
led_single_led_set(i, color[color_idx], 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ! DEF_LED_DRV_ENABLED */
|
||||
@@ -0,0 +1,97 @@
|
||||
#ifndef __LED_DRV_H__
|
||||
#define __LED_DRV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "led_drv_if.h"
|
||||
|
||||
#define LED_DRV_ERROR (-1)
|
||||
#define LED_DRV_SUCCESS (0)
|
||||
|
||||
#define LED_NONE \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0x00, .G = 0x00, .B = 0x00 \
|
||||
}
|
||||
#define LED_RED \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0xFF, .G = 0x00, .B = 0x00 \
|
||||
}
|
||||
#define LED_ORANGE \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0xFF, .G = 0x58, .B = 0x09 \
|
||||
}
|
||||
#define LED_YELLOW \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0xEF, .G = 0x9F, .B = 0x00 \
|
||||
}
|
||||
#define LED_GREEN \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0x00, .G = 0xFF, .B = 0x00 \
|
||||
}
|
||||
#define LED_CYAN \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0x00, .G = 0xFF, .B = 0xFF \
|
||||
}
|
||||
#define LED_BLUE \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0x00, .G = 0x00, .B = 0xFF \
|
||||
}
|
||||
#define LED_PURPLE \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0xFF, .G = 0x00, .B = 0xFF \
|
||||
}
|
||||
#define LED_ORANGE \
|
||||
(struct led_color) \
|
||||
{ \
|
||||
.R = 0xFF, .G = 0x58, .B = 0x09 \
|
||||
}
|
||||
|
||||
#define LED_OFF LED_NONE
|
||||
#define LED_ON LED_GREEN
|
||||
#define LED_ERROR LED_RED
|
||||
#define LED_IDEL_DISCONNECT LED_YELLOW
|
||||
#define LED_IDEL_CONNECTED LED_GREEN
|
||||
#define LED_REC LED_CYAN
|
||||
#define LED_IDENTICY_DEV LED_PURPLE
|
||||
#define LED_BUTTON_PRESS LED_YELLOW
|
||||
|
||||
#define BT_WAIT 0x01
|
||||
#define NO_EVENT 0x02
|
||||
#define PRE_WORK 0x03
|
||||
#define WORKING 0x04
|
||||
#define POST_WORK 0x05
|
||||
|
||||
#if (DEF_LED_DRV_ENABLED)
|
||||
int32_t
|
||||
led_init(void);
|
||||
int32_t led_set(struct led_color color);
|
||||
int32_t led_single_led_set(uint32_t idx, struct led_color color, uint8_t brightness);
|
||||
int32_t led_mode(uint16_t mode_status);
|
||||
int32_t led_as_rainbow(void);
|
||||
|
||||
#else
|
||||
|
||||
#define led_init()
|
||||
#define led_set(x)
|
||||
#define led_single_led_set(x, y, z)
|
||||
#define led_mode(x)
|
||||
#define led_as_rainbow(x)
|
||||
|
||||
#endif /* ! DEF_LED_DRV_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __LED_DRV_H__ */
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef __LED_DRV_IF_H__
|
||||
#define __LED_DRV_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct led_color
|
||||
{
|
||||
uint8_t B;
|
||||
uint8_t G;
|
||||
uint8_t R;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*init)(uint32_t cnt);
|
||||
int32_t (*set)(uint32_t idx, struct led_color color, uint8_t brightness);
|
||||
} led_drv_if_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __LED_DRV_IF_H__ */
|
||||
+6457
File diff suppressed because it is too large
Load Diff
+795
@@ -0,0 +1,795 @@
|
||||
/*
|
||||
* The little filesystem
|
||||
*
|
||||
* Copyright (c) 2022, The littlefs authors.
|
||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef LFS_H
|
||||
#define LFS_H
|
||||
|
||||
#include "lfs_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/// Version info ///
|
||||
|
||||
// Software library version
|
||||
// Major (top-nibble), incremented on backwards incompatible changes
|
||||
// Minor (bottom-nibble), incremented on feature additions
|
||||
#define LFS_VERSION 0x00020009
|
||||
#define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
|
||||
#define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0))
|
||||
|
||||
// Version of On-disk data structures
|
||||
// Major (top-nibble), incremented on backwards incompatible changes
|
||||
// Minor (bottom-nibble), incremented on feature additions
|
||||
#define LFS_DISK_VERSION 0x00020001
|
||||
#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
|
||||
#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
|
||||
|
||||
|
||||
/// Definitions ///
|
||||
|
||||
// Type definitions
|
||||
typedef uint32_t lfs_size_t;
|
||||
typedef uint32_t lfs_off_t;
|
||||
|
||||
typedef int32_t lfs_ssize_t;
|
||||
typedef int32_t lfs_soff_t;
|
||||
|
||||
typedef uint32_t lfs_block_t;
|
||||
|
||||
// Maximum name size in bytes, may be redefined to reduce the size of the
|
||||
// info struct. Limited to <= 1022. Stored in superblock and must be
|
||||
// respected by other littlefs drivers.
|
||||
#ifndef LFS_NAME_MAX
|
||||
#define LFS_NAME_MAX 255
|
||||
#endif
|
||||
|
||||
// Maximum size of a file in bytes, may be redefined to limit to support other
|
||||
// drivers. Limited on disk to <= 2147483647. Stored in superblock and must be
|
||||
// respected by other littlefs drivers.
|
||||
#ifndef LFS_FILE_MAX
|
||||
#define LFS_FILE_MAX 2147483647
|
||||
#endif
|
||||
|
||||
// Maximum size of custom attributes in bytes, may be redefined, but there is
|
||||
// no real benefit to using a smaller LFS_ATTR_MAX. Limited to <= 1022.
|
||||
#ifndef LFS_ATTR_MAX
|
||||
#define LFS_ATTR_MAX 1022
|
||||
#endif
|
||||
|
||||
// Possible error codes, these are negative to allow
|
||||
// valid positive return values
|
||||
enum lfs_error {
|
||||
LFS_ERR_OK = 0, // No error
|
||||
LFS_ERR_IO = -5, // Error during device operation
|
||||
LFS_ERR_CORRUPT = -84, // Corrupted
|
||||
LFS_ERR_NOENT = -2, // No directory entry
|
||||
LFS_ERR_EXIST = -17, // Entry already exists
|
||||
LFS_ERR_NOTDIR = -20, // Entry is not a dir
|
||||
LFS_ERR_ISDIR = -21, // Entry is a dir
|
||||
LFS_ERR_NOTEMPTY = -39, // Dir is not empty
|
||||
LFS_ERR_BADF = -9, // Bad file number
|
||||
LFS_ERR_FBIG = -27, // File too large
|
||||
LFS_ERR_INVAL = -22, // Invalid parameter
|
||||
LFS_ERR_NOSPC = -28, // No space left on device
|
||||
LFS_ERR_NOMEM = -12, // No more memory available
|
||||
LFS_ERR_NOATTR = -61, // No data/attr available
|
||||
LFS_ERR_NAMETOOLONG = -36, // File name too long
|
||||
};
|
||||
|
||||
// File types
|
||||
enum lfs_type {
|
||||
// file types
|
||||
LFS_TYPE_REG = 0x001,
|
||||
LFS_TYPE_DIR = 0x002,
|
||||
|
||||
// internally used types
|
||||
LFS_TYPE_SPLICE = 0x400,
|
||||
LFS_TYPE_NAME = 0x000,
|
||||
LFS_TYPE_STRUCT = 0x200,
|
||||
LFS_TYPE_USERATTR = 0x300,
|
||||
LFS_TYPE_FROM = 0x100,
|
||||
LFS_TYPE_TAIL = 0x600,
|
||||
LFS_TYPE_GLOBALS = 0x700,
|
||||
LFS_TYPE_CRC = 0x500,
|
||||
|
||||
// internally used type specializations
|
||||
LFS_TYPE_CREATE = 0x401,
|
||||
LFS_TYPE_DELETE = 0x4ff,
|
||||
LFS_TYPE_SUPERBLOCK = 0x0ff,
|
||||
LFS_TYPE_DIRSTRUCT = 0x200,
|
||||
LFS_TYPE_CTZSTRUCT = 0x202,
|
||||
LFS_TYPE_INLINESTRUCT = 0x201,
|
||||
LFS_TYPE_SOFTTAIL = 0x600,
|
||||
LFS_TYPE_HARDTAIL = 0x601,
|
||||
LFS_TYPE_MOVESTATE = 0x7ff,
|
||||
LFS_TYPE_CCRC = 0x500,
|
||||
LFS_TYPE_FCRC = 0x5ff,
|
||||
|
||||
// internal chip sources
|
||||
LFS_FROM_NOOP = 0x000,
|
||||
LFS_FROM_MOVE = 0x101,
|
||||
LFS_FROM_USERATTRS = 0x102,
|
||||
};
|
||||
|
||||
// File open flags
|
||||
enum lfs_open_flags {
|
||||
// open flags
|
||||
LFS_O_RDONLY = 1, // Open a file as read only
|
||||
#ifndef LFS_READONLY
|
||||
LFS_O_WRONLY = 2, // Open a file as write only
|
||||
LFS_O_RDWR = 3, // Open a file as read and write
|
||||
LFS_O_CREAT = 0x0100, // Create a file if it does not exist
|
||||
LFS_O_EXCL = 0x0200, // Fail if a file already exists
|
||||
LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
|
||||
LFS_O_APPEND = 0x0800, // Move to end of file on every write
|
||||
#endif
|
||||
|
||||
// internally used flags
|
||||
#ifndef LFS_READONLY
|
||||
LFS_F_DIRTY = 0x010000, // File does not match storage
|
||||
LFS_F_WRITING = 0x020000, // File has been written since last flush
|
||||
#endif
|
||||
LFS_F_READING = 0x040000, // File has been read since last flush
|
||||
#ifndef LFS_READONLY
|
||||
LFS_F_ERRED = 0x080000, // An error occurred during write
|
||||
#endif
|
||||
LFS_F_INLINE = 0x100000, // Currently inlined in directory entry
|
||||
};
|
||||
|
||||
// File seek flags
|
||||
enum lfs_whence_flags {
|
||||
LFS_SEEK_SET = 0, // Seek relative to an absolute position
|
||||
LFS_SEEK_CUR = 1, // Seek relative to the current file position
|
||||
LFS_SEEK_END = 2, // Seek relative to the end of the file
|
||||
};
|
||||
|
||||
|
||||
// Configuration provided during initialization of the littlefs
|
||||
struct lfs_config {
|
||||
// Opaque user provided context that can be used to pass
|
||||
// information to the block device operations
|
||||
void *context;
|
||||
|
||||
// Read a region in a block. Negative error codes are propagated
|
||||
// to the user.
|
||||
int (*read)(const struct lfs_config *c, lfs_block_t block,
|
||||
lfs_off_t off, void *buffer, lfs_size_t size);
|
||||
|
||||
// Program a region in a block. The block must have previously
|
||||
// been erased. Negative error codes are propagated to the user.
|
||||
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||
int (*prog)(const struct lfs_config *c, lfs_block_t block,
|
||||
lfs_off_t off, const void *buffer, lfs_size_t size);
|
||||
|
||||
// Erase a block. A block must be erased before being programmed.
|
||||
// The state of an erased block is undefined. Negative error codes
|
||||
// are propagated to the user.
|
||||
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||
int (*erase)(const struct lfs_config *c, lfs_block_t block);
|
||||
|
||||
// Sync the state of the underlying block device. Negative error codes
|
||||
// are propagated to the user.
|
||||
int (*sync)(const struct lfs_config *c);
|
||||
|
||||
#ifdef LFS_THREADSAFE
|
||||
// Lock the underlying block device. Negative error codes
|
||||
// are propagated to the user.
|
||||
int (*lock)(const struct lfs_config *c);
|
||||
|
||||
// Unlock the underlying block device. Negative error codes
|
||||
// are propagated to the user.
|
||||
int (*unlock)(const struct lfs_config *c);
|
||||
#endif
|
||||
|
||||
// Minimum size of a block read in bytes. All read operations will be a
|
||||
// multiple of this value.
|
||||
lfs_size_t read_size;
|
||||
|
||||
// Minimum size of a block program in bytes. All program operations will be
|
||||
// a multiple of this value.
|
||||
lfs_size_t prog_size;
|
||||
|
||||
// Size of an erasable block in bytes. This does not impact ram consumption
|
||||
// and may be larger than the physical erase size. However, non-inlined
|
||||
// files take up at minimum one block. Must be a multiple of the read and
|
||||
// program sizes.
|
||||
lfs_size_t block_size;
|
||||
|
||||
// Number of erasable blocks on the device.
|
||||
lfs_size_t block_count;
|
||||
|
||||
// Number of erase cycles before littlefs evicts metadata logs and moves
|
||||
// the metadata to another block. Suggested values are in the
|
||||
// range 100-1000, with large values having better performance at the cost
|
||||
// of less consistent wear distribution.
|
||||
//
|
||||
// Set to -1 to disable block-level wear-leveling.
|
||||
int32_t block_cycles;
|
||||
|
||||
// Size of block caches in bytes. Each cache buffers a portion of a block in
|
||||
// RAM. The littlefs needs a read cache, a program cache, and one additional
|
||||
// cache per file. Larger caches can improve performance by storing more
|
||||
// data and reducing the number of disk accesses. Must be a multiple of the
|
||||
// read and program sizes, and a factor of the block size.
|
||||
lfs_size_t cache_size;
|
||||
|
||||
// Size of the lookahead buffer in bytes. A larger lookahead buffer
|
||||
// increases the number of blocks found during an allocation pass. The
|
||||
// lookahead buffer is stored as a compact bitmap, so each byte of RAM
|
||||
// can track 8 blocks.
|
||||
lfs_size_t lookahead_size;
|
||||
|
||||
// Threshold for metadata compaction during lfs_fs_gc in bytes. Metadata
|
||||
// pairs that exceed this threshold will be compacted during lfs_fs_gc.
|
||||
// Defaults to ~88% block_size when zero, though the default may change
|
||||
// in the future.
|
||||
//
|
||||
// Note this only affects lfs_fs_gc. Normal compactions still only occur
|
||||
// when full.
|
||||
//
|
||||
// Set to -1 to disable metadata compaction during lfs_fs_gc.
|
||||
lfs_size_t compact_thresh;
|
||||
|
||||
// Optional statically allocated read buffer. Must be cache_size.
|
||||
// By default lfs_malloc is used to allocate this buffer.
|
||||
void *read_buffer;
|
||||
|
||||
// Optional statically allocated program buffer. Must be cache_size.
|
||||
// By default lfs_malloc is used to allocate this buffer.
|
||||
void *prog_buffer;
|
||||
|
||||
// Optional statically allocated lookahead buffer. Must be lookahead_size.
|
||||
// By default lfs_malloc is used to allocate this buffer.
|
||||
void *lookahead_buffer;
|
||||
|
||||
// Optional upper limit on length of file names in bytes. No downside for
|
||||
// larger names except the size of the info struct which is controlled by
|
||||
// the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in
|
||||
// superblock and must be respected by other littlefs drivers.
|
||||
lfs_size_t name_max;
|
||||
|
||||
// Optional upper limit on files in bytes. No downside for larger files
|
||||
// but must be <= LFS_FILE_MAX. Defaults to LFS_FILE_MAX when zero. Stored
|
||||
// in superblock and must be respected by other littlefs drivers.
|
||||
lfs_size_t file_max;
|
||||
|
||||
// Optional upper limit on custom attributes in bytes. No downside for
|
||||
// larger attributes size but must be <= LFS_ATTR_MAX. Defaults to
|
||||
// LFS_ATTR_MAX when zero.
|
||||
lfs_size_t attr_max;
|
||||
|
||||
// Optional upper limit on total space given to metadata pairs in bytes. On
|
||||
// devices with large blocks (e.g. 128kB) setting this to a low size (2-8kB)
|
||||
// can help bound the metadata compaction time. Must be <= block_size.
|
||||
// Defaults to block_size when zero.
|
||||
lfs_size_t metadata_max;
|
||||
|
||||
// Optional upper limit on inlined files in bytes. Inlined files live in
|
||||
// metadata and decrease storage requirements, but may be limited to
|
||||
// improve metadata-related performance. Must be <= cache_size, <=
|
||||
// attr_max, and <= block_size/8. Defaults to the largest possible
|
||||
// inline_max when zero.
|
||||
//
|
||||
// Set to -1 to disable inlined files.
|
||||
lfs_size_t inline_max;
|
||||
|
||||
#ifdef LFS_MULTIVERSION
|
||||
// On-disk version to use when writing in the form of 16-bit major version
|
||||
// + 16-bit minor version. This limiting metadata to what is supported by
|
||||
// older minor versions. Note that some features will be lost. Defaults to
|
||||
// to the most recent minor version when zero.
|
||||
uint32_t disk_version;
|
||||
#endif
|
||||
};
|
||||
|
||||
// File info structure
|
||||
struct lfs_info {
|
||||
// Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR
|
||||
uint8_t type;
|
||||
|
||||
// Size of the file, only valid for REG files. Limited to 32-bits.
|
||||
lfs_size_t size;
|
||||
|
||||
// Name of the file stored as a null-terminated string. Limited to
|
||||
// LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to
|
||||
// reduce RAM. LFS_NAME_MAX is stored in superblock and must be
|
||||
// respected by other littlefs drivers.
|
||||
char name[LFS_NAME_MAX+1];
|
||||
};
|
||||
|
||||
// Filesystem info structure
|
||||
struct lfs_fsinfo {
|
||||
// On-disk version.
|
||||
uint32_t disk_version;
|
||||
|
||||
// Size of a logical block in bytes.
|
||||
lfs_size_t block_size;
|
||||
|
||||
// Number of logical blocks in filesystem.
|
||||
lfs_size_t block_count;
|
||||
|
||||
// Upper limit on the length of file names in bytes.
|
||||
lfs_size_t name_max;
|
||||
|
||||
// Upper limit on the size of files in bytes.
|
||||
lfs_size_t file_max;
|
||||
|
||||
// Upper limit on the size of custom attributes in bytes.
|
||||
lfs_size_t attr_max;
|
||||
};
|
||||
|
||||
// Custom attribute structure, used to describe custom attributes
|
||||
// committed atomically during file writes.
|
||||
struct lfs_attr {
|
||||
// 8-bit type of attribute, provided by user and used to
|
||||
// identify the attribute
|
||||
uint8_t type;
|
||||
|
||||
// Pointer to buffer containing the attribute
|
||||
void *buffer;
|
||||
|
||||
// Size of attribute in bytes, limited to LFS_ATTR_MAX
|
||||
lfs_size_t size;
|
||||
};
|
||||
|
||||
// Optional configuration provided during lfs_file_opencfg
|
||||
struct lfs_file_config {
|
||||
// Optional statically allocated file buffer. Must be cache_size.
|
||||
// By default lfs_malloc is used to allocate this buffer.
|
||||
void *buffer;
|
||||
|
||||
// Optional list of custom attributes related to the file. If the file
|
||||
// is opened with read access, these attributes will be read from disk
|
||||
// during the open call. If the file is opened with write access, the
|
||||
// attributes will be written to disk every file sync or close. This
|
||||
// write occurs atomically with update to the file's contents.
|
||||
//
|
||||
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller
|
||||
// than the buffer, it will be padded with zeros. If the stored attribute
|
||||
// is larger, then it will be silently truncated. If the attribute is not
|
||||
// found, it will be created implicitly.
|
||||
struct lfs_attr *attrs;
|
||||
|
||||
// Number of custom attributes in the list
|
||||
lfs_size_t attr_count;
|
||||
};
|
||||
|
||||
|
||||
/// internal littlefs data structures ///
|
||||
typedef struct lfs_cache {
|
||||
lfs_block_t block;
|
||||
lfs_off_t off;
|
||||
lfs_size_t size;
|
||||
uint8_t *buffer;
|
||||
} lfs_cache_t;
|
||||
|
||||
typedef struct lfs_mdir {
|
||||
lfs_block_t pair[2];
|
||||
uint32_t rev;
|
||||
lfs_off_t off;
|
||||
uint32_t etag;
|
||||
uint16_t count;
|
||||
bool erased;
|
||||
bool split;
|
||||
lfs_block_t tail[2];
|
||||
} lfs_mdir_t;
|
||||
|
||||
// littlefs directory type
|
||||
typedef struct lfs_dir {
|
||||
struct lfs_dir *next;
|
||||
uint16_t id;
|
||||
uint8_t type;
|
||||
lfs_mdir_t m;
|
||||
|
||||
lfs_off_t pos;
|
||||
lfs_block_t head[2];
|
||||
} lfs_dir_t;
|
||||
|
||||
// littlefs file type
|
||||
typedef struct lfs_file {
|
||||
struct lfs_file *next;
|
||||
uint16_t id;
|
||||
uint8_t type;
|
||||
lfs_mdir_t m;
|
||||
|
||||
struct lfs_ctz {
|
||||
lfs_block_t head;
|
||||
lfs_size_t size;
|
||||
} ctz;
|
||||
|
||||
uint32_t flags;
|
||||
lfs_off_t pos;
|
||||
lfs_block_t block;
|
||||
lfs_off_t off;
|
||||
lfs_cache_t cache;
|
||||
|
||||
const struct lfs_file_config *cfg;
|
||||
} lfs_file_t;
|
||||
|
||||
typedef struct lfs_superblock {
|
||||
uint32_t version;
|
||||
lfs_size_t block_size;
|
||||
lfs_size_t block_count;
|
||||
lfs_size_t name_max;
|
||||
lfs_size_t file_max;
|
||||
lfs_size_t attr_max;
|
||||
} lfs_superblock_t;
|
||||
|
||||
typedef struct lfs_gstate {
|
||||
uint32_t tag;
|
||||
lfs_block_t pair[2];
|
||||
} lfs_gstate_t;
|
||||
|
||||
// The littlefs filesystem type
|
||||
typedef struct lfs {
|
||||
lfs_cache_t rcache;
|
||||
lfs_cache_t pcache;
|
||||
|
||||
lfs_block_t root[2];
|
||||
struct lfs_mlist {
|
||||
struct lfs_mlist *next;
|
||||
uint16_t id;
|
||||
uint8_t type;
|
||||
lfs_mdir_t m;
|
||||
} *mlist;
|
||||
uint32_t seed;
|
||||
|
||||
lfs_gstate_t gstate;
|
||||
lfs_gstate_t gdisk;
|
||||
lfs_gstate_t gdelta;
|
||||
|
||||
struct lfs_lookahead {
|
||||
lfs_block_t start;
|
||||
lfs_block_t size;
|
||||
lfs_block_t next;
|
||||
lfs_block_t ckpoint;
|
||||
uint8_t *buffer;
|
||||
} lookahead;
|
||||
|
||||
const struct lfs_config *cfg;
|
||||
lfs_size_t block_count;
|
||||
lfs_size_t name_max;
|
||||
lfs_size_t file_max;
|
||||
lfs_size_t attr_max;
|
||||
lfs_size_t inline_max;
|
||||
|
||||
#ifdef LFS_MIGRATE
|
||||
struct lfs1 *lfs1;
|
||||
#endif
|
||||
} lfs_t;
|
||||
|
||||
|
||||
/// Filesystem functions ///
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Format a block device with the littlefs
|
||||
//
|
||||
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||
// object, and does not leave the filesystem mounted. The config struct must
|
||||
// be zeroed for defaults and backwards compatibility.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
|
||||
#endif
|
||||
|
||||
// Mounts a littlefs
|
||||
//
|
||||
// Requires a littlefs object and config struct. Multiple filesystems
|
||||
// may be mounted simultaneously with multiple littlefs objects. Both
|
||||
// lfs and config must be allocated while mounted. The config struct must
|
||||
// be zeroed for defaults and backwards compatibility.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
|
||||
|
||||
// Unmounts a littlefs
|
||||
//
|
||||
// Does nothing besides releasing any allocated resources.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_unmount(lfs_t *lfs);
|
||||
|
||||
/// General operations ///
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Removes a file or directory
|
||||
//
|
||||
// If removing a directory, the directory must be empty.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_remove(lfs_t *lfs, const char *path);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Rename or move a file or directory
|
||||
//
|
||||
// If the destination exists, it must match the source in type.
|
||||
// If the destination is a directory, the directory must be empty.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
|
||||
#endif
|
||||
|
||||
// Find info about a file or directory
|
||||
//
|
||||
// Fills out the info structure, based on the specified file or directory.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
|
||||
|
||||
// Get a custom attribute
|
||||
//
|
||||
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller than
|
||||
// the buffer, it will be padded with zeros. If the stored attribute is larger,
|
||||
// then it will be silently truncated. If no attribute is found, the error
|
||||
// LFS_ERR_NOATTR is returned and the buffer is filled with zeros.
|
||||
//
|
||||
// Returns the size of the attribute, or a negative error code on failure.
|
||||
// Note, the returned size is the size of the attribute on disk, irrespective
|
||||
// of the size of the buffer. This can be used to dynamically allocate a buffer
|
||||
// or check for existence.
|
||||
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
||||
uint8_t type, void *buffer, lfs_size_t size);
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Set custom attributes
|
||||
//
|
||||
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||
// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be
|
||||
// implicitly created.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_setattr(lfs_t *lfs, const char *path,
|
||||
uint8_t type, const void *buffer, lfs_size_t size);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Removes a custom attribute
|
||||
//
|
||||
// If an attribute is not found, nothing happens.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type);
|
||||
#endif
|
||||
|
||||
|
||||
/// File operations ///
|
||||
|
||||
#ifndef LFS_NO_MALLOC
|
||||
// Open a file
|
||||
//
|
||||
// The mode that the file is opened in is determined by the flags, which
|
||||
// are values from the enum lfs_open_flags that are bitwise-ored together.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
||||
const char *path, int flags);
|
||||
|
||||
// if LFS_NO_MALLOC is defined, lfs_file_open() will fail with LFS_ERR_NOMEM
|
||||
// thus use lfs_file_opencfg() with config.buffer set.
|
||||
#endif
|
||||
|
||||
// Open a file with extra configuration
|
||||
//
|
||||
// The mode that the file is opened in is determined by the flags, which
|
||||
// are values from the enum lfs_open_flags that are bitwise-ored together.
|
||||
//
|
||||
// The config struct provides additional config options per file as described
|
||||
// above. The config struct must remain allocated while the file is open, and
|
||||
// the config struct must be zeroed for defaults and backwards compatibility.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
||||
const char *path, int flags,
|
||||
const struct lfs_file_config *config);
|
||||
|
||||
// Close a file
|
||||
//
|
||||
// Any pending writes are written out to storage as though
|
||||
// sync had been called and releases any allocated resources.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
|
||||
|
||||
// Synchronize a file on storage
|
||||
//
|
||||
// Any pending writes are written out to storage.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
|
||||
|
||||
// Read data from file
|
||||
//
|
||||
// Takes a buffer and size indicating where to store the read data.
|
||||
// Returns the number of bytes read, or a negative error code on failure.
|
||||
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
||||
void *buffer, lfs_size_t size);
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Write data to file
|
||||
//
|
||||
// Takes a buffer and size indicating the data to write. The file will not
|
||||
// actually be updated on the storage until either sync or close is called.
|
||||
//
|
||||
// Returns the number of bytes written, or a negative error code on failure.
|
||||
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
||||
const void *buffer, lfs_size_t size);
|
||||
#endif
|
||||
|
||||
// Change the position of the file
|
||||
//
|
||||
// The change in position is determined by the offset and whence flag.
|
||||
// Returns the new position of the file, or a negative error code on failure.
|
||||
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
||||
lfs_soff_t off, int whence);
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Truncates the size of the file to the specified size
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
|
||||
#endif
|
||||
|
||||
// Return the position of the file
|
||||
//
|
||||
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
|
||||
// Returns the position of the file, or a negative error code on failure.
|
||||
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
|
||||
|
||||
// Change the position of the file to the beginning of the file
|
||||
//
|
||||
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_SET)
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
|
||||
|
||||
// Return the size of the file
|
||||
//
|
||||
// Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END)
|
||||
// Returns the size of the file, or a negative error code on failure.
|
||||
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
|
||||
|
||||
|
||||
/// Directory operations ///
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Create a directory
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_mkdir(lfs_t *lfs, const char *path);
|
||||
#endif
|
||||
|
||||
// Open a directory
|
||||
//
|
||||
// Once open a directory can be used with read to iterate over files.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
|
||||
|
||||
// Close a directory
|
||||
//
|
||||
// Releases any allocated resources.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
|
||||
|
||||
// Read an entry in the directory
|
||||
//
|
||||
// Fills out the info structure, based on the specified file or directory.
|
||||
// Returns a positive value on success, 0 at the end of directory,
|
||||
// or a negative error code on failure.
|
||||
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
|
||||
|
||||
// Change the position of the directory
|
||||
//
|
||||
// The new off must be a value previous returned from tell and specifies
|
||||
// an absolute offset in the directory seek.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
|
||||
|
||||
// Return the position of the directory
|
||||
//
|
||||
// The returned offset is only meant to be consumed by seek and may not make
|
||||
// sense, but does indicate the current position in the directory iteration.
|
||||
//
|
||||
// Returns the position of the directory, or a negative error code on failure.
|
||||
lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
|
||||
|
||||
// Change the position of the directory to the beginning of the directory
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
|
||||
|
||||
|
||||
/// Filesystem-level filesystem operations
|
||||
|
||||
// Find on-disk info about the filesystem
|
||||
//
|
||||
// Fills out the fsinfo structure based on the filesystem found on-disk.
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo);
|
||||
|
||||
// Finds the current size of the filesystem
|
||||
//
|
||||
// Note: Result is best effort. If files share COW structures, the returned
|
||||
// size may be larger than the filesystem actually is.
|
||||
//
|
||||
// Returns the number of allocated blocks, or a negative error code on failure.
|
||||
lfs_ssize_t lfs_fs_size(lfs_t *lfs);
|
||||
|
||||
// Traverse through all blocks in use by the filesystem
|
||||
//
|
||||
// The provided callback will be called with each block address that is
|
||||
// currently in use by the filesystem. This can be used to determine which
|
||||
// blocks are in use or how much of the storage is available.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Attempt to make the filesystem consistent and ready for writing
|
||||
//
|
||||
// Calling this function is not required, consistency will be implicitly
|
||||
// enforced on the first operation that writes to the filesystem, but this
|
||||
// function allows the work to be performed earlier and without other
|
||||
// filesystem changes.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_fs_mkconsistent(lfs_t *lfs);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Attempt any janitorial work
|
||||
//
|
||||
// This currently:
|
||||
// 1. Calls mkconsistent if not already consistent
|
||||
// 2. Compacts metadata > compact_thresh
|
||||
// 3. Populates the block allocator
|
||||
//
|
||||
// Though additional janitorial work may be added in the future.
|
||||
//
|
||||
// Calling this function is not required, but may allow the offloading of
|
||||
// expensive janitorial work to a less time-critical code path.
|
||||
//
|
||||
// Returns a negative error code on failure. Accomplishing nothing is not
|
||||
// an error.
|
||||
int lfs_fs_gc(lfs_t *lfs);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
// Grows the filesystem to a new size, updating the superblock with the new
|
||||
// block count.
|
||||
//
|
||||
// Note: This is irreversible.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count);
|
||||
#endif
|
||||
|
||||
#ifndef LFS_READONLY
|
||||
#ifdef LFS_MIGRATE
|
||||
// Attempts to migrate a previous version of littlefs
|
||||
//
|
||||
// Behaves similarly to the lfs_format function. Attempts to mount
|
||||
// the previous version of littlefs and update the filesystem so it can be
|
||||
// mounted with the current version of littlefs.
|
||||
//
|
||||
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||
// object, and does not leave the filesystem mounted. The config struct must
|
||||
// be zeroed for defaults and backwards compatibility.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* lfs util functions
|
||||
*
|
||||
* Copyright (c) 2022, The littlefs authors.
|
||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include "lfs_util.h"
|
||||
|
||||
// Only compile if user does not provide custom config
|
||||
#ifndef LFS_CONFIG
|
||||
|
||||
|
||||
// If user provides their own CRC impl we don't need this
|
||||
#ifndef LFS_CRC
|
||||
// Software CRC implementation with small lookup table
|
||||
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
|
||||
static const uint32_t rtable[16] = {
|
||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c,
|
||||
};
|
||||
|
||||
const uint8_t *data = buffer;
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf];
|
||||
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf];
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* lfs utility functions
|
||||
*
|
||||
* Copyright (c) 2022, The littlefs authors.
|
||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef LFS_UTIL_H
|
||||
#define LFS_UTIL_H
|
||||
|
||||
// Users can override lfs_util.h with their own configuration by defining
|
||||
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
|
||||
//
|
||||
// If LFS_CONFIG is used, none of the default utils will be emitted and must be
|
||||
// provided by the config file. To start, I would suggest copying lfs_util.h
|
||||
// and modifying as needed.
|
||||
#ifdef LFS_CONFIG
|
||||
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
|
||||
#define LFS_STRINGIZE2(x) #x
|
||||
#include LFS_STRINGIZE(LFS_CONFIG)
|
||||
#else
|
||||
|
||||
// System includes
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef LFS_NO_MALLOC
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifndef LFS_NO_ASSERT
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#if !defined(LFS_NO_DEBUG) || \
|
||||
!defined(LFS_NO_WARN) || \
|
||||
!defined(LFS_NO_ERROR) || \
|
||||
defined(LFS_YES_TRACE)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define LFS_MALLOC pvPortMalloc
|
||||
#define LFS_FREE vPortFree
|
||||
|
||||
|
||||
// Macros, may be replaced by system specific wrappers. Arguments to these
|
||||
// macros must not have side-effects as the macros can be removed for a smaller
|
||||
// code footprint
|
||||
|
||||
// Logging functions
|
||||
#ifndef LFS_TRACE
|
||||
#ifdef LFS_YES_TRACE
|
||||
#define LFS_TRACE_(fmt, ...) \
|
||||
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
||||
#else
|
||||
#define LFS_TRACE(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LFS_DEBUG
|
||||
#ifndef LFS_NO_DEBUG
|
||||
#define LFS_DEBUG_(fmt, ...) \
|
||||
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "")
|
||||
#else
|
||||
#define LFS_DEBUG(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LFS_WARN
|
||||
#ifndef LFS_NO_WARN
|
||||
#define LFS_WARN_(fmt, ...) \
|
||||
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "")
|
||||
#else
|
||||
#define LFS_WARN(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LFS_ERROR
|
||||
#ifndef LFS_NO_ERROR
|
||||
#define LFS_ERROR_(fmt, ...) \
|
||||
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "")
|
||||
#else
|
||||
#define LFS_ERROR(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Runtime assertions
|
||||
#ifndef LFS_ASSERT
|
||||
#ifndef LFS_NO_ASSERT
|
||||
#define LFS_ASSERT(test) assert(test)
|
||||
#else
|
||||
#define LFS_ASSERT(test)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Builtin functions, these may be replaced by more efficient
|
||||
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
|
||||
// expensive basic C implementation for debugging purposes
|
||||
|
||||
// Min/max functions for unsigned 32-bit numbers
|
||||
static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
// Align to nearest multiple of a size
|
||||
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
|
||||
return a - (a % alignment);
|
||||
}
|
||||
|
||||
static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) {
|
||||
return lfs_aligndown(a + alignment-1, alignment);
|
||||
}
|
||||
|
||||
// Find the smallest power of 2 greater than or equal to a
|
||||
static inline uint32_t lfs_npw2(uint32_t a) {
|
||||
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||
return 32 - __builtin_clz(a-1);
|
||||
#else
|
||||
uint32_t r = 0;
|
||||
uint32_t s;
|
||||
a -= 1;
|
||||
s = (a > 0xffff) << 4; a >>= s; r |= s;
|
||||
s = (a > 0xff ) << 3; a >>= s; r |= s;
|
||||
s = (a > 0xf ) << 2; a >>= s; r |= s;
|
||||
s = (a > 0x3 ) << 1; a >>= s; r |= s;
|
||||
return (r | (a >> 1)) + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Count the number of trailing binary zeros in a
|
||||
// lfs_ctz(0) may be undefined
|
||||
static inline uint32_t lfs_ctz(uint32_t a) {
|
||||
#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__)
|
||||
return __builtin_ctz(a);
|
||||
#else
|
||||
return lfs_npw2((a & -a) + 1) - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Count the number of binary ones in a
|
||||
static inline uint32_t lfs_popc(uint32_t a) {
|
||||
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||
return __builtin_popcount(a);
|
||||
#else
|
||||
a = a - ((a >> 1) & 0x55555555);
|
||||
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
|
||||
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Find the sequence comparison of a and b, this is the distance
|
||||
// between a and b ignoring overflow
|
||||
static inline int lfs_scmp(uint32_t a, uint32_t b) {
|
||||
return (int)(unsigned)(a - b);
|
||||
}
|
||||
|
||||
// Convert between 32-bit little-endian and native order
|
||||
static inline uint32_t lfs_fromle32(uint32_t a) {
|
||||
#if (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
return a;
|
||||
#elif !defined(LFS_NO_INTRINSICS) && ( \
|
||||
(defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
return __builtin_bswap32(a);
|
||||
#else
|
||||
return (((uint8_t*)&a)[0] << 0) |
|
||||
(((uint8_t*)&a)[1] << 8) |
|
||||
(((uint8_t*)&a)[2] << 16) |
|
||||
(((uint8_t*)&a)[3] << 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t lfs_tole32(uint32_t a) {
|
||||
return lfs_fromle32(a);
|
||||
}
|
||||
|
||||
// Convert between 32-bit big-endian and native order
|
||||
static inline uint32_t lfs_frombe32(uint32_t a) {
|
||||
#if !defined(LFS_NO_INTRINSICS) && ( \
|
||||
(defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||
return __builtin_bswap32(a);
|
||||
#elif (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
|
||||
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
return a;
|
||||
#else
|
||||
return (((uint8_t*)&a)[0] << 24) |
|
||||
(((uint8_t*)&a)[1] << 16) |
|
||||
(((uint8_t*)&a)[2] << 8) |
|
||||
(((uint8_t*)&a)[3] << 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t lfs_tobe32(uint32_t a) {
|
||||
return lfs_frombe32(a);
|
||||
}
|
||||
|
||||
// Calculate CRC-32 with polynomial = 0x04c11db7
|
||||
#ifdef LFS_CRC
|
||||
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
|
||||
return LFS_CRC(crc, buffer, size)
|
||||
}
|
||||
#else
|
||||
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size);
|
||||
#endif
|
||||
|
||||
// Allocate memory, only used if buffers are not provided to littlefs
|
||||
//
|
||||
// littlefs current has no alignment requirements, as it only allocates
|
||||
// byte-level buffers.
|
||||
static inline void *lfs_malloc(size_t size) {
|
||||
#if defined(LFS_MALLOC)
|
||||
return LFS_MALLOC(size);
|
||||
#elif !defined(LFS_NO_MALLOC)
|
||||
return malloc(size);
|
||||
#else
|
||||
(void)size;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Deallocate memory, only used if buffers are not provided to littlefs
|
||||
static inline void lfs_free(void *p) {
|
||||
#if defined(LFS_FREE)
|
||||
LFS_FREE(p);
|
||||
#elif !defined(LFS_NO_MALLOC)
|
||||
free(p);
|
||||
#else
|
||||
(void)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -7,23 +7,16 @@ extern "C"
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "apply_old_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "sdk_config.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "nrf_log_default_backends.h"
|
||||
|
||||
#include "nrf_delay.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
#include "nrf_sdh.h"
|
||||
#include "nrf_sdh_ble.h"
|
||||
#include "nrf_sdh_freertos.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -42,22 +35,22 @@ static void le_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
case BLE_GAP_EVT_CONN_PARAM_UPDATE:
|
||||
NRF_LOG_INFO("Connection parameters updated.");
|
||||
break;
|
||||
case BLE_GAP_EVT_CONNECTED: {
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
NRF_LOG_INFO("Connect to peer.");
|
||||
err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN, p_ble_evt->evt.gap_evt.conn_handle, 8);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED: {
|
||||
led_set(LED_IDEL_CONNECTED);
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
NRF_LOG_INFO("Disconnect from peer.");
|
||||
err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, p_ble_evt->evt.gap_evt.conn_handle, 0);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
break;
|
||||
led_set(LED_IDEL_DISCONNECT);
|
||||
break;
|
||||
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
|
||||
NRF_LOG_INFO("PHY update response. (AUTO)");
|
||||
ble_gap_phys_t const phys = {
|
||||
.rx_phys = BLE_GAP_PHY_AUTO,
|
||||
.rx_phys = BLE_GAP_PHY_AUTO, // adv&connection: 1M PHY, After connection: mobile-2M, PC-1M
|
||||
.tx_phys = BLE_GAP_PHY_AUTO,
|
||||
};
|
||||
err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
|
||||
@@ -102,27 +95,36 @@ static void le_stack_Init(void)
|
||||
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, le_evt_handler, NULL);
|
||||
}
|
||||
|
||||
static void nrf_sdh_freertos_task_hook(void *p_context)
|
||||
{
|
||||
UNUSED_PARAMETER(p_context);
|
||||
|
||||
elite_board_init();
|
||||
|
||||
elite_drv_init();
|
||||
|
||||
le_stack_Init(); // enable ble stack, but unscannable!! register "le_evt_handler" handle(CB)
|
||||
|
||||
extern void le_gap_init(const char *device_name, uint16_t usAppearance);
|
||||
le_gap_init(ELITE_DEVICE_NAME, BLE_APPEARANCE_UNKNOWN); // set BT name & connection interval
|
||||
|
||||
extern void le_gatt_init(void);
|
||||
le_gatt_init();
|
||||
|
||||
extern void le_srv_init(void);
|
||||
le_srv_init(); // service
|
||||
|
||||
extern void le_adv_init(uint8_t ble_conn_cfg_tag);
|
||||
le_adv_init(APP_BLE_CONN_CFG_TAG); // could be scanned
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
NRF_LOG_INIT(NULL, 0);
|
||||
NRF_LOG_DEFAULT_BACKENDS_INIT();
|
||||
NRF_LOG_INFO("%s Build: %s %s", ELITE_DEVICE_NAME, __TIME__, __DATE__);
|
||||
|
||||
le_stack_Init();
|
||||
|
||||
extern void le_gap_init(const char *device_name, uint16_t usAppearance);
|
||||
le_gap_init(ELITE_DEVICE_NAME, BLE_APPEARANCE_UNKNOWN);
|
||||
|
||||
extern void le_gatt_init(void);
|
||||
le_gatt_init();
|
||||
|
||||
extern void le_srv_init(void);
|
||||
le_srv_init();
|
||||
|
||||
extern void le_adv_init(uint8_t ble_conn_cfg_tag);
|
||||
le_adv_init(APP_BLE_CONN_CFG_TAG);
|
||||
|
||||
nrf_sdh_freertos_init(NULL, NULL);
|
||||
nrf_sdh_freertos_init(nrf_sdh_freertos_task_hook, NULL); // create event: softdevice_task - wireless protocal stack
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "max5136.h"
|
||||
|
||||
|
||||
#include "dac_drv_if.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_MAX5136_ENABLED)
|
||||
#define MAX5136_NOP_MODE (0x00 << 0)
|
||||
#define MAX5136_LDAC_MODE (0x01 << 0)
|
||||
#define MAX5136_CLR_MODE (0x02 << 0)
|
||||
#define MAX5136_PWR_CTRL_MODE (0x03 << 0)
|
||||
#define MAX5136_LINEARITY_MODE (0x05 << 0)
|
||||
#define MAX5136_WRITE_MODE (0x01 << 4)
|
||||
#define MAX5136_WRITE_THROUGH_MODE (0x03 << 4)
|
||||
|
||||
#define MAX5136_LINEARITY_SET (0b1000000000)
|
||||
#define MAX5136_LINEARITY_CLR (0b0000000000)
|
||||
|
||||
typedef struct __PACKED
|
||||
{
|
||||
uint8_t ctrl_bits;
|
||||
uint16_t data_bits;
|
||||
} max5136_opcode_t;
|
||||
|
||||
static int max5136_ldac_mode(uint32_t channel_mask)
|
||||
{
|
||||
/*
|
||||
Move contents of input to DAC registers indicated by 1's.
|
||||
No effect on registers indicated by 0's.
|
||||
*/
|
||||
max5136_opcode_t op_code = {
|
||||
.ctrl_bits = MAX5136_LDAC_MODE,
|
||||
.data_bits = __REVSH((channel_mask & 0b1111) << 8),
|
||||
};
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max5136_power_control_mode(uint32_t channel_mask, uint32_t ready_enable)
|
||||
{
|
||||
/*
|
||||
Power down DACs indicated by 1's.
|
||||
Set READY_EN = 1 to enable READY.
|
||||
*/
|
||||
max5136_opcode_t op_code = {
|
||||
.ctrl_bits = MAX5136_PWR_CTRL_MODE | (channel_mask & 0b1111),
|
||||
.data_bits = __REVSH(((channel_mask & 0b1111) << 8) | (ready_enable == 0 ? 0 : 1)),
|
||||
};
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max5136_write_mode(uint32_t channel_mask, int32_t dac_val)
|
||||
{
|
||||
/*
|
||||
Write to selected input registers (DAC output not affected).
|
||||
*/
|
||||
max5136_opcode_t op_code = {
|
||||
.ctrl_bits = MAX5136_WRITE_MODE | (channel_mask & 0b1111),
|
||||
.data_bits = __REVSH(dac_val),
|
||||
};
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max5136_write_through_mode(uint32_t channel_mask, int32_t dac_val)
|
||||
{
|
||||
/*
|
||||
Write to selected input and DAC registers, DAC outputs updated (writethrough).
|
||||
*/
|
||||
max5136_opcode_t op_code = {
|
||||
.ctrl_bits = MAX5136_WRITE_THROUGH_MODE | (channel_mask & 0b1111),
|
||||
.data_bits = __REVSH(dac_val),
|
||||
};
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void max5136_linearity(void)
|
||||
{
|
||||
/*
|
||||
To guarantee DAC linearity, wait until the supplies have
|
||||
settled. Set the LIN bit in the DAC linearity register; wait
|
||||
10ms, and clear the LIN bit.
|
||||
*/
|
||||
max5136_opcode_t op_code = { .ctrl_bits = MAX5136_LINEARITY_MODE };
|
||||
|
||||
op_code.data_bits = __REVSH(MAX5136_LINEARITY_SET);
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
op_code.data_bits = __REVSH(MAX5136_LINEARITY_CLR);
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
}
|
||||
|
||||
static int max5136_soft_reset(void)
|
||||
{
|
||||
/*
|
||||
The software clear command acts as a software POR,
|
||||
erasing the contents of all registers. All outputs
|
||||
return to the state determined by the M/Z input.
|
||||
*/
|
||||
|
||||
max5136_opcode_t op_code = {
|
||||
.ctrl_bits = MAX5136_CLR_MODE,
|
||||
.data_bits = 0,
|
||||
};
|
||||
spim_xfer(CS_DAC_PIN, NRF_SPIM_MODE_2, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max5136_init(void)
|
||||
{
|
||||
max5136_soft_reset();
|
||||
max5136_linearity();
|
||||
return 0;
|
||||
}
|
||||
|
||||
dac_drv_if_t max5316_drv = {
|
||||
.init = max5136_init,
|
||||
.ldac_mode = max5136_ldac_mode,
|
||||
.reset = max5136_soft_reset,
|
||||
.power_control_mode = max5136_power_control_mode,
|
||||
.write_mode = max5136_write_mode,
|
||||
.write_through_mode = max5136_write_through_mode,
|
||||
};
|
||||
|
||||
#endif /* !DEF_MAX5136_ENABLED */
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef __MAX5136_H__
|
||||
#define __MAX5136_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "dac_drv_if.h"
|
||||
|
||||
#if (DEF_MAX5136_ENABLED)
|
||||
extern dac_drv_if_t max5136;
|
||||
#endif /* ! DEF_MAX5316_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __MAX5136_H__ */
|
||||
@@ -4,8 +4,7 @@ MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00027000, LENGTH = 0x000B7000
|
||||
RAM_SOFTDEVICE (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
|
||||
RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 0x0002F000
|
||||
RTT (rwx) : ORIGIN = 0x2003F000, LENGTH = 0x00001000
|
||||
RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 0x00030000
|
||||
CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000
|
||||
}
|
||||
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
@@ -18,7 +18,7 @@
|
||||
</KeyValue>
|
||||
<KeyValue>
|
||||
<Key>com.sysprogs.bspoptions.nrf5x.pinreset</Key>
|
||||
<Value>CONFIG_GPIO_AS_PINRESET</Value>
|
||||
<Value />
|
||||
</KeyValue>
|
||||
<KeyValue>
|
||||
<Key>com.sysprogs.bspoptions.primary_memory</Key>
|
||||
|
||||
@@ -0,0 +1,445 @@
|
||||
#include "pel.h"
|
||||
#include "pel10_io.h"
|
||||
|
||||
#include "elite_def.h"
|
||||
|
||||
#include "nrf_delay.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_log.h"
|
||||
|
||||
#include "adc_drv.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float val;
|
||||
uint32_t pin;
|
||||
uint32_t mask;
|
||||
} input_pin_t;
|
||||
|
||||
TaskHandle_t test_gpio_task_Handle = NULL;
|
||||
|
||||
static pel_output_t output_data = { 0 };
|
||||
|
||||
const input_pin_t input_pin_tab[] = {
|
||||
{ 0.5, INPUT_1_PIN, PEL_0P5R_MASK},
|
||||
{ 1.0, INPUT_2_PIN, PEL_1P0R_MASK},
|
||||
{ 2.0, INPUT_3_PIN, PEL_2P0R_MASK},
|
||||
{ 4.0, INPUT_4_PIN, PEL_4P0R_MASK},
|
||||
{ 8.0, INPUT_5_PIN, PEL_8P0R_MASK},
|
||||
{ 16.2, INPUT_6_PIN, PEL_16P2R_MASK},
|
||||
{ 32.4, INPUT_7_PIN, PEL_32P4R_MASK},
|
||||
{ 63.4, INPUT_8_PIN, PEL_63P4R_MASK},
|
||||
{ 127.0, INPUT_9_PIN, PEL_127R_MASK},
|
||||
{ 255.0, INPUT_10_PIN, PEL_255R_MASK},
|
||||
{ 511.0, INPUT_11_PIN, PEL_511R_MASK},
|
||||
{1000.0, INPUT_12_PIN, PEL_1000R_MASK},
|
||||
};
|
||||
|
||||
static float _load_set(uint32_t mask)
|
||||
{
|
||||
float ohms = 0;
|
||||
for (uint32_t i = 0; i < COUNTOF(input_pin_tab); i++)
|
||||
{
|
||||
if (input_pin_tab[i].mask & mask)
|
||||
{
|
||||
nrf_gpio_pin_clear(input_pin_tab[i].pin);
|
||||
ohms += input_pin_tab[i].val;
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_gpio_pin_set(input_pin_tab[i].pin);
|
||||
}
|
||||
}
|
||||
return ohms;
|
||||
}
|
||||
|
||||
static float _load_set_by_ohms(float ohms)
|
||||
{
|
||||
// TODO...
|
||||
return ohms;
|
||||
}
|
||||
|
||||
static void _sample_measure_out_is_low(void)
|
||||
{
|
||||
nrf_gpio_pin_set(ANODE_PIN);
|
||||
nrf_gpio_pin_clear(CATHODE_PIN);
|
||||
nrf_gpio_pin_clear(SAMPLE_R_PIN);
|
||||
nrf_gpio_pin_clear(SAMPLE_V_PIN);
|
||||
nrf_delay_us(10);
|
||||
|
||||
nrf_gpio_pin_toggle(ANODE_PIN);
|
||||
nrf_gpio_pin_toggle(CATHODE_PIN);
|
||||
nrf_delay_us(3);
|
||||
|
||||
nrf_gpio_pin_toggle(SAMPLE_R_PIN);
|
||||
nrf_gpio_pin_toggle(SAMPLE_V_PIN);
|
||||
nrf_delay_us(5);
|
||||
|
||||
nrf_gpio_pin_toggle(SAMPLE_R_PIN);
|
||||
nrf_gpio_pin_toggle(SAMPLE_V_PIN);
|
||||
nrf_gpio_pin_toggle(CATHODE_PIN);
|
||||
nrf_gpio_pin_toggle(ANODE_PIN);
|
||||
}
|
||||
|
||||
static void _sample_measure_out_is_high(void)
|
||||
{
|
||||
nrf_gpio_pin_clear(ANODE_PIN);
|
||||
nrf_gpio_pin_set(CATHODE_PIN);
|
||||
nrf_gpio_pin_clear(SAMPLE_R_PIN);
|
||||
nrf_gpio_pin_clear(SAMPLE_V_PIN);
|
||||
nrf_delay_us(10);
|
||||
|
||||
nrf_gpio_pin_toggle(ANODE_PIN);
|
||||
nrf_gpio_pin_toggle(CATHODE_PIN);
|
||||
nrf_delay_us(3);
|
||||
|
||||
nrf_gpio_pin_toggle(SAMPLE_R_PIN);
|
||||
nrf_gpio_pin_toggle(SAMPLE_V_PIN);
|
||||
nrf_delay_us(5);
|
||||
|
||||
nrf_gpio_pin_toggle(SAMPLE_R_PIN);
|
||||
nrf_gpio_pin_toggle(SAMPLE_V_PIN);
|
||||
nrf_gpio_pin_toggle(CATHODE_PIN);
|
||||
nrf_gpio_pin_toggle(ANODE_PIN);
|
||||
}
|
||||
|
||||
void pel_relays_set(uint32_t measure_out)
|
||||
{
|
||||
if (measure_out)
|
||||
{
|
||||
nrf_gpio_pin_set(RELAY1_PIN);
|
||||
nrf_gpio_pin_clear(RELAY2_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
nrf_gpio_pin_clear(RELAY1_PIN);
|
||||
nrf_gpio_pin_set(RELAY2_PIN);
|
||||
}
|
||||
/* delay 30ms */
|
||||
vTaskDelay(pdMS_TO_TICKS(30));
|
||||
}
|
||||
|
||||
pel_output_t pel_smaple_and_convt_all(uint32_t measure_out, uint32_t load_mask)
|
||||
{
|
||||
uint32_t ch_list[] = {
|
||||
[OUTPUT_R1_IDX] = OUTPUT_R1_CHANNEL,
|
||||
[OUTPUT_R2_IDX] = OUTPUT_R2_CHANNEL,
|
||||
[OUTPUT_VO_IDX] = OUTPUT_VO_CHANNEL,
|
||||
[OUTPUT_VC_IDX] = OUTPUT_VC_CHANNEL,
|
||||
[OUTPUT_VE_IDX] = OUTPUT_VE_CHANNEL
|
||||
};
|
||||
int32_t results[COUNTOF(ch_list)];
|
||||
float f_results[COUNTOF(ch_list)];
|
||||
/* config E-load */
|
||||
_load_set(load_mask);
|
||||
/* send a pulse to sample and then read ADC channels */
|
||||
if (measure_out)
|
||||
{
|
||||
adc_read_mutiple_channels_ex(ch_list, results, COUNTOF(ch_list), _sample_measure_out_is_high);
|
||||
adc_read_multiple_milivolt_ex(ch_list, f_results, COUNTOF(ch_list), _sample_measure_out_is_high);
|
||||
}
|
||||
else
|
||||
{
|
||||
adc_read_mutiple_channels_ex(ch_list, results, COUNTOF(ch_list), _sample_measure_out_is_low);
|
||||
adc_read_multiple_milivolt_ex(ch_list, f_results, COUNTOF(ch_list), _sample_measure_out_is_low);
|
||||
}
|
||||
/* copy results */
|
||||
output_data.output_r1 = results[OUTPUT_R1_IDX];
|
||||
output_data.output_r2 = results[OUTPUT_R2_IDX];
|
||||
output_data.output_vo = results[OUTPUT_VO_IDX];
|
||||
output_data.output_vc = results[OUTPUT_VC_IDX];
|
||||
output_data.output_ve = results[OUTPUT_VE_IDX];
|
||||
{
|
||||
char str[128];
|
||||
snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_r1", output_data.output_r1, f_results[OUTPUT_R1_IDX]);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_r2", output_data.output_r2, f_results[OUTPUT_R2_IDX]);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_vo", output_data.output_vo, f_results[OUTPUT_VO_IDX]);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_vc", output_data.output_vc, f_results[OUTPUT_VC_IDX]);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_ve", output_data.output_ve, f_results[OUTPUT_VE_IDX]);
|
||||
NRF_LOG_INFO("%s", str);
|
||||
}
|
||||
return output_data;
|
||||
}
|
||||
|
||||
#define VERSION_DATE_YEAR 24
|
||||
#define VERSION_DATE_MONTH 7
|
||||
#define VERSION_DATE_DAY 9
|
||||
#define VERSION_DATE_HOUR 11
|
||||
#define VERSION_DATE_MINUTE 8
|
||||
static void cis_version(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
uint8_t cis_ver[] = {
|
||||
CIS_VERSION,
|
||||
VERSION_DATE_YEAR,
|
||||
VERSION_DATE_MONTH,
|
||||
VERSION_DATE_DAY,
|
||||
VERSION_DATE_HOUR,
|
||||
VERSION_DATE_MINUTE,
|
||||
};
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)cis_ver, sizeof(cis_ver));
|
||||
}
|
||||
|
||||
static void vis_rst(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
}
|
||||
|
||||
void test_gpio_task(void *pArg)
|
||||
{
|
||||
const uint32_t pel_pins[] = {
|
||||
INPUT_1_PIN,
|
||||
INPUT_2_PIN,
|
||||
INPUT_3_PIN,
|
||||
INPUT_4_PIN,
|
||||
INPUT_5_PIN,
|
||||
INPUT_6_PIN,
|
||||
INPUT_7_PIN,
|
||||
INPUT_8_PIN,
|
||||
INPUT_9_PIN,
|
||||
INPUT_10_PIN,
|
||||
INPUT_11_PIN,
|
||||
INPUT_12_PIN,
|
||||
ANODE_PIN,
|
||||
CATHODE_PIN,
|
||||
SAMPLE_R_PIN,
|
||||
SAMPLE_V_PIN,
|
||||
RELAY1_PIN,
|
||||
RELAY2_PIN
|
||||
};
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
NRF_LOG_INFO("[test] all output pin set low");
|
||||
for (int i = 0; i < COUNTOF(pel_pins); i++)
|
||||
{
|
||||
nrf_gpio_pin_clear(pel_pins[i]);
|
||||
}
|
||||
vTaskDelay(1000);
|
||||
|
||||
NRF_LOG_INFO("[test] all output pin set high");
|
||||
for (int i = 0; i < COUNTOF(pel_pins); i++)
|
||||
{
|
||||
nrf_gpio_pin_set(pel_pins[i]);
|
||||
}
|
||||
vTaskDelay(1000);
|
||||
|
||||
NRF_LOG_INFO("[test] alternating high and low signals on all output pins");
|
||||
for (int i = 0; i < COUNTOF(pel_pins); i++)
|
||||
{
|
||||
nrf_gpio_pin_clear(pel_pins[i]);
|
||||
}
|
||||
vTaskDelay(1000);
|
||||
for (int i = 0; i < COUNTOF(pel_pins); i++)
|
||||
{
|
||||
nrf_gpio_pin_set(pel_pins[i]);
|
||||
vTaskDelay(100);
|
||||
nrf_gpio_pin_clear(pel_pins[i]);
|
||||
}
|
||||
vTaskDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAGIC_NUM 0xFF00
|
||||
static pel_output_t dev_mode_pel_output;
|
||||
static void dev_mode(uint8_t *ins, uint16_t size)
|
||||
{
|
||||
NRF_LOG_INFO("%s", __FUNCTION__);
|
||||
struct __PACKED
|
||||
{
|
||||
uint8_t id : 4;
|
||||
uint8_t : 4;
|
||||
uint16_t magic : 16;
|
||||
uint8_t opcode;
|
||||
uint8_t param[];
|
||||
} *p_ins = (void *)ins;
|
||||
|
||||
if (p_ins->magic != MAGIC_NUM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p_ins->opcode)
|
||||
{
|
||||
case 0x60: {
|
||||
struct
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t mask;
|
||||
} __PACKED *p_param = (void *)p_ins->param;
|
||||
|
||||
pel_relays_set(p_param->status);
|
||||
dev_mode_pel_output = pel_smaple_and_convt_all(p_param->status, __REVSH(p_param->mask));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x61: {
|
||||
struct
|
||||
{
|
||||
uint8_t channel;
|
||||
} __PACKED *p_param = (void *)p_ins->param;
|
||||
|
||||
if (p_param->channel == 0x01)
|
||||
{
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)&dev_mode_pel_output.output_r1, sizeof(dev_mode_pel_output.output_r1));
|
||||
}
|
||||
else if (p_param->channel == 0x02)
|
||||
{
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)&dev_mode_pel_output.output_r2, sizeof(dev_mode_pel_output.output_r2));
|
||||
}
|
||||
else if (p_param->channel == 0x03)
|
||||
{
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)&dev_mode_pel_output.output_vo, sizeof(dev_mode_pel_output.output_vo));
|
||||
}
|
||||
else if (p_param->channel == 0x04)
|
||||
{
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)&dev_mode_pel_output.output_vc, sizeof(dev_mode_pel_output.output_vc));
|
||||
}
|
||||
else if (p_param->channel == 0x05)
|
||||
{
|
||||
extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len);
|
||||
le_data_upadate((void *)&dev_mode_pel_output.output_ve, sizeof(dev_mode_pel_output.output_ve));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xF0: {
|
||||
pel10_io_init();
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xF1: {
|
||||
struct
|
||||
{
|
||||
uint8_t status;
|
||||
} __PACKED *p_param = (void *)p_ins->param;
|
||||
|
||||
if (p_param->status == 0x01)
|
||||
{
|
||||
if (test_gpio_task_Handle == NULL)
|
||||
{
|
||||
NRF_LOG_INFO("[test] start test_gpio_task task");
|
||||
xTaskCreate(test_gpio_task, "test_gpio_task", 1024, NULL, 4, &test_gpio_task_Handle);
|
||||
}
|
||||
}
|
||||
else if (p_param->status == 0x00)
|
||||
{
|
||||
if (test_gpio_task_Handle != NULL)
|
||||
{
|
||||
NRF_LOG_INFO("[test] delete test_gpio_task task");
|
||||
vTaskDelete(test_gpio_task_Handle);
|
||||
test_gpio_task_Handle = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xF2: {
|
||||
struct
|
||||
{
|
||||
uint8_t input_n;
|
||||
uint8_t status;
|
||||
} __PACKED *p_param = (void *)p_ins->param;
|
||||
|
||||
uint32_t high_low = p_param->status;
|
||||
|
||||
switch (p_param->input_n) {
|
||||
case 0x01:
|
||||
nrf_gpio_pin_write(INPUT_1_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_1_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
nrf_gpio_pin_write(INPUT_2_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_2_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
nrf_gpio_pin_write(INPUT_3_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_3_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
nrf_gpio_pin_write(INPUT_4_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_4_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
nrf_gpio_pin_write(INPUT_5_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_5_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
nrf_gpio_pin_write(INPUT_6_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_6_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
nrf_gpio_pin_write(INPUT_7_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_7_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
nrf_gpio_pin_write(INPUT_8_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_8_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
nrf_gpio_pin_write(INPUT_9_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_9_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x0A:
|
||||
nrf_gpio_pin_write(INPUT_10_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_10_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x0B:
|
||||
nrf_gpio_pin_write(INPUT_11_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_11_PIN = %d", high_low);
|
||||
break;
|
||||
|
||||
case 0x0C:
|
||||
nrf_gpio_pin_write(INPUT_12_PIN, high_low);
|
||||
NRF_LOG_INFO("set INPUT_12_PIN = %d", high_low);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const elite_instance_t pel_elite_instance = {
|
||||
.cis_func = {
|
||||
[CIS_VERSION] = cis_version,
|
||||
},
|
||||
.vis_func = {
|
||||
[VIS_RST] = vis_rst,
|
||||
},
|
||||
.ris_func = {
|
||||
[DEV_MODE] = dev_mode,
|
||||
}
|
||||
};
|
||||
|
||||
const elite_instance_t *pel_init(void)
|
||||
{
|
||||
return &pel_elite_instance;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef __PEL_H__
|
||||
#define __PEL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "elite.h"
|
||||
|
||||
#define PEL_0P5R_MASK (0x01 << 0)
|
||||
#define PEL_1P0R_MASK (0x01 << 1)
|
||||
#define PEL_2P0R_MASK (0x01 << 2)
|
||||
#define PEL_4P0R_MASK (0x01 << 3)
|
||||
#define PEL_8P0R_MASK (0x01 << 4)
|
||||
#define PEL_16P2R_MASK (0x01 << 5)
|
||||
#define PEL_32P4R_MASK (0x01 << 6)
|
||||
#define PEL_63P4R_MASK (0x01 << 7)
|
||||
#define PEL_127R_MASK (0x01 << 8)
|
||||
#define PEL_255R_MASK (0x01 << 9)
|
||||
#define PEL_511R_MASK (0x01 << 10)
|
||||
#define PEL_1000R_MASK (0x01 << 11)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t output_r1;
|
||||
int32_t output_r2;
|
||||
int32_t output_vo;
|
||||
int32_t output_vc;
|
||||
int32_t output_ve;
|
||||
} pel_output_t;
|
||||
|
||||
void pel_relays_set(uint32_t measure_out);
|
||||
pel_output_t pel_smaple_and_convt_all(uint32_t measure_out, uint32_t load_mask);
|
||||
const elite_instance_t *pel_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __PEL_H__ */
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
|
||||
void spim_xfer(uint32_t cs_pin,
|
||||
nrf_spim_mode_t spi_mode,
|
||||
uint8_t *p_tx_buffer,
|
||||
uint16_t tx_buffer_length,
|
||||
uint8_t *p_rx_buf,
|
||||
uint16_t rx_buffer_length)
|
||||
{
|
||||
__disable_irq();
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
switch (spi_mode)
|
||||
{
|
||||
default:
|
||||
case NRF_SPIM_MODE_0:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_1:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_2:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_3:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
NRF_SPIM3->TXD.MAXCNT = tx_buffer_length;
|
||||
NRF_SPIM3->TXD.PTR = (uint32_t)p_tx_buffer;
|
||||
|
||||
NRF_SPIM3->RXD.MAXCNT = rx_buffer_length;
|
||||
NRF_SPIM3->RXD.PTR = (uint32_t)p_rx_buf;
|
||||
|
||||
nrf_gpio_pin_clear(cs_pin);
|
||||
|
||||
NRF_SPIM3->EVENTS_END = 0;
|
||||
NRF_SPIM3->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SPIM3->EVENTS_END == 0);
|
||||
|
||||
nrf_gpio_pin_set(cs_pin);
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void pel10_io_init(void)
|
||||
{
|
||||
const uint32_t pel_pins_default_high[] = {
|
||||
INPUT_1_PIN,
|
||||
INPUT_2_PIN,
|
||||
INPUT_3_PIN,
|
||||
INPUT_4_PIN,
|
||||
INPUT_5_PIN,
|
||||
INPUT_6_PIN,
|
||||
INPUT_7_PIN,
|
||||
INPUT_8_PIN,
|
||||
INPUT_9_PIN,
|
||||
INPUT_10_PIN,
|
||||
INPUT_11_PIN,
|
||||
INPUT_12_PIN
|
||||
};
|
||||
|
||||
const uint32_t pel_pins_default_low[] = {
|
||||
ANODE_PIN,
|
||||
CATHODE_PIN,
|
||||
SAMPLE_R_PIN,
|
||||
SAMPLE_V_PIN,
|
||||
RELAY1_PIN,
|
||||
RELAY2_PIN
|
||||
};
|
||||
|
||||
for (int i = 0; i < COUNTOF(pel_pins_default_high); i++)
|
||||
{
|
||||
nrf_gpio_pin_set(pel_pins_default_high[i]);
|
||||
nrf_gpio_cfg_output(pel_pins_default_high[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < COUNTOF(pel_pins_default_low); i++)
|
||||
{
|
||||
nrf_gpio_pin_clear(pel_pins_default_low[i]);
|
||||
nrf_gpio_cfg_output(pel_pins_default_low[i]);
|
||||
}
|
||||
|
||||
// Config spi module
|
||||
|
||||
nrf_gpio_pin_set(WP_MEM_PIN);
|
||||
nrf_gpio_cfg_output(WP_MEM_PIN);
|
||||
nrf_gpio_pin_set(CS_MEM_PIN);
|
||||
nrf_gpio_cfg_output(CS_MEM_PIN);
|
||||
nrf_gpio_pin_clear(SPIM_MOSI_PIN);
|
||||
nrf_gpio_cfg_output(SPIM_MOSI_PIN);
|
||||
nrf_gpio_pin_clear(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg_output(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg_input(SPIM_MISO_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
NRF_SPIM3->ORC = 0x00000000;
|
||||
NRF_SPIM3->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M32;
|
||||
NRF_SPIM3->CSNPOL = SPIM_CSNPOL_CSNPOL_LOW;
|
||||
NRF_SPIM3->IFTIMING.CSNDUR = 8;
|
||||
NRF_SPIM3->PSEL.CSN = CS_MEM_PIN;
|
||||
NRF_SPIM3->PSEL.SCK = SPIM_CLK_PIN;
|
||||
NRF_SPIM3->PSEL.MOSI = SPIM_MOSI_PIN;
|
||||
NRF_SPIM3->PSEL.MISO = SPIM_MISO_PIN;
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
}
|
||||
|
||||
#endif
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
#ifndef __PEL10_IO_H__
|
||||
#define __PEL10_IO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
||||
|
||||
#define RELAY1_PIN NRF_GPIO_PIN_MAP(1, 10)
|
||||
#define RELAY2_PIN NRF_GPIO_PIN_MAP(1, 15)
|
||||
|
||||
#define SAMPLE_R_PIN NRF_GPIO_PIN_MAP(1, 11)
|
||||
#define SAMPLE_V_PIN NRF_GPIO_PIN_MAP(1, 6)
|
||||
|
||||
#define CATHODE_PIN NRF_GPIO_PIN_MAP(0, 7)
|
||||
#define ANODE_PIN NRF_GPIO_PIN_MAP(0, 8)
|
||||
|
||||
#define OUTPUT_R1_PIN NRF_GPIO_PIN_MAP(0, 31)
|
||||
#define OUTPUT_R2_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
#define OUTPUT_VO_PIN NRF_GPIO_PIN_MAP(0, 29)
|
||||
#define OUTPUT_VC_PIN NRF_GPIO_PIN_MAP(0, 3)
|
||||
#define OUTPUT_VE_PIN NRF_GPIO_PIN_MAP(0, 2)
|
||||
|
||||
#define OUTPUT_R1_CHANNEL 7
|
||||
#define OUTPUT_R2_CHANNEL 4
|
||||
#define OUTPUT_VO_CHANNEL 5
|
||||
#define OUTPUT_VC_CHANNEL 1
|
||||
#define OUTPUT_VE_CHANNEL 0
|
||||
|
||||
#define OUTPUT_R1_IDX 0
|
||||
#define OUTPUT_R2_IDX 1
|
||||
#define OUTPUT_VO_IDX 2
|
||||
#define OUTPUT_VC_IDX 3
|
||||
#define OUTPUT_VE_IDX 4
|
||||
|
||||
#define INPUT_1_PIN NRF_GPIO_PIN_MAP(0, 15)
|
||||
#define INPUT_2_PIN NRF_GPIO_PIN_MAP(0, 13)
|
||||
#define INPUT_3_PIN NRF_GPIO_PIN_MAP(0, 20)
|
||||
#define INPUT_4_PIN NRF_GPIO_PIN_MAP(1, 0)
|
||||
#define INPUT_5_PIN NRF_GPIO_PIN_MAP(0, 25)
|
||||
#define INPUT_6_PIN NRF_GPIO_PIN_MAP(0, 11)
|
||||
#define INPUT_7_PIN NRF_GPIO_PIN_MAP(0, 14)
|
||||
#define INPUT_8_PIN NRF_GPIO_PIN_MAP(0, 17)
|
||||
#define INPUT_9_PIN NRF_GPIO_PIN_MAP(0, 18)
|
||||
#define INPUT_10_PIN NRF_GPIO_PIN_MAP(0, 21)
|
||||
#define INPUT_11_PIN NRF_GPIO_PIN_MAP(0, 19)
|
||||
#define INPUT_12_PIN NRF_GPIO_PIN_MAP(0, 22)
|
||||
|
||||
#define WP_MEM_PIN NRF_GPIO_PIN_MAP(0, 12)
|
||||
#define CS_MEM_PIN NRF_GPIO_PIN_MAP(0, 6)
|
||||
#define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 27)
|
||||
#define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 4)
|
||||
#define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
|
||||
|
||||
void spim_xfer(uint32_t cs_pin,
|
||||
nrf_spim_mode_t spi_mode,
|
||||
uint8_t *p_tx_buffer,
|
||||
uint16_t tx_buffer_length,
|
||||
uint8_t *p_rx_buf,
|
||||
uint16_t rx_buffer_length);
|
||||
|
||||
void pel10_io_init(void);
|
||||
|
||||
#endif /* ! DEF_ELITE_MODEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __PEL10_IO_H__ */
|
||||
@@ -65,7 +65,7 @@ async def ble_notify_demo(mac_addr: str):
|
||||
mac_addr = "DF:4C:23:1C:F5:59"
|
||||
mac_addr = "EB:E6:E0:52:26:ED"
|
||||
mac_addr = "D8:96:4A:0B:14:4A"
|
||||
mac_addr = "DC:05:1F:1F:71:DA"
|
||||
mac_addr = "DC:05:1F:1F:71:DA"
|
||||
if asyncio.run(ble_notify_demo(mac_addr)) == True :
|
||||
print("Recv total: {0} bytes".format(TotalBytes))
|
||||
f.close()
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "sw_drv.h"
|
||||
|
||||
#if (DEF_ADGS1412_ENABLED)
|
||||
|
||||
#include "adgs1412.h"
|
||||
const sw_drv_if_t *p_inst = &adgs1412;
|
||||
|
||||
#else
|
||||
|
||||
const sw_drv_if_t *p_inst = NULL;
|
||||
|
||||
#endif /* ! DEF_ADGS1412_ENABLED */
|
||||
|
||||
#if (DEF_SW_DRV_ENABLED)
|
||||
|
||||
int sw_init(void)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return SW_DRV_ERROR;
|
||||
}
|
||||
return p_inst->init();
|
||||
}
|
||||
|
||||
int sw_reset(void)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return SW_DRV_ERROR;
|
||||
}
|
||||
return p_inst->reset();
|
||||
}
|
||||
|
||||
int sw_write(sw_t sw_mask)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return SW_DRV_ERROR;
|
||||
}
|
||||
return p_inst->write(sw_mask);
|
||||
}
|
||||
|
||||
int sw_read(sw_t *p_sw_mask)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return SW_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read(p_sw_mask);
|
||||
}
|
||||
|
||||
|
||||
int sw_count(uint32_t *p_sw_count)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return SW_DRV_ERROR;
|
||||
}
|
||||
return p_inst->get_sw_count(p_sw_count);
|
||||
}
|
||||
|
||||
#endif /* ! DEF_SW_DRV_ENABLED */
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef __SW_DRV_H__
|
||||
#define __SW_DRV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "app_config.h"
|
||||
#include "sw_drv_if.h"
|
||||
|
||||
#define SW_DRV_ERROR (-1)
|
||||
#define SW_DRV_SUCCESS (0)
|
||||
|
||||
#if (DEF_SW_DRV_ENABLED)
|
||||
|
||||
int sw_init(void);
|
||||
int sw_reset(void);
|
||||
int sw_write(sw_t sw_mask);
|
||||
int sw_read(sw_t *p_sw_mask);
|
||||
int sw_count(uint32_t *p_sw_count);
|
||||
|
||||
#else
|
||||
|
||||
#define sw_init()
|
||||
#define sw_reset()
|
||||
#define sw_write(x)
|
||||
#define sw_read(x)
|
||||
#define sw_count(x)
|
||||
|
||||
#endif /* ! DEF_SW_DRV_ENABLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __SW_DRV_H__ */
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
#ifndef __SW_DRV_IF_H__
|
||||
#define __SW_DRV_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint64_t val;
|
||||
struct
|
||||
{
|
||||
uint64_t sw0 : 1;
|
||||
uint64_t sw1 : 1;
|
||||
uint64_t sw2 : 1;
|
||||
uint64_t sw3 : 1;
|
||||
uint64_t sw4 : 1;
|
||||
uint64_t sw5 : 1;
|
||||
uint64_t sw6 : 1;
|
||||
uint64_t sw7 : 1;
|
||||
uint64_t sw8 : 1;
|
||||
uint64_t sw9 : 1;
|
||||
uint64_t sw10 : 1;
|
||||
uint64_t sw11 : 1;
|
||||
uint64_t sw12 : 1;
|
||||
uint64_t sw13 : 1;
|
||||
uint64_t sw14 : 1;
|
||||
uint64_t sw15 : 1;
|
||||
uint64_t sw16 : 1;
|
||||
uint64_t sw17 : 1;
|
||||
uint64_t sw18 : 1;
|
||||
uint64_t sw19 : 1;
|
||||
uint64_t sw20 : 1;
|
||||
uint64_t sw21 : 1;
|
||||
uint64_t sw22 : 1;
|
||||
uint64_t sw23 : 1;
|
||||
uint64_t sw24 : 1;
|
||||
uint64_t sw25 : 1;
|
||||
uint64_t sw26 : 1;
|
||||
uint64_t sw27 : 1;
|
||||
uint64_t sw28 : 1;
|
||||
uint64_t sw29 : 1;
|
||||
uint64_t sw30 : 1;
|
||||
uint64_t sw31 : 1;
|
||||
uint64_t sw32 : 1;
|
||||
uint64_t sw33 : 1;
|
||||
uint64_t sw34 : 1;
|
||||
uint64_t sw35 : 1;
|
||||
uint64_t sw36 : 1;
|
||||
uint64_t sw37 : 1;
|
||||
uint64_t sw38 : 1;
|
||||
uint64_t sw39 : 1;
|
||||
uint64_t sw40 : 1;
|
||||
uint64_t sw41 : 1;
|
||||
uint64_t sw42 : 1;
|
||||
uint64_t sw43 : 1;
|
||||
uint64_t sw44 : 1;
|
||||
uint64_t sw45 : 1;
|
||||
uint64_t sw46 : 1;
|
||||
uint64_t sw47 : 1;
|
||||
uint64_t sw48 : 1;
|
||||
uint64_t sw49 : 1;
|
||||
uint64_t sw50 : 1;
|
||||
uint64_t sw51 : 1;
|
||||
uint64_t sw52 : 1;
|
||||
uint64_t sw53 : 1;
|
||||
uint64_t sw54 : 1;
|
||||
uint64_t sw55 : 1;
|
||||
uint64_t sw56 : 1;
|
||||
uint64_t sw57 : 1;
|
||||
uint64_t sw58 : 1;
|
||||
uint64_t sw59 : 1;
|
||||
uint64_t sw60 : 1;
|
||||
uint64_t sw61 : 1;
|
||||
uint64_t sw62 : 1;
|
||||
uint64_t sw63 : 1;
|
||||
};
|
||||
} sw_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int (*init)(void);
|
||||
int (*reset)(void);
|
||||
int (*write)(sw_t sw_mask);
|
||||
int (*read)(sw_t *p_sw_mask);
|
||||
int (*get_sw_count)(uint32_t *p_sw_count);
|
||||
} sw_drv_if_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __SW_DRV_IF_H__ */
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file syscalls.c
|
||||
* @author Auto-generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE Minimal System calls file
|
||||
*
|
||||
* For more information about which c-functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib libc-manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
/* Variables */
|
||||
extern int __io_putchar(int ch) __attribute__((weak));
|
||||
extern int __io_getchar(void) __attribute__((weak));
|
||||
|
||||
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
|
||||
/* Functions */
|
||||
void initialise_monitor_handles()
|
||||
{
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit (int status)
|
||||
{
|
||||
_kill(status, -1);
|
||||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
*ptr++ = __io_getchar();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _open(char *path, int flags, ...)
|
||||
{
|
||||
/* Pretend like we always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _wait(int *status)
|
||||
{
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _unlink(char *name)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _times(struct tms *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _stat(char *file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user