Compare commits

..

1 Commits

Author SHA1 Message Date
Roy_01 10e1b32bc1 wheel capacitive touch sensor driver 2024-01-23 14:16:46 +08:00
86 changed files with 1778 additions and 21327 deletions
-1
View File
@@ -2,4 +2,3 @@
/.visualgdb/
/VisualGDB/
*.vgdbsettings.*.user
*.zip
+97 -93
View File
@@ -26,6 +26,7 @@
* 1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
@@ -37,8 +38,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.
@@ -52,152 +53,155 @@
* 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 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
#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
/* 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 */
-86
View File
@@ -1,86 +0,0 @@
#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 */
-47
View File
@@ -1,47 +0,0 @@
#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__ */
-47
View File
@@ -1,47 +0,0 @@
#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
View File
@@ -1,71 +0,0 @@
#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
View File
@@ -1,30 +0,0 @@
#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__ */
-336
View File
@@ -1,336 +0,0 @@
#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 */
-21
View File
@@ -1,21 +0,0 @@
#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__ */
-77
View File
@@ -1,77 +0,0 @@
#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 */
-22
View File
@@ -1,22 +0,0 @@
#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__ */
+73 -172
View File
@@ -1,3 +1,4 @@
#pragma once
#ifndef __APP_CONFIG_H__
#define __APP_CONFIG_H__
@@ -18,13 +19,12 @@ extern "C"
#define NRF_LOG_DEFERRED 0
#define NRF_LOG_USES_TIMESTAMP 0
#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 0
#define NRF_LOG_MSGPOOL_ELEMENT_COUNT 31
// SEGGER-RTT
#define SEGGER_RTT_SECTION ".segger_rtt"
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 1
#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 1
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 2048
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4000
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
@@ -103,202 +103,103 @@ extern "C"
#define BLE_ADVERTISING_ENABLED 1
// BLE device name
#define DEF_ELITE_DEV 0x00000000
#define DEF_ELITE_EDC_V2_0 0x00020109
#define DEF_ELITE_PEL_V2_0 0x00070001
#define DEF_ELITE_CPG_V1_1 0x00080001
#define DEF_ELITE_MODEL DEF_ELITE_CPG_V1_1
#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_TW1508_ENABLED 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_MAX14802_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_V2_0)
#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_TW1508_ENABLED 0
#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_MAX14802_ENABLED 0
#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_ELITE_PEL_V2_0)
#define ELITE_DEVICE_NAME "Elite-PEL"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 7
#define MAJOR_VERSION_NUMBER 0
#define MINOR_VERSION_NUMBER 1
#define DEF_TW1508_ENABLED 0
#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_MAX14802_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_CPG_V1_1)
#define ELITE_DEVICE_NAME "Elite-CPG"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 8
#define MAJOR_VERSION_NUMBER 0
#define MINOR_VERSION_NUMBER 1
#define DEF_TW1508_ENABLED 1
#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 1
#define DEF_MAX14802_ENABLED 1
#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
#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_EDC_15RE
#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
#define BLE_EDC_ENABLED 1
#define EDC_BLE_OBSERVER_PRIO 3
#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
#define BLE_EDC_ENABLED 1
#define EDC_BLE_OBSERVER_PRIO 3
#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 EDC_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 EDC_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
#define BLE_EIS_ENABLED 1
#define EDC_BLE_OBSERVER_PRIO 3
#endif
#define BLE_ELITE_SRV_ENABLED 1
#define BLE_ELITE_OBSERVER_PRIO 3
#define ELITE_UUID 0xFFF0
#define ELITE_COMPANY_CODE "BPHS"
#define ELITE_COMPANY_CODE "Elite"
#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
#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]))
#define UNCONNECTED_PIN 0xFFFFFFFF
#define TWI_ENABLED 1
#define TWI0_ENABLED 1
#define TWI0_USE_EASY_DMA 1
#ifdef __cplusplus
}
#endif
#endif /* ! __APP_CONFIG_H__ */
#endif // !__APP_CONFIG_H__
-33
View File
@@ -1,33 +0,0 @@
#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__ */
+4 -2
View File
@@ -25,6 +25,7 @@
<ProjectFile>bmd380_peripheral.vcxproj</ProjectFile>
<RemoteBuildEnvironment>
<Records />
<EnvironmentSetupFiles />
</RemoteBuildEnvironment>
<ParallelJobCount>1</ParallelJobCount>
<SuppressDirectoryChangeMessages>true</SuppressDirectoryChangeMessages>
@@ -113,6 +114,8 @@
</AdditionalGDBSettings>
<DebugMethod>
<ID>jlink-jtag</ID>
<InterfaceID>com.sysprogs.debug.jlink.jlinksw</InterfaceID>
<InterfaceSerialNumber>000682409936</InterfaceSerialNumber>
<Configuration xsi:type="com.visualgdb.edp.segger.settings">
<CommandLine>-select USB -device $$SYS:MCU_ID$$ -speed auto -if SWD</CommandLine>
<ProgramMode>Enabled</ProgramMode>
@@ -137,8 +140,7 @@
<EnableVirtualHalts>false</EnableVirtualHalts>
<DynamicAnalysisSettings />
<EndOfStackSymbol>_estack</EndOfStackSymbol>
<TimestampProvider>com.sysprogs.arm.dwt</TimestampProvider>
<TimestampProviderTicksPerSecond>64000000</TimestampProviderTicksPerSecond>
<TimestampProviderTicksPerSecond>0</TimestampProviderTicksPerSecond>
<KeepConsoleAfterExit>false</KeepConsoleAfterExit>
<UnusedStackFillPattern xsi:nil="true" />
<CheckInterfaceDrivers>true</CheckInterfaceDrivers>
+13 -86
View File
@@ -32,42 +32,31 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
<GNUConfigurationType>Debug</GNUConfigurationType>
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
<ToolchainVersion>13.3.1/15.1/r2</ToolchainVersion>
<ToolchainVersion>12.3.1/13.2/r1</ToolchainVersion>
<GenerateHexFile>true</GenerateHexFile>
<MCUPropertyListFile>$(ProjectDir)nrf5x.props</MCUPropertyListFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|VisualGDB'">
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
<ToolchainVersion>13.3.1/15.1/r2</ToolchainVersion>
<ToolchainVersion>12.3.1/13.2/r1</ToolchainVersion>
<GenerateHexFile>true</GenerateHexFile>
<MCUPropertyListFile>$(ProjectDir)nrf5x.props</MCUPropertyListFile>
</PropertyGroup>
<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;littlefs;%(ClCompile.AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>DEBUG=1;USE_APP_CONFIG=1;LFS_THREADSAFE=1;CONFIG_NFCT_PINS_AS_GPIOS;%(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;%(ClCompile.AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>DEBUG=1;USE_APP_CONFIG=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>
@@ -191,46 +180,18 @@
<ClCompile Include="..\bmd380_sdk\integration\nrfx\legacy\nrf_drv_uart.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">true</ExcludedFromBuild>
</ClCompile>
<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="cpg11_dev_mode.c" />
<ClCompile Include="cpg11_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="max14802.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="edc_regular_data.c" />
<ClCompile Include="i2c.c" />
<ClCompile Include="led.c" />
<ClCompile Include="le_adv.c" />
<ClCompile Include="le_dfu.c" />
<ClCompile Include="le_elite_srv.c" />
<ClCompile Include="le_edc_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="pel20_io.c" />
<ClCompile Include="sw_drv.c" />
<ClCompile Include="spi.c" />
<ClCompile Include="syscalls.c" />
<ClCompile Include="tw1508.c" />
<ClInclude Include="max14802.h" />
<ClInclude Include="pel20_io.h" />
<ClInclude Include="tw1508.h" />
<None Include="nRF52811_XXAA_s140.lds" />
<None Include="nRF52840_XXAA_S140_reserve.lds" />
<None Include="nrf5x.props" />
@@ -373,39 +334,9 @@
<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="cpg11_dev_mode.h" />
<ClInclude Include="cpg11_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="sw_drv.h" />
<ClInclude Include="sw_drv_if.h" />
<ClInclude Include="led.h" />
<ClInclude Include="sdk_config.h" />
<ClInclude Include="radio_config.h" />
<ClInclude Include="sdio_config.h" />
@@ -662,9 +593,5 @@
<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>
+9 -204
View File
@@ -232,12 +232,6 @@
<Filter Include="Header files\ble\common">
<UniqueIdentifier>{defffc43-551c-4791-967b-7d0aee507516}</UniqueIdentifier>
</Filter>
<Filter Include="Source files\littlefs">
<UniqueIdentifier>{7f850d36-a444-417b-bf03-8433324adaa4}</UniqueIdentifier>
</Filter>
<Filter Include="Header files\littlefs">
<UniqueIdentifier>{0203873a-9b27-4c14-8951-9bfadceafef5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.c">
@@ -1341,9 +1335,15 @@
<ClCompile Include="..\bmd380_sdk\components\ble\nrf_ble_gatt\nrf_ble_gatt.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="edc_regular_data.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="le_dfu.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="le_edc_srv.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="le_gatt.c">
<Filter>Source files</Filter>
</ClCompile>
@@ -1356,106 +1356,10 @@
<ClCompile Include="..\bmd380_sdk\components\libraries\pwr_mgmt\nrf_pwr_mgmt.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="le_elite_srv.c">
<ClCompile Include="led.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="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="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>
<ClCompile Include="builtin_saadc.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="cpg.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="cpg11_dev_mode.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="cpg11_io.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="tw1508.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="max14802.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="pel20_io.c">
<ClCompile Include="spi.c">
<Filter>Source files</Filter>
</ClCompile>
</ItemGroup>
@@ -1723,106 +1627,7 @@
<ClInclude Include="..\bmd380_sdk\components\libraries\pwr_mgmt\nrf_pwr_mgmt.h">
<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="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="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>
<ClInclude Include="tw1508.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="cpg.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="cpg11_dev_mode.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="cpg11_io.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="max14802.h">
<Filter>Header files</Filter>
</ClInclude>
<ClInclude Include="pel20_io.h">
<ClInclude Include="led.h">
<Filter>Header files</Filter>
</ClInclude>
</ItemGroup>
-194
View File
@@ -1,194 +0,0 @@
#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 */
-20
View File
@@ -1,20 +0,0 @@
#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
View File
@@ -1,341 +0,0 @@
#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,
};
-16
View File
@@ -1,16 +0,0 @@
#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__ */
-114
View File
@@ -1,114 +0,0 @@
#include "cpg11_dev_mode.h"
#include "pel.h"
#include "elite_board.h"
#include "elite_def.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_log.h"
#include "tw1508.h"
#if (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
#define VERSION_DATE_YEAR 24
#define VERSION_DATE_MONTH 9
#define VERSION_DATE_DAY 26
#define VERSION_DATE_HOUR 11
#define VERSION_DATE_MINUTE 04
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 func_id;
uint8_t opcode;
uint8_t param[];
} *p_ins = (void *)ins;
switch (p_ins->func_id)
{
case 0x00:
dev_mode_electrode_switch(ins);
break;
case 0x01:
dev_mode_tw1508(ins);
break;
case 0x02:
dev_mode_ctrl_cpg11_electrodes_task(ins);
break;
case 0x03:
dev_mode_adapter_block_switch(ins);
break;
// 0xA0 to 0xBF are reserved for controlling the BMD380
case 0xA0:
dev_mode_gpio(ins);
break;
case 0xA1:
// spi
break;
case 0xA2:
// i2c
break;
// 0xF0 to 0xFF are reserved for calibration
case 0xF0:
// cali
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)
{
tw1508_init();
tw1508_set(5, 5); // 5*0.13= 0.65mA, formula:value*0.13=mA
return &cpg_elite_instance;
}
#endif
-15
View File
@@ -1,15 +0,0 @@
#ifndef __CPG_H__
#define __CPG_H__
#ifdef __cplusplus
extern "C"
{
#endif
const elite_instance_t *cpg_init(void);
#ifdef __cplusplus
}
#endif
#endif /* ! __CPG_H__ */
-1599
View File
File diff suppressed because it is too large Load Diff
-24
View File
@@ -1,24 +0,0 @@
#ifndef __CPG11_DEV_MODE_H__
#define __CPG11_DEV_MODE_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_button.h"
#include "elite_board.h"
#if (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
void dev_mode_electrode_switch(uint8_t *ins);
void dev_mode_tw1508(uint8_t *ins);
void dev_mode_ctrl_cpg11_electrodes_task(uint8_t *ins);
void dev_mode_adapter_block_switch(uint8_t *ins);
void dev_mode_gpio(uint8_t *ins);
#endif
#ifdef __cplusplus
}
#endif
#endif /* ! __CPG11_DEV_MODE_H__ */
-489
View File
@@ -1,489 +0,0 @@
#include "elite_board.h"
#include "nrf_gpio.h"
#include "nrf_gpiote.h"
#include "nrf_log.h"
#include "nrf_spim.h"
#include "nrf_timer.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#pragma GCC optimize("O2")
#if (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
typedef struct
{
const uint32_t gpiote_idx[4];
NRF_TIMER_Type *TMR_A;
NRF_TIMER_Type *TMR_B;
uint32_t IRQn;
pulse_gen_t *p_pulse_gen;
struct
{
pulse_gen_t *p_pulse_gen;
uint32_t len;
uint32_t select;
} private;
} pulse_gen_hw_t;
pulse_gen_hw_t pulse_gen_hw[] = {
{.gpiote_idx = { 0, 1, 2, 3 },
.TMR_A = NRF_TIMER1,
.TMR_B = NRF_TIMER3,
.IRQn = TIMER3_IRQn,
.p_pulse_gen = NULL,
.private = { NULL, 0, 0 }},
{.gpiote_idx = { 4, 5, 6, 7 },
.TMR_A = NRF_TIMER2,
.TMR_B = NRF_TIMER4,
.IRQn = TIMER4_IRQn,
.p_pulse_gen = NULL,
.private = { NULL, 0, 0 }},
};
__STATIC_INLINE void cpg11_tmr_cb(uint32_t hw_idx)
{
if (pulse_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[4])
{
pulse_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[4] = 0;
uint32_t sel = pulse_gen_hw[hw_idx].private.select;
if (pulse_gen_hw[hw_idx].private.p_pulse_gen[sel].pulse_cnt > 0)
{
pulse_gen_hw[hw_idx].private.p_pulse_gen[sel].pulse_cnt--;
}
for (uint32_t i = 0; i < pulse_gen_hw[hw_idx].private.len; i++)
{
sel = (sel + 1) % pulse_gen_hw[hw_idx].private.len;
if (pulse_gen_hw[hw_idx].private.p_pulse_gen[sel].pulse_cnt > 0)
{
pulse_gen_hw[hw_idx].private.select = sel;
cpg11_pulse_start(hw_idx, &pulse_gen_hw[hw_idx].private.p_pulse_gen[sel]);
return;
}
}
}
}
void TIMER3_IRQHandler(void)
{
cpg11_tmr_cb(0);
}
void TIMER4_IRQHandler(void)
{
cpg11_tmr_cb(1);
}
void cpg11_pulse_suspend_by_pulse_id(uint32_t pulse_id)
{
for (uint32_t i = 0; i < COUNTOF(pulse_gen_hw); i++)
{
for (uint32_t j = 0; j < pulse_gen_hw[i].private.len; j++)
{
if (pulse_gen_hw[i].private.p_pulse_gen[j].pulse_id == pulse_id)
{
taskENTER_CRITICAL();
pulse_gen_hw[i].private.p_pulse_gen[j].VAxH = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[j].VBxH = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[j].VAxL = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[j].VBxL = 0xFFFFFFFF;
taskEXIT_CRITICAL();
}
}
}
}
void cpg11_pulse_resume_by_pulse_id(uint32_t pulse_id)
{
for (uint32_t i = 0; i < COUNTOF(pulse_gen_hw); i++)
{
for (uint32_t j = 0; j < pulse_gen_hw[i].private.len; j++)
{
if (pulse_gen_hw[i].private.p_pulse_gen[j].pulse_id == pulse_id)
{
taskENTER_CRITICAL();
pulse_gen_hw[i].private.p_pulse_gen[j].VAxH = pulse_gen_hw[i].p_pulse_gen[j].VAxH;
pulse_gen_hw[i].private.p_pulse_gen[j].VBxH = pulse_gen_hw[i].p_pulse_gen[j].VBxH;
pulse_gen_hw[i].private.p_pulse_gen[j].VAxL = pulse_gen_hw[i].p_pulse_gen[j].VAxL;
pulse_gen_hw[i].private.p_pulse_gen[j].VBxL = pulse_gen_hw[i].p_pulse_gen[j].VBxL;
taskEXIT_CRITICAL();
}
}
}
}
void cpg11_pulse_stop(uint32_t hw_idx)
{
pulse_gen_hw[hw_idx].TMR_B->TASKS_STOP = 1;
pulse_gen_hw[hw_idx].TMR_A->TASKS_STOP = 1;
sd_nvic_DisableIRQ(pulse_gen_hw[hw_idx].IRQn);
sd_nvic_ClearPendingIRQ(pulse_gen_hw[hw_idx].IRQn);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[0]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[1]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[2]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[3]);
}
void cpg11_pulse_start(uint32_t hw_idx, pulse_gen_t *p_pulse_gen)
{
pulse_gen_hw[hw_idx].TMR_B->TASKS_STOP = 1;
pulse_gen_hw[hw_idx].TMR_A->TASKS_STOP = 1;
sd_nvic_DisableIRQ(pulse_gen_hw[hw_idx].IRQn);
sd_nvic_ClearPendingIRQ(pulse_gen_hw[hw_idx].IRQn);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[0]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[1]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[2]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[3]);
nrf_gpiote_task_configure(pulse_gen_hw[hw_idx].gpiote_idx[0], p_pulse_gen->VAxH, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_configure(pulse_gen_hw[hw_idx].gpiote_idx[1], p_pulse_gen->VBxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_configure(pulse_gen_hw[hw_idx].gpiote_idx[2], p_pulse_gen->VBxH, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_configure(pulse_gen_hw[hw_idx].gpiote_idx[3], p_pulse_gen->VAxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_enable(pulse_gen_hw[hw_idx].gpiote_idx[0]);
nrf_gpiote_task_enable(pulse_gen_hw[hw_idx].gpiote_idx[1]);
nrf_gpiote_task_enable(pulse_gen_hw[hw_idx].gpiote_idx[2]);
nrf_gpiote_task_enable(pulse_gen_hw[hw_idx].gpiote_idx[3]);
uint32_t offs = 8 * hw_idx;
NRF_PPI->CH[offs + 0].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[0];
NRF_PPI->CH[offs + 0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[0]];
NRF_PPI->CHENSET = (1 << (offs + 0));
NRF_PPI->CH[offs + 1].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[1];
NRF_PPI->CH[offs + 1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[1]];
NRF_PPI->CHENSET = (1 << (offs + 1));
NRF_PPI->CH[offs + 2].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[2];
NRF_PPI->CH[offs + 2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[1]];
NRF_PPI->CHENSET = (1 << (offs + 2));
NRF_PPI->CH[offs + 3].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[3];
NRF_PPI->CH[offs + 3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[0]];
NRF_PPI->FORK[offs + 3].TEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_B->TASKS_START;
NRF_PPI->CHENSET = (1 << (offs + 3));
NRF_PPI->CH[offs + 4].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[0];
NRF_PPI->CH[offs + 4].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[2]];
NRF_PPI->CHENSET = (1 << (offs + 4));
NRF_PPI->CH[offs + 5].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[1];
NRF_PPI->CH[offs + 5].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[3]];
NRF_PPI->CHENSET = (1 << (offs + 5));
NRF_PPI->CH[offs + 6].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[2];
NRF_PPI->CH[offs + 6].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[3]];
NRF_PPI->CHENSET = (1 << (offs + 6));
NRF_PPI->CH[offs + 7].EEP = (uint32_t)&pulse_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[3];
NRF_PPI->CH[offs + 7].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw[hw_idx].gpiote_idx[2]];
NRF_PPI->CHENSET = (1 << (offs + 7));
pulse_gen_hw[hw_idx].TMR_B->TASKS_CLEAR = 1;
pulse_gen_hw[hw_idx].TMR_A->TASKS_CLEAR = 1;
pulse_gen_hw[hw_idx].TMR_B->CC[0] = 1 + p_pulse_gen->point_us[3] * 16;
pulse_gen_hw[hw_idx].TMR_B->CC[1] = pulse_gen_hw[hw_idx].TMR_B->CC[0] + p_pulse_gen->point_us[4] * 16;
pulse_gen_hw[hw_idx].TMR_B->CC[2] = pulse_gen_hw[hw_idx].TMR_B->CC[1] + p_pulse_gen->point_us[5] * 16;
pulse_gen_hw[hw_idx].TMR_B->CC[3] = pulse_gen_hw[hw_idx].TMR_B->CC[2] + p_pulse_gen->point_us[6] * 16;
pulse_gen_hw[hw_idx].TMR_B->CC[4] = pulse_gen_hw[hw_idx].TMR_B->CC[3] + p_pulse_gen->idle_us * 16;
pulse_gen_hw[hw_idx].TMR_B->SHORTS = NRF_TIMER_SHORT_COMPARE4_STOP_MASK | NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK;
pulse_gen_hw[hw_idx].TMR_B->INTENSET = NRF_TIMER_INT_COMPARE4_MASK;
pulse_gen_hw[hw_idx].TMR_A->CC[0] = 1;
pulse_gen_hw[hw_idx].TMR_A->CC[1] = pulse_gen_hw[hw_idx].TMR_A->CC[0] + p_pulse_gen->point_us[0] * 16;
pulse_gen_hw[hw_idx].TMR_A->CC[2] = pulse_gen_hw[hw_idx].TMR_A->CC[1] + p_pulse_gen->point_us[1] * 16;
pulse_gen_hw[hw_idx].TMR_A->CC[3] = pulse_gen_hw[hw_idx].TMR_A->CC[2] + p_pulse_gen->point_us[2] * 16;
pulse_gen_hw[hw_idx].TMR_A->SHORTS = NRF_TIMER_SHORT_COMPARE3_STOP_MASK | NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK;
sd_nvic_EnableIRQ(pulse_gen_hw[hw_idx].IRQn);
pulse_gen_hw[hw_idx].TMR_A->TASKS_START = 1;
}
void cpg11_pulse_init(uint32_t hw_idx, pulse_gen_t *p_pulse_gen, uint32_t len)
{
taskENTER_CRITICAL();
if (pulse_gen_hw[hw_idx].private.p_pulse_gen != NULL)
{
pulse_gen_hw[hw_idx].TMR_B->TASKS_STOP = 1;
pulse_gen_hw[hw_idx].TMR_A->TASKS_STOP = 1;
sd_nvic_DisableIRQ(pulse_gen_hw[hw_idx].IRQn);
sd_nvic_ClearPendingIRQ(pulse_gen_hw[hw_idx].IRQn);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[0]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[1]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[2]);
nrf_gpiote_task_disable(pulse_gen_hw[hw_idx].gpiote_idx[3]);
vPortFree(pulse_gen_hw[hw_idx].private.p_pulse_gen);
}
pulse_gen_hw[hw_idx].p_pulse_gen = p_pulse_gen;
pulse_gen_hw[hw_idx].private.len = len;
pulse_gen_hw[hw_idx].private.select = 0;
pulse_gen_hw[hw_idx].private.p_pulse_gen = pvPortMalloc(sizeof(pulse_gen_t) * len);
memcpy(pulse_gen_hw[hw_idx].private.p_pulse_gen, pulse_gen_hw[hw_idx].p_pulse_gen, sizeof(*p_pulse_gen) * len);
taskEXIT_CRITICAL();
};
void cpg_pulse_default_demo_ext(void)
{
bool e1 = 1;
bool e2 = 1;
bool e3 = 1;
bool e4 = 1;
pulse_gen_t p_pulse_genA[2];
pulse_gen_t p_pulse_genB[2];
p_pulse_genA[0] = (pulse_gen_t) {
.VBxH = VB1H_PIN,
.VBxL = VB1L_PIN,
.VAxH = VA1H_PIN,
.VAxL = VA1L_PIN,
.point_us[0] = 1,
.point_us[1] = 50,
.point_us[2] = 1,
.point_us[3] = 0,
.point_us[4] = 1,
.point_us[5] = 50,
.point_us[6] = 1,
.idle_us = 1000,
.pulse_cnt = UINT32_MAX,
.pulse_id = PULSE_ID_A,
};
p_pulse_genA[1] = (pulse_gen_t) {
.VBxH = VB2H_PIN,
.VBxL = VB2L_PIN,
.VAxH = VA2H_PIN,
.VAxL = VA2L_PIN,
.point_us[0] = 1,
.point_us[1] = 50,
.point_us[2] = 1,
.point_us[3] = 0,
.point_us[4] = 1,
.point_us[5] = 50,
.point_us[6] = 1,
.idle_us = 1000,
.pulse_cnt = UINT32_MAX,
.pulse_id = PULSE_ID_B,
};
p_pulse_genB[0] = (pulse_gen_t) {
.VBxH = VB3H_PIN,
.VBxL = VB3L_PIN,
.VAxH = VA3H_PIN,
.VAxL = VA3L_PIN,
.point_us[0] = 1,
.point_us[1] = 50,
.point_us[2] = 1,
.point_us[3] = 0,
.point_us[4] = 1,
.point_us[5] = 50,
.point_us[6] = 1,
.idle_us = 1000,
.pulse_cnt = UINT32_MAX,
.pulse_id = PULSE_ID_C,
};
p_pulse_genB[1] = (pulse_gen_t) {
.VBxH = VB4H_PIN,
.VBxL = VB4L_PIN,
.VAxH = VA4H_PIN,
.VAxL = VA4L_PIN,
.point_us[0] = 1,
.point_us[1] = 50,
.point_us[2] = 1,
.point_us[3] = 0,
.point_us[4] = 1,
.point_us[5] = 50,
.point_us[6] = 1,
.idle_us = 1000,
.pulse_cnt = UINT32_MAX,
.pulse_id = PULSE_ID_B,
};
if(e1)
{
nrf_gpio_pin_clear(p_pulse_genA[0].VBxL);
nrf_gpio_pin_clear(p_pulse_genA[0].VBxH);
nrf_gpio_pin_clear(p_pulse_genA[0].VAxL);
nrf_gpio_pin_clear(p_pulse_genA[0].VAxH);
}
if(e2)
{
nrf_gpio_pin_clear(p_pulse_genA[1].VBxL);
nrf_gpio_pin_clear(p_pulse_genA[1].VBxH);
nrf_gpio_pin_clear(p_pulse_genA[1].VAxL);
nrf_gpio_pin_clear(p_pulse_genA[1].VAxH);
}
if(e3)
{
nrf_gpio_pin_clear(p_pulse_genB[0].VBxL);
nrf_gpio_pin_clear(p_pulse_genB[0].VBxH);
nrf_gpio_pin_clear(p_pulse_genB[0].VAxL);
nrf_gpio_pin_clear(p_pulse_genB[0].VAxH);
}
if(e4)
{
nrf_gpio_pin_clear(p_pulse_genB[1].VBxL);
nrf_gpio_pin_clear(p_pulse_genB[1].VBxH);
nrf_gpio_pin_clear(p_pulse_genB[1].VAxL);
nrf_gpio_pin_clear(p_pulse_genB[1].VAxH);
}
if (e1 && e2)
{
cpg11_pulse_init(0, p_pulse_genA, 2);
cpg11_pulse_start(0, p_pulse_genA);
}
else if (e1 && e2==0)
{
cpg11_pulse_init(0, p_pulse_genA, 1);
cpg11_pulse_start(0, p_pulse_genA);
}
else if (e2 && e1==0)
{
cpg11_pulse_init(0, &p_pulse_genA[1], 1);
cpg11_pulse_start(0, &p_pulse_genA[1]);
}
if (e3 && e4)
{
cpg11_pulse_init(1, p_pulse_genB, 2);
cpg11_pulse_start(1, p_pulse_genB);
}
else if (e3 && e4==0)
{
cpg11_pulse_init(1, p_pulse_genB, 1);
cpg11_pulse_start(1, p_pulse_genB);
}
else if (e4 && e3==0)
{
cpg11_pulse_init(1, &p_pulse_genB[1], 1);
cpg11_pulse_start(1, &p_pulse_genB[1]);
}
}
void cpg11_io_init(void)
{
const uint32_t pel_pins_default_high[] = {
LED_R_PIN,
LED_G_PIN,
CS_MEM_PIN,
ADPT_CLR_PIN
};
const uint32_t pel_pins_default_low[] = {
LED_B_PIN,
TW_SCKI_0_PIN,
TW_SCKI_1_PIN,
ADPT_CLK_PIN,
HV_EN_PIN,
SPIM_CLK_PIN,
SPIM_MOSI_PIN,
SPIM_MISO_PIN,
ADPT_LE_PIN,
ADPT0_S4_PIN,
ADPT0_S3_PIN,
ADPT0_S2_PIN,
ADPT0_S1_PIN,
ADPT1_S4_PIN,
ADPT1_S3_PIN,
ADPT1_S2_PIN,
ADPT1_S1_PIN,
VB1L_PIN,
VB1H_PIN,
VA1L_PIN,
VA1H_PIN,
VB2L_PIN,
VB2H_PIN,
VA2L_PIN,
VA2H_PIN,
VB3L_PIN,
VB3H_PIN,
VA3L_PIN,
VA3H_PIN,
VB4L_PIN,
VB4H_PIN,
VA4L_PIN,
VA4H_PIN,
};
for (int i = 0; i < COUNTOF(pel_pins_default_high); i++)
{
nrf_gpio_cfg_output(pel_pins_default_high[i]);
nrf_gpio_pin_set(pel_pins_default_high[i]);
}
for (int i = 0; i < COUNTOF(pel_pins_default_low); i++)
{
nrf_gpio_cfg_output(pel_pins_default_low[i]);
nrf_gpio_pin_clear(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);
for (uint32_t i = 0; i < COUNTOF(pulse_gen_hw); i++)
{
pulse_gen_hw[i].TMR_B->PRESCALER = NRF_TIMER_FREQ_16MHz;
pulse_gen_hw[i].TMR_B->MODE = NRF_TIMER_MODE_TIMER;
pulse_gen_hw[i].TMR_B->BITMODE = NRF_TIMER_BIT_WIDTH_32;
pulse_gen_hw[i].TMR_A->PRESCALER = NRF_TIMER_FREQ_16MHz;
pulse_gen_hw[i].TMR_A->MODE = NRF_TIMER_MODE_TIMER;
pulse_gen_hw[i].TMR_A->BITMODE = NRF_TIMER_BIT_WIDTH_32;
sd_nvic_SetPriority(pulse_gen_hw[i].IRQn, _PRIO_APP_HIGH);
}
for (int i = 0; i < 2; i++)
{
pulse_gen_hw[i].p_pulse_gen[0].VAxH = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[0].VBxH = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[0].VAxL = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[0].VBxL = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[1].VAxH = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[1].VBxH = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[1].VAxL = 0xFFFFFFFF;
pulse_gen_hw[i].p_pulse_gen[1].VBxL = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[0].VAxH = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[0].VBxH = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[0].VAxL = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[0].VBxL = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[1].VAxH = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[1].VBxH = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[1].VAxL = 0xFFFFFFFF;
pulse_gen_hw[i].private.p_pulse_gen[1].VBxL = 0xFFFFFFFF;
}
cpg_pulse_default_demo_ext();
}
#endif
-97
View File
@@ -1,97 +0,0 @@
#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_ELITE_CPG_V1_1)
#define UNDEF_GPIO 0xFFFFFFFF
#define VA1H_PIN NRF_GPIO_PIN_MAP(0, 22)
#define VA1L_PIN NRF_GPIO_PIN_MAP(0, 25)
#define VB1H_PIN NRF_GPIO_PIN_MAP(0, 19)
#define VB1L_PIN NRF_GPIO_PIN_MAP(0, 21)
#define VA2H_PIN NRF_GPIO_PIN_MAP(0, 17)
#define VA2L_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 ADPT_CLK_PIN NRF_GPIO_PIN_MAP(0, 11)
#define HV_EN_PIN NRF_GPIO_PIN_MAP(1, 8)
#define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 12)
#define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
#define VB2H_PIN NRF_GPIO_PIN_MAP(0, 8)
#define VB2L_PIN NRF_GPIO_PIN_MAP(0, 6)
#define VA3H_PIN NRF_GPIO_PIN_MAP(0, 5)
#define VA3L_PIN NRF_GPIO_PIN_MAP(0, 27)
#define VB3H_PIN NRF_GPIO_PIN_MAP(0, 26)
#define VB3L_PIN NRF_GPIO_PIN_MAP(0, 4)
#define VA4H_PIN NRF_GPIO_PIN_MAP(0, 1)
#define VA4L_PIN NRF_GPIO_PIN_MAP(0, 0)
#define ADPT_LE_PIN NRF_GPIO_PIN_MAP(0, 31)
#define ADPT_CLR_PIN NRF_GPIO_PIN_MAP(1, 15)
#define CS_MEM_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 ADPT0_S4_PIN NRF_GPIO_PIN_MAP(1, 12)
#define ADPT0_S3_PIN NRF_GPIO_PIN_MAP(1, 14)
#define ADPT0_S2_PIN NRF_GPIO_PIN_MAP(0, 3)
#define ADPT0_S1_PIN NRF_GPIO_PIN_MAP(1, 13)
#define ADPT1_S4_PIN NRF_GPIO_PIN_MAP(1, 3)
#define ADPT1_S3_PIN NRF_GPIO_PIN_MAP(1, 10)
#define ADPT1_S2_PIN NRF_GPIO_PIN_MAP(1, 6)
#define ADPT1_S1_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 VB4H_PIN NRF_GPIO_PIN_MAP(0, 24)
#define VB4L_PIN NRF_GPIO_PIN_MAP(0, 23)
#define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 7)
#define TW_SDI_PIN NRF_GPIO_PIN_MAP(0, 7)
#define ADPT_DIN_PIN NRF_GPIO_PIN_MAP(0, 7)
#define PULSE_ID_NULL 0
#define PULSE_ID_A 1
#define PULSE_ID_B 2
#define PULSE_ID_C 3
#define PULSE_ID_D 4
typedef struct
{
uint32_t VAxH;
uint32_t VAxL;
uint32_t VBxH;
uint32_t VBxL;
uint32_t idle_us; // min: 500us, max: 60sec
uint32_t point_us[7]; // toggle point timestamp
uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF
uint32_t pulse_id; // NO_USE_IRQ / USE_TIMER1_IRQ / USE_TIMER2_IRQ
} pulse_gen_t;
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 cpg11_io_init(void);
void cpg11_pulse_init(uint32_t hw_idx, pulse_gen_t *p_pulse_gen, uint32_t len);
void cpg11_pulse_start(uint32_t idx, pulse_gen_t *p_pulse_gen);
void cpg11_pulse_stop(uint32_t hw_idx);
void cpg11_pulse_suspend_by_pulse_id(uint32_t pulse_id);
void cpg11_pulse_resume_by_pulse_id(uint32_t pulse_id);
#endif /* ! DEF_ELITE_MODEL */
#ifdef __cplusplus
}
#endif
#endif /* ! __CPG10_IO_H__ */
-48
View File
@@ -1,48 +0,0 @@
#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 */
-61
View File
@@ -1,61 +0,0 @@
#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__ */
-30
View File
@@ -1,30 +0,0 @@
#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__ */
-142
View File
@@ -1,142 +0,0 @@
#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__ */
-1014
View File
File diff suppressed because it is too large Load Diff
-500
View File
@@ -1,500 +0,0 @@
#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_V2_0)
#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
View File
@@ -1,721 +0,0 @@
#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_V2_0)
//==========================================================
// 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, &reg_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, &reg_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
View File
@@ -1,98 +0,0 @@
#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__ */
+261
View File
@@ -0,0 +1,261 @@
#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 edc_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 edc_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_edc_regular_data_observer, 3, edc_regular_data_handler, NULL);
}
-16
View File
@@ -1,16 +0,0 @@
#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__ */
-127
View File
@@ -1,127 +0,0 @@
#include "elite.h"
#if (DEF_ELITE_MODEL == DEF_ELITE_DEV)
#include "elite_dev.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_V2_0)
#include "edc.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
#include "pel.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
#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_V2_0)
edc.init();
p_instance = edc.p_elite_instance;
#elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
p_instance = pel_init();
#elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
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);
}
-23
View File
@@ -1,23 +0,0 @@
#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__ */
-8
View File
@@ -1,8 +0,0 @@
#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
View File
@@ -1,19 +0,0 @@
#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__ */
-57
View File
@@ -1,57 +0,0 @@
#include "elite_board.h"
void elite_board_init(void)
{
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_V2_0)
edc20_io_init();
#elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
pel20_io_init();
#elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
cpg11_io_init();
#endif
}
void elite_board_power_off(void)
{
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_V2_0)
edc20_io_power_off();
#elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
#elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
#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 */
}
-36
View File
@@ -1,36 +0,0 @@
#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_V2_0)
#include "edc20_io.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
#include "pel20_io.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1)
#include "cpg11_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
View File
File diff suppressed because it is too large Load Diff
-36
View File
@@ -1,36 +0,0 @@
#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
View File
@@ -1,55 +0,0 @@
#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
View File
@@ -1,28 +0,0 @@
#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
View File
@@ -1,120 +0,0 @@
#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
View File
@@ -1,260 +0,0 @@
#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
View File
@@ -1,17 +0,0 @@
#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__ */
-205
View File
@@ -1,205 +0,0 @@
#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 */
-42
View File
@@ -1,42 +0,0 @@
#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
View File
@@ -1,275 +0,0 @@
#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 *)&rx;
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 *)&rx;
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
View File
@@ -1,22 +0,0 @@
#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__ */
+159
View File
@@ -0,0 +1,159 @@
#include "nrf_drv_twi.h"
#include "nrf_gpio.h"
#include "nrf_log.h"
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
#include "task.h"
#define I2C_SDA NRF_GPIO_PIN_MAP(0, 11)
#define I2C_SCL NRF_GPIO_PIN_MAP(0, 2)
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;
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);
}
static void virtual_data(uint8_t *p_rx_buf, uint8_t rx_buffer_length)
{
uint8_t virtual_data_buff[20] = { 9, 8, 7, 6, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
if (rx_buffer_length == 0)
return;
memcpy(p_rx_buf, virtual_data_buff, rx_buffer_length);
}
void twi0_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t data_len);
void twi0_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 = I2C_SCL,
.sda = I2C_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, &reg_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, sizeof(i2c_buf));
}
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, &reg_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);
}
-23
View File
@@ -1,23 +0,0 @@
#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
+17 -30
View File
@@ -31,13 +31,6 @@ 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)
@@ -66,39 +59,33 @@ 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
{
uint8_t company_code[2];
uint8_t hw_ver[4];
uint8_t build_time[2];
uint8_t bat_str[3];
const uint8_t company_code[5];
const uint8_t hw_ver[4];
uint16_t bat_volt;
} __PACKED data = {
.hw_ver = ELITE_HW_VER,
.build_time = {24, 01},
.bat_str = "BAT",
.bat_volt = 0x0C1C,
.company_code = ELITE_COMPANY_CODE,
.hw_ver = ELITE_HW_VER,
.bat_volt = 100,
};
ble_advdata_manuf_data_t manuf_specific_data;
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;
ble_advdata_manuf_data_t manuf_specific_data; // Advertising Data: add manuf_specific_data = FF FF 45 6C 69 74 65 00 04 01 01 1C 0C
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;
init.config.ble_adv_fast_enabled = true;
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.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.evt_handler = le_adv_evt_handler;
init.error_handler = le_adv_error_handler;
+728
View File
@@ -0,0 +1,728 @@
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(BLE_EDC)
#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_EDC_BASE_UUID \
{ \
{ \
0x4D, 0x3C, 0x56, 0x45, 0x12, 0x8B, 0x44, 0x1D, 0x8D, 0x6F, 0xC5, 0x95, 0x00, 0x00, 0x9B, 0xD8 \
} \
}
#define BLE_UUID_EDC_SERVICE 0x0001
#define BLE_UUID_EDC_BAT_VOLT_CHAR 0x0002
#define BLE_UUID_EDC_LOW_FREQ_DATA_CHAR 0x0003
#define BLE_UUID_EDC_AUXILIARY_DATA_CHAR 0x0004
#define BLE_UUID_EDC_STATUS_CHAR 0x0005
#define BLE_UUID_EDC_EVENT_CHAR 0x0006
#define BLE_UUID_EDC_INSTRUCTION_CHAR 0x0007
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;
ble_gatts_char_handles_t instruction_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;
uint8_t instruction[20];
} ble_edc_t;
typedef struct
{
uint16_t dummy;
} ble_edc_init_t;
static ble_edc_t ble_edc = {
.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_edc_t *p_edc, ble_evt_t const *p_ble_evt)
{
p_edc->conn_handle = p_ble_evt->evt.common_evt.conn_handle;
}
static void on_disconnect(ble_edc_t *p_edc, ble_evt_t const *p_ble_evt)
{
p_edc->conn_handle = BLE_CONN_HANDLE_INVALID;
p_edc->regular_data_notify_enable = false;
p_edc->low_freq_data_notify_enable = false;
p_edc->auxiliary_data_notify_enable = false;
p_edc->status_notify_enable = false;
p_edc->event_notify_enable = false;
}
static void edc_ccc_update(ble_edc_t *p_edc, 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_edc->regular_data_handles.cccd_handle)
{
p_edc->regular_data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
NRF_LOG_INFO("regular_data_notify:%s", p_edc->regular_data_notify_enable ? "enable" : "disable");
return;
}
else if (p_evt_write->handle == p_edc->low_freq_data_handles.cccd_handle)
{
p_edc->low_freq_data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
NRF_LOG_INFO("low_freq_data_notify:%s", p_edc->low_freq_data_notify_enable ? "enable" : "disable");
return;
}
else if (p_evt_write->handle == p_edc->auxiliary_data_handles.cccd_handle)
{
p_edc->auxiliary_data_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
NRF_LOG_INFO("auxiliary_data_notify:%s", p_edc->auxiliary_data_notify_enable ? "enable" : "disable");
return;
}
else if (p_evt_write->handle == p_edc->status_handles.cccd_handle)
{
p_edc->status_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
NRF_LOG_INFO("status_notify:%s", p_edc->status_notify_enable ? "enable" : "disable");
return;
}
else if (p_evt_write->handle == p_edc->event_handles.cccd_handle)
{
p_edc->event_notify_enable = ble_srv_is_notification_enabled(p_evt_write->data);
NRF_LOG_INFO("event_notify:%s", p_edc->event_notify_enable ? "enable" : "disable");
return;
}
}
void instruction_char_reply(uint8_t *reply, uint32_t reply_len)
{
// update database.
ble_gatts_value_t gatts_value = {
.p_value = reply,
.offset = 0,
.len = reply_len,
};
ret_code_t err_code = sd_ble_gatts_value_set(BLE_CONN_HANDLE_INVALID, ble_edc.instruction_handles.value_handle, &gatts_value);
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("reply[gatt]");
NRF_LOG_HEXDUMP_INFO(reply, reply_len);
}
#include "led.h"
static void tool_change_led(uint8_t *instru_received)
{
// instruction: 0x3xxxFF01ccll
// ps. ll = brightness
// ps. cc = 00 | 01 | 02 | 03 | 04 | 05 |
// LED_NONE | LED_RED | LED_GREEN | LED_CYAN | LED_BLUE | LED_PURPLE |
struct led_color color;
uint8_t brightness = *(instru_received + 5);
uint8_t reply[20] = { 0 };
switch (*(instru_received + 4))
{
case 0x00:
color = LED_NONE;
memcpy(reply, "LED_NONE", sizeof("LED_NONE"));
NRF_LOG_INFO("LED_NONE(%d)", brightness);
break;
case 0x01:
color = LED_RED;
memcpy(reply, "LED_RED", sizeof("LED_RED"));
NRF_LOG_INFO("LED_RED(%d)", brightness);
break;
case 0x02:
color = LED_GREEN;
memcpy(reply, "LED_GREEN", sizeof("LED_GREEN"));
NRF_LOG_INFO("LED_GREEN(%d)", brightness);
break;
case 0x03:
color = LED_CYAN;
memcpy(reply, "LED_CYAN", sizeof("LED_CYAN"));
NRF_LOG_INFO("LED_CYAN(%d)", brightness);
break;
case 0x04:
color = LED_BLUE;
memcpy(reply, "LED_BLUE", sizeof("LED_BLUE"));
NRF_LOG_INFO("LED_BLUE(%d)", brightness);
break;
case 0x05:
color = LED_PURPLE;
memcpy(reply, "LED_PURPLE", sizeof("LED_PURPLE"));
NRF_LOG_INFO("LED_PURPLE(%d)", brightness);
break;
default:
memcpy(reply, "Wrong...", sizeof("Wrong..."));
NRF_LOG_INFO("Wrong...");
break;
}
for (int i = 0; i < 12; i++)
{
led_set(i, color, brightness);
}
instruction_char_reply(reply, sizeof(reply));
}
#include "nrf_gpio.h"
static void tool_gpio_output(uint8_t *instru_received)
{
// tool_gpio_output()
// instruction: 0x3xxxFFA0ppnnss
// ps. pp = 00 | 01 |
// part0 | part1 |
// ps. nn = 0x00 ~ 0x31
// ps. ss = 00 | 01 |
// low | hihg |
uint16_t pin_number_user = *(instru_received + 4) << 8 | *(instru_received + 5);
uint8_t pin_signal = *(instru_received + 6);
uint8_t reply[20] = { 0 };
uint32_t pin;
switch (pin_number_user)
{
case 0x0015:
pin = NRF_GPIO_PIN_MAP(0, 15);
break;
case 0x0020: // special pin for BMD380 EVK
pin = NRF_GPIO_PIN_MAP(0, 20);
break;
case 0x0008:
pin = NRF_GPIO_PIN_MAP(0, 8);
break;
case 0x0006:
pin = NRF_GPIO_PIN_MAP(0, 6);
break;
case 0x0005:
pin = NRF_GPIO_PIN_MAP(0, 5);
break;
case 0x0025:
pin = NRF_GPIO_PIN_MAP(0, 25);
break;
case 0x0019: // special pin for BMD380 EVK
pin = NRF_GPIO_PIN_MAP(0, 19);
break;
case 0x0021: // special pin for BMD380 EVK
pin = NRF_GPIO_PIN_MAP(0, 21);
break;
case 0x0017: // special pin for BMD380 EVK
pin = NRF_GPIO_PIN_MAP(0, 17);
break;
case 0x0026:
pin = NRF_GPIO_PIN_MAP(0, 26);
break;
case 0x0004:
pin = NRF_GPIO_PIN_MAP(0, 4);
break;
case 0x0112:
pin = NRF_GPIO_PIN_MAP(1, 12);
break;
case 0x0114:
pin = NRF_GPIO_PIN_MAP(1, 14);
break;
case 0x0113:
pin = NRF_GPIO_PIN_MAP(1, 13);
break;
case 0x0103:
pin = NRF_GPIO_PIN_MAP(1, 3);
break;
case 0x0110:
pin = NRF_GPIO_PIN_MAP(1, 10);
break;
case 0x0106:
pin = NRF_GPIO_PIN_MAP(1, 6);
break;
case 0x0111:
pin = NRF_GPIO_PIN_MAP(1, 11);
break;
case 0x0016:
pin = NRF_GPIO_PIN_MAP(0, 16);
break;
default:
memcpy(reply, "Wrong...", sizeof("Wrong..."));
NRF_LOG_INFO("Wrong...");
instruction_char_reply(reply, sizeof(reply));
return;
break;
}
if (pin_signal == 0)
{
nrf_gpio_pin_clear(pin);
memset(reply, (pin_number_user & 0xFF00) >> 8, 1);
memset(reply + 1, (pin_number_user & 0x00FF), 1);
memset(reply + 2, pin_signal, 1);
NRF_LOG_INFO("tool_gpio_output(): P%X.%02X(%d)", (pin_number_user & 0xFF00) >> 8, pin_number_user & 0x00FF, pin_signal);
}
else if (pin_signal == 1)
{
nrf_gpio_pin_set(pin);
memset(reply, (pin_number_user & 0xFF00) >> 8, 1);
memset(reply + 1, (pin_number_user & 0x00FF), 1);
memset(reply + 2, pin_signal, 1);
NRF_LOG_INFO("tool_gpio_output(): P%X.%02X(%d)", (pin_number_user & 0xFF00) >> 8, pin_number_user & 0x00FF, pin_signal);
}
else
{
memcpy(reply, "Wrong...", sizeof("Wrong..."));
NRF_LOG_INFO("Wrong...");
}
instruction_char_reply(reply, sizeof(reply));
}
static void tool_gpio_input(uint8_t *instru_received)
{
// tool_gpio_input()
// instruction: 0x3xxxFFA1ppnn
// ps. pp = 00 | 01 |
// part0 | part1 |
// ps. nn = 0x00 ~ 0x31
uint16_t pin_number_user = *(instru_received + 4) << 8 | *(instru_received + 5);
uint8_t reply[20] = { 0 };
uint32_t pin;
uint32_t pin_signal;
switch (pin_number_user)
{
case 0x0003:
pin = NRF_GPIO_PIN_MAP(0, 3);
break;
case 0x0027:
pin = NRF_GPIO_PIN_MAP(0, 27);
break;
case 0x0108:
pin = NRF_GPIO_PIN_MAP(1, 8);
break;
default:
memcpy(reply, "Wrong...", sizeof("Wrong..."));
NRF_LOG_INFO("Wrong...");
instruction_char_reply(reply, sizeof(reply));
return;
break;
}
pin_signal = nrf_gpio_pin_read(pin);
memset(reply, (pin_number_user & 0xFF00) >> 8, 1);
memset(reply + 1, (pin_number_user & 0x00FF), 1);
memset(reply + 2, pin_signal, 1);
NRF_LOG_INFO("tool_gpio_input(): P%X.%02X(%d)", (pin_number_user & 0xFF00) >> 8, pin_number_user & 0x00FF, pin_signal);
instruction_char_reply(reply, sizeof(reply));
}
extern void spi2_write(uint32_t cs_pin, uint8_t *p_tx_buffer, uint8_t tx_buffer_length, uint8_t *p_rx_buf, uint8_t rx_buffer_length);
#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)
static void tool_spi2(uint8_t *instru_received)
{
// tool_spi2()
// instruction: 0x3xxxFFA2ssttrrcccccc......
// ps. ss = selector
// | 00 | 01 | 02 | 03 |
// | SW | MEM | ADC | DAC |
// ps. tt = tx length
// ps. rr = rx length
// ps. cc = tx content
uint8_t chip_seletor = *(instru_received + 4);
uint8_t tx_buffer_len = *(instru_received + 5);
uint8_t rx_buffer_len = *(instru_received + 6);
uint8_t tx_buffer[tx_buffer_len];
uint8_t rx_buffer[rx_buffer_len];
uint8_t reply[20] = { 0 };
memcpy(tx_buffer, instru_received + 7, tx_buffer_len);
switch (chip_seletor)
{
case 0x00:
NRF_LOG_INFO("tool_spi2(): CS_SW");
spi2_write(CS_SW_PIN, tx_buffer, tx_buffer_len, rx_buffer, rx_buffer_len);
break;
case 0x01:
NRF_LOG_INFO("tool_spi2(): CS_MEM_PIN");
spi2_write(CS_MEM_PIN, tx_buffer, tx_buffer_len, rx_buffer, rx_buffer_len);
break;
case 0x02:
NRF_LOG_INFO("tool_spi2(): CS_ADC_PIN");
spi2_write(CS_ADC_PIN, tx_buffer, tx_buffer_len, rx_buffer, rx_buffer_len);
break;
case 0x03:
NRF_LOG_INFO("tool_spi2(): CS_DAC_PIN");
spi2_write(CS_DAC_PIN, tx_buffer, tx_buffer_len, rx_buffer, rx_buffer_len);
break;
default:
memcpy(reply, "Wrong...", sizeof("Wrong..."));
NRF_LOG_INFO("Wrong...");
instruction_char_reply(reply, sizeof(reply));
return;
break;
}
if (rx_buffer_len == 0)
{
instruction_char_reply(reply, sizeof(reply));
}
else
{
memcpy(reply, rx_buffer, rx_buffer_len);
instruction_char_reply(reply, sizeof(reply));
}
}
extern void twi0_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t data_len);
extern void twi0_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_rx_buf, uint8_t rx_buffer_length);
static void tool_i2c0(uint8_t *instru_received)
{
// tool_i2c0()
// instruction: 0x3xxxFFA3aaggttrrcccccc......
// ps. aa = slave address
// ps. gg = reg address
// ps. tt = tx length
// ps. rr = rx length
// ps. cc = tx content
NRF_LOG_INFO("tool_i2c0()");
uint8_t slave_addr = *(instru_received + 4);
uint8_t reg_addr = *(instru_received + 5);
uint8_t tx_buffer_len = *(instru_received + 6);
uint8_t rx_buffer_len = *(instru_received + 7);
uint8_t tx_buffer[tx_buffer_len];
uint8_t rx_buffer[rx_buffer_len];
uint8_t reply[20] = { 0 };
memcpy(tx_buffer, instru_received + 8, tx_buffer_len);
if (rx_buffer_len == 0)
{
twi0_write_reg(slave_addr, reg_addr, tx_buffer, tx_buffer_len);
instruction_char_reply(reply, sizeof(reply));
}
else
{
twi0_write_reg(slave_addr, reg_addr, tx_buffer, tx_buffer_len);
twi0_read_reg(slave_addr, reg_addr, rx_buffer, rx_buffer_len);
memcpy(reply, rx_buffer, rx_buffer_len);
instruction_char_reply(reply, sizeof(reply));
}
}
static void decode_instruction(uint8_t *instru_received)
{
uint32_t func = *(instru_received + 2);
switch (func)
{
case 0xFF: // tool 0x3xxxFF......
switch (*(instru_received + 3))
{
case 0x01: // instruction: 0x3xxxFF01ccll 3000FF010101
tool_change_led(instru_received);
break;
case 0xA0: // instruction: 0x3xxxFFA0ppnnss 3000FFA0011301
tool_gpio_output(instru_received);
break;
case 0xA1: // instruction: 0x3xxxFFA1ppnn 3000FFA10108
tool_gpio_input(instru_received);
break;
case 0xA2: // instruction: 0x3xxxFFA2ssttrrcccccc...... 3000FFA2010301112233
tool_spi2(instru_received);
break;
case 0xA3: // instruction: 0x3xxxFFA3aaggttrrcccccc...... 3000FFA3519902037788
tool_i2c0(instru_received);
break;
}
break;
}
}
static void on_write(ble_edc_t *p_edc, 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;
NRF_LOG_INFO("@ble on_write[gatt]: ble uuid=0x%02x, handle=0x%02x", uuid.uuid, handle);
switch (uuid.uuid)
{
case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
NRF_LOG_INFO("uuid.uuid=BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG");
edc_ccc_update(p_edc, p_ble_evt);
break;
case BLE_UUID_CHARACTERISTIC:
NRF_LOG_INFO("uuid.uuid=BLE_UUID_CHARACTERISTIC");
break;
case BLE_UUID_EDC_INSTRUCTION_CHAR: {
ble_gatts_evt_write_t const *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
NRF_LOG_INFO("uuid.uuid=BLE_UUID_EDC_INSTRUCTION_CHAR");
if (p_evt_write->handle == p_edc->instruction_handles.value_handle)
{
memcpy(p_edc->instruction, p_evt_write->data, p_evt_write->len);
NRF_LOG_INFO("p_edc->instruction[0:%d]=", p_evt_write->len - 1);
NRF_LOG_HEXDUMP_INFO(p_edc->instruction, p_evt_write->len);
decode_instruction(p_edc->instruction);
}
}
break;
default:
break;
}
}
static void on_hvx_tx_complete(ble_edc_t *p_edc, ble_evt_t const *p_ble_evt)
{
}
static void ble_edc_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
ble_edc_t *p_edc = (ble_edc_t *)p_context;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
on_connect(p_edc, p_ble_evt);
break;
case BLE_GAP_EVT_DISCONNECTED:
on_disconnect(p_edc, p_ble_evt);
break;
case BLE_GATTS_EVT_WRITE:
on_write(p_edc, p_ble_evt);
break;
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
on_hvx_tx_complete(p_edc, 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_edc.service_handle, &add_char_params, p_handles);
return err_code;
}
static ret_code_t add_characteristic_read_write(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.write = 1;
add_char_params.write_access = SEC_OPEN;
add_char_params.char_props.read = 1;
add_char_params.read_access = SEC_OPEN;
ret_code_t err_code = characteristic_add(ble_edc.service_handle, &add_char_params, p_handles);
return err_code;
}
static uint32_t ble_edc_init(ble_edc_init_t const *p_edc_init)
{
ret_code_t err_code;
ble_uuid128_t base_uuid = BLE_EDC_BASE_UUID;
ble_uuid_t ble_uuid = {
.type = BLE_UUID_TYPE_UNKNOWN,
.uuid = BLE_UUID_EDC_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_edc.service_handle);
APP_ERROR_CHECK(err_code);
// Adding regular data characteristic to the SoftDevice
err_code = add_characteristic(BLE_UUID_EDC_BAT_VOLT_CHAR,
ble_uuid.type,
NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3,
NULL,
&ble_edc.regular_data_handles);
APP_ERROR_CHECK(err_code);
// Adding low freq data characteristic to the SoftDevice
err_code = add_characteristic(BLE_UUID_EDC_LOW_FREQ_DATA_CHAR,
ble_uuid.type,
32,
NULL,
&ble_edc.low_freq_data_handles);
APP_ERROR_CHECK(err_code);
// Adding auxiliary data characteristic to the SoftDevice
err_code = add_characteristic(BLE_UUID_EDC_AUXILIARY_DATA_CHAR,
ble_uuid.type,
32,
NULL,
&ble_edc.auxiliary_data_handles);
APP_ERROR_CHECK(err_code);
// Adding status characteristic to the SoftDevice
err_code = add_characteristic(BLE_UUID_EDC_STATUS_CHAR,
ble_uuid.type,
32,
NULL,
&ble_edc.status_handles);
APP_ERROR_CHECK(err_code);
// Adding event characteristic to the SoftDevice
err_code = add_characteristic(BLE_UUID_EDC_EVENT_CHAR,
ble_uuid.type,
32,
NULL,
&ble_edc.event_handles);
APP_ERROR_CHECK(err_code);
// Adding instruction characteristic to the SoftDevice
err_code = add_characteristic_read_write(BLE_UUID_EDC_INSTRUCTION_CHAR,
ble_uuid.type,
32,
NULL,
&ble_edc.instruction_handles);
APP_ERROR_CHECK(err_code);
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER(m_edc_observer, EDC_BLE_OBSERVER_PRIO, ble_edc_evt_handler, &ble_edc);
NRF_LOG_INFO("+------------------------+------+");
NRF_LOG_INFO("| regular_data_handles | 0x%02x |", ble_edc.regular_data_handles.value_handle);
NRF_LOG_INFO("| low_freq_data_handles | 0x%02x |", ble_edc.low_freq_data_handles.value_handle);
NRF_LOG_INFO("| auxiliary_data_handles | 0x%02x |", ble_edc.auxiliary_data_handles.value_handle);
NRF_LOG_INFO("| status_handles | 0x%02x |", ble_edc.status_handles.value_handle);
NRF_LOG_INFO("| event_handles | 0x%02x |", ble_edc.event_handles.value_handle);
NRF_LOG_INFO("| instruction_handles | 0x%02x |", ble_edc.instruction_handles.value_handle);
NRF_LOG_INFO("+------------------------+------+");
return NRF_SUCCESS;
}
void le_edc_init(void)
{
ble_edc_init_t edc_init;
memset(&edc_init, 0x00, sizeof(edc_init));
ret_code_t err_code = ble_edc_init(&edc_init);
APP_ERROR_CHECK(err_code);
extern void edc_regular_data_init(void);
edc_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_edc.regular_data_handles.value_handle, &gatts_value);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// send notify
if (ble_edc.regular_data_notify_enable)
{
ble_gatts_hvx_params_t hvx_params = {
.handle = ble_edc.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_edc.conn_handle) == BLE_CONN_STATUS_CONNECTED)
{
err_code = sd_ble_gatts_hvx(ble_edc.conn_handle, &hvx_params);
}
}
return err_code;
}
bool le_regular_data_notify_is_enable(void)
{
return ble_edc.regular_data_notify_enable;
}
#endif // NRF_MODULE_ENABLED(BLE_EDC)
-281
View File
@@ -1,281 +0,0 @@
#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)
+2 -6
View File
@@ -40,17 +40,13 @@ 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);
@@ -64,6 +60,6 @@ void le_srv_init(void)
extern void le_dfu_init(void);
le_dfu_init();
extern void le_elite_srv_init(void);
le_elite_srv_init(); // customer service
extern void le_edc_init(void);
le_edc_init(); // customer service
}
+100
View File
@@ -0,0 +1,100 @@
#include "led.h"
#include "nrf_gpio.h"
#include "nrf_log.h"
#include "nrf_spim.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#define DISP_LED_COLOR 0
#define LED_COUNT 12
typedef struct
{
uint8_t brightness : 5;
uint8_t preamble : 3;
struct led_color color;
} led_t;
led_t led[LED_COUNT];
const led_t led_default = {
.brightness = 0b00000,
.preamble = 0b111,
.color = {
.B = 0,
.G = 0,
.R = 0},
};
static void led_write(uint8_t *pucData, uint32_t ulSize)
{
extern void spi1_write(uint8_t * p_tx_buffer, uint8_t tx_buffer_length);
spi1_write(pucData, ulSize);
// for (uint32_t i = 0; i < ulSize; i++)
// {
// for (uint32_t j = 0x80; j > 0; j >>= 1)
// {
// nrf_gpio_pin_clear(LED_CLK_PIN);
// if (pucData[i] & j)
// {
// nrf_gpio_pin_set(LED_SDI_PIN);
// }
// else
// {
// nrf_gpio_pin_clear(LED_SDI_PIN);
// }
// // portYIELD();
// nrf_gpio_pin_set(LED_CLK_PIN);
// // portYIELD();
// }
// }
// nrf_gpio_pin_clear(LED_CLK_PIN);
}
void led_set(uint32_t idx, struct led_color color, uint8_t brightness)
{
uint32_t start_frame = 0x00000000;
led_write((void *)&start_frame, sizeof(start_frame));
led[idx].color = color;
led[idx].brightness = brightness;
for (int i = 0; i < LED_COUNT; i++)
{
led_write((void *)&led[i], sizeof(led[i]));
}
uint32_t end_frame = 0xFFFFFFFF;
led_write((void *)&end_frame, sizeof(end_frame));
}
void led_off(void)
{
NRF_LOG_INFO("LED_NONE");
uint32_t start_frame = 0x00000000;
led_write((void *)&start_frame, sizeof(start_frame));
for (int i = 0; i < LED_COUNT; i++)
{
led[i] = led_default;
led_write((void *)&led[i], sizeof(led[i]));
}
uint32_t end_frame = 0xFFFFFFFF;
led_write((void *)&end_frame, sizeof(end_frame));
}
void led_init(void)
{
// // led gpio init
// nrf_gpio_pin_clear(LED_CLK_PIN);
// nrf_gpio_cfg_output(LED_CLK_PIN);
// nrf_gpio_pin_clear(LED_SDI_PIN);
// nrf_gpio_cfg_output(LED_SDI_PIN);
// turn off
led_off();
}
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#ifndef __LED_H__
#define __LED_H__
#include <stdint.h>
struct led_color
{
uint8_t B;
uint8_t G;
uint8_t R;
};
#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_GREEN \
(struct led_color) { .R = 0x00, .G = 0xFF, .B = 0x00 }
#define LED_CYAN \
(struct led_color) { .R = 0x00, .G = 0xFF, .B = 0xFF } // connect to neulive
#define LED_BLUE \
(struct led_color) { .R = 0x00, .G = 0x00, .B = 0xFF } // neulive recording
#define LED_YELLOW \
(struct led_color) { .R = 0xEF, .G = 0x9F, .B = 0x00 } // neulive stimulate
#define LED_PURPLE \
(struct led_color) { .R = 0xFF, .G = 0x00, .B = 0xFF } // neulive rec + sti
#define LED_OFF LED_NONE
#define LED_ERROR LED_RED
#define LED_ON LED_GREEN
#define LED_CONNECTED LED_CYAN
#define LED_REC LED_BLUE
#define LED_STIMU LED_YELLOW
#define LED_STIMU_REC LED_PURPLE
void led_init(void);
void led_off(void);
void led_set(uint32_t idx, struct led_color color, uint8_t brightness);
#endif // !__LED_H__
-125
View File
@@ -1,125 +0,0 @@
#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 */
-97
View File
@@ -1,97 +0,0 @@
#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__ */
-29
View File
@@ -1,29 +0,0 @@
#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
View File
File diff suppressed because it is too large Load Diff
-795
View File
@@ -1,795 +0,0 @@
/*
* 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
-37
View File
@@ -1,37 +0,0 @@
/*
* 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
-261
View File
@@ -1,261 +0,0 @@
/*
* 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
+143 -10
View File
@@ -7,16 +7,26 @@ extern "C"
#endif
#include "app_config.h"
#include "elite_board.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_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"
#include "timers.h"
#include "led.h"
#ifdef __cplusplus
}
#endif
@@ -35,18 +45,18 @@ 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);
led_set(LED_IDEL_CONNECTED);
break;
case BLE_GAP_EVT_DISCONNECTED:
}
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);
led_set(LED_IDEL_DISCONNECT);
break;
}
break;
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
NRF_LOG_INFO("PHY update response. (AUTO)");
ble_gap_phys_t const phys = {
@@ -95,13 +105,132 @@ static void le_stack_Init(void)
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, le_evt_handler, NULL);
}
/* edc2.0 pin */
#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 CS_SW_PIN NRF_GPIO_PIN_MAP(0, 20)
#define OFF_PIN NRF_GPIO_PIN_MAP(0, 15)
#define SHUT_DOWN_PIN NRF_GPIO_PIN_MAP(1, 8)
#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 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 POWER_5V_EN_PIN NRF_GPIO_PIN_MAP(0, 24)
#define POWER_12V_EN_PIN NRF_GPIO_PIN_MAP(0, 23)
#define CV_CTRL_PIN NRF_GPIO_PIN_MAP(0, 16)
void gpio_init(void)
{
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);
nrf_gpio_pin_set(POWER_5V_EN_PIN);
nrf_gpio_pin_set(POWER_12V_EN_PIN);
nrf_gpio_pin_set(OFF_PIN); // disable 6994
nrf_gpio_pin_set(CS_SW_PIN);
nrf_gpio_pin_set(CS_MEM_PIN);
nrf_gpio_pin_set(CS_ADC_PIN);
nrf_gpio_pin_set(CS_DAC_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);
}
static void enable_6994_callback(void *pvParameter)
{
nrf_gpio_pin_clear(OFF_PIN); // enable 6994
NRF_LOG_INFO("enable 6994");
}
extern void twi0_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t data_len);
extern void twi0_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_rx_buf, uint8_t rx_buffer_length);
void touch_sensor_task(void *pArg)
{
/*
* pin assign:
* SDA SCL INT VDD GND
* p0.11 p0.02 p0.29 5V0 GND
*/
nrf_gpio_cfg_input(29, NRF_GPIO_PIN_NOPULL);//INT
for (;;)
{
bool button = nrf_gpio_pin_read(29);
NRF_LOG_INFO("button=%d", button);
uint8_t rx_buffer[1];
twi0_read_reg(0x50, 0x0D, rx_buffer, 1);
vTaskDelay(500);
}
}
static void nrf_sdh_freertos_task_hook(void *p_context)
{
extern void twi0_init(void);
extern void spi_init(void);
UNUSED_PARAMETER(p_context);
elite_board_init();
gpio_init();
spi_init();
twi0_init();
led_init();
elite_drv_init();
xTaskCreate(touch_sensor_task, "touch_sensor_task", 256, NULL, 3, NULL);
NRF_LOG_INFO("LED_GREEN");
for (int i = 0; i < 12; i++)
{
led_set(i, LED_GREEN, 1);
}
le_stack_Init(); // enable ble stack, but unscannable!! register "le_evt_handler" handle(CB)
@@ -116,6 +245,11 @@ static void nrf_sdh_freertos_task_hook(void *p_context)
extern void le_adv_init(uint8_t ble_conn_cfg_tag);
le_adv_init(APP_BLE_CONN_CFG_TAG); // could be scanned
/* Start timer to call enable_6994_callback() */
TimerHandle_t timer_handle; /**< Reference to counter FreeRTOS timer. */
timer_handle = xTimerCreate("enable 6994", 1000, pdFALSE, NULL, enable_6994_callback); // 1000ms no repeat
xTimerStart(timer_handle, 0);
}
int main(void)
@@ -123,7 +257,6 @@ 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__);
NRF_LOG_INFO("Elite hw ver(%d.%d.%d.%d)", MAJOR_PRODUCT_NUMBER, MINOR_PRODUCT_NUMBER, MAJOR_VERSION_NUMBER, MINOR_VERSION_NUMBER);
nrf_sdh_freertos_init(nrf_sdh_freertos_task_hook, NULL); // create event: softdevice_task - wireless protocal stack
-187
View File
@@ -1,187 +0,0 @@
#include "max14802.h"
#include "elite_board.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "string.h"
#pragma GCC optimize("O2")
#if (DEF_MAX14802_ENABLED)
static sw_t m_sw = { .val = UINT64_MAX };
#define EXCLUDE_IO_ENABLE 1
#define EXCLUDE_IO_DISABLE 0
static const uint32_t exclude_io[64] = {
ADPT0_S1_PIN,
ADPT0_S2_PIN,
ADPT0_S3_PIN,
ADPT0_S4_PIN,
ADPT1_S1_PIN,
ADPT1_S2_PIN,
ADPT1_S3_PIN,
ADPT1_S4_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
UNCONNECTED_PIN,
};
static void shift_out(uint8_t *p, uint32_t len)
{
nrf_gpio_pin_clear(ADPT_LE_PIN);
for (int32_t j = len; j > 0; j--)
{
uint32_t val = p[j - 1];
for (uint32_t i = 0x01 << (SW_PER_BYTE - 1); i > 0; i >>= 1)
{
nrf_gpio_pin_clear(ADPT_CLK_PIN);
nrf_gpio_pin_write(ADPT_DIN_PIN, val & i);
nrf_gpio_pin_set(ADPT_CLK_PIN);
nrf_gpio_pin_write(ADPT_DIN_PIN, val & i);
}
}
nrf_gpio_pin_clear(ADPT_CLK_PIN);
nrf_gpio_pin_clear(ADPT_DIN_PIN);
nrf_gpio_pin_set(ADPT_LE_PIN);
nrf_gpio_pin_clear(ADPT_LE_PIN);
}
int max14802_reset(void)
{
m_sw.val = 0;
shift_out((uint8_t *)&m_sw.val, SW_TOTAL_COUNT / SW_PER_BYTE);
return 0;
}
int max14802_write(sw_t sw_mask)
{
if (m_sw.val != sw_mask.val)
{
m_sw = sw_mask;
// Disable A1_AOUT,A2_AOUT,B1_AOUT, .... B3_AOUT, B4_AOUT
for (uint32_t i = 0; i < SW_TOTAL_COUNT; i++)
{
nrf_gpio_pin_write(exclude_io[i], EXCLUDE_IO_DISABLE);
}
// Set max14082
shift_out((uint8_t *)&m_sw.val, SW_TOTAL_COUNT / SW_PER_BYTE);
// Enable A1_AOUT,A2_AOUT,B1_AOUT, .... B3_AOUT, B4_AOUT are all disable when all max14082 off
if (m_sw.val == 0)
{
for (uint32_t i = 0; i < SW_TOTAL_COUNT; i++)
{
nrf_gpio_pin_write(exclude_io[i], EXCLUDE_IO_ENABLE);
}
}
}
return 0;
}
int max14802_read(sw_t *p_sw_mask)
{
*p_sw_mask = m_sw;
return 0;
}
int max14802_get_sw_count(uint32_t *p_sw_count)
{
*p_sw_count = SW_TOTAL_COUNT;
return 0;
}
int max14802_init(void)
{
nrf_gpio_pin_set(ADPT_CLR_PIN);
nrf_gpio_pin_clear(ADPT_LE_PIN);
nrf_gpio_pin_clear(ADPT_CLK_PIN);
nrf_gpio_pin_clear(ADPT_DIN_PIN);
nrf_gpio_cfg_output(ADPT_CLR_PIN);
nrf_gpio_cfg_output(ADPT_LE_PIN);
nrf_gpio_cfg_output(ADPT_CLK_PIN);
nrf_gpio_cfg_output(ADPT_DIN_PIN);
for (uint32_t i = 0; i < COUNTOF(exclude_io); i++)
{
nrf_gpio_pin_write(exclude_io[i], EXCLUDE_IO_DISABLE);
}
max14802_write((sw_t) { .val = 0 });
nrf_gpio_pin_clear(ADPT_CLR_PIN);
return 0;
}
const sw_drv_if_t max14802 = {
.init = max14802_init,
.reset = max14802_reset,
.write = max14802_write,
.read = max14802_read,
.get_sw_count = max14802_get_sw_count,
};
#endif
-31
View File
@@ -1,31 +0,0 @@
#ifndef __MAX14802_H__
#define __MAX14802_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_config.h"
#include "sw_drv_if.h"
#if (DEF_MAX14802_ENABLED)
#define MAX14802_COUNT 1
#define SW_PER_MAX14802 16
#define SW_TOTAL_COUNT (SW_PER_MAX14802 * MAX14802_COUNT)
#define SW_PER_BYTE 8
#if (SW_TOTAL_COUNT > 64)
#error "unsupport"
#endif /* ! SW_TOTAL_COUNT */
extern const sw_drv_if_t max14802;
#endif /* ! DEF_MAX14802_ENABLED */
#ifdef __cplusplus
}
#endif
#endif // !__MAX14802_H__
-133
View File
@@ -1,133 +0,0 @@
#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 */
-20
View File
@@ -1,20 +0,0 @@
#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__ */
+9 -1
View File
@@ -4,8 +4,16 @@ MEMORY
{
FLASH (rx) : ORIGIN = 0x00027000, LENGTH = 0x000B7000
RAM_SOFTDEVICE (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 0x00030000
RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 0x0002F000
RTT (rwx) : ORIGIN = 0x2003F000, LENGTH = 0x00001000
CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000
}
SECTIONS
{
.segger_rtt (NOLOAD) :
{
} > RTT
}
INCLUDE "nrf_full.ld"
+1 -1
View File
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -2,9 +2,9 @@
<EmbeddedProfile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
<ToolchainVersion>
<GCC>13.3.1</GCC>
<GDB>15.1</GDB>
<Revision>2</Revision>
<GCC>12.3.1</GCC>
<GDB>13.2</GDB>
<Revision>1</Revision>
</ToolchainVersion>
<BspID>com.sysprogs.arm.nordic.nrf5x</BspID>
<BspVersion>17.0</BspVersion>
@@ -18,7 +18,7 @@
</KeyValue>
<KeyValue>
<Key>com.sysprogs.bspoptions.nrf5x.pinreset</Key>
<Value />
<Value>CONFIG_GPIO_AS_PINRESET</Value>
</KeyValue>
<KeyValue>
<Key>com.sysprogs.bspoptions.primary_memory</Key>
-618
View File
@@ -1,618 +0,0 @@
#include "pel.h"
#include "elite_board.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_ELITE_PEL_V2_0)
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 (int32_t i = COUNTOF(input_pin_tab) - 1; i >= 0; 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 void set_resistor_to_default(void)
{
const uint32_t resistor_to_default = 0b000000000000;
_load_set(resistor_to_default);
}
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 */
set_resistor_to_default();
_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 10
#define VERSION_DATE_DAY 8
#define VERSION_DATE_HOUR 12
#define VERSION_DATE_MINUTE 31
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);
}
}
void set_a_specific_resistor_combination(uint16_t resistor_combination)
{
typedef struct
{
uint16_t val;
uint32_t mask;
} resistor_combination_t;
const resistor_combination_t resis_combination_tab[] = {
{ 1, 0b111},
{ 2, 0b011},
{ 3, 0b101},
{ 4, 0b001},
{ 5, 0b111 << 1},
{ 6, 0b011 << 1},
{ 7, 0b101 << 1},
{ 8, 0b001 << 1},
{ 9, 0b111 << 2},
{10, 0b011 << 2},
{11, 0b101 << 2},
{12, 0b001 << 2},
{13, 0b111 << 3},
{14, 0b011 << 3},
{15, 0b101 << 3},
{16, 0b001 << 3},
{17, 0b111 << 4},
{18, 0b011 << 4},
{19, 0b101 << 4},
{20, 0b001 << 4},
{21, 0b111 << 5},
{22, 0b011 << 5},
{23, 0b101 << 5},
{24, 0b001 << 5},
{25, 0b111 << 6},
{26, 0b011 << 6},
{27, 0b101 << 6},
{28, 0b001 << 6},
{29, 0b111 << 7},
{30, 0b011 << 7},
{31, 0b101 << 7},
{32, 0b001 << 7},
{33, 0b111 << 8},
{34, 0b011 << 8},
{35, 0b101 << 8},
{36, 0b001 << 8},
{37, 0b111 << 9},
{38, 0b011 << 9},
{39, 0b101 << 9},
{40, 0b001 << 9},
{41, 0b11 << 10},
{42, 0b01 << 10},
{43, 0b1 << 11},
};
for (int32_t i = 0; i < COUNTOF(resis_combination_tab); i++)
{
if (resis_combination_tab[i].val == resistor_combination)
{
NRF_LOG_INFO("No.%d resistor_combination: 0x%03X(FW) ", resis_combination_tab[i].val, resis_combination_tab[i].mask);
NRF_LOG_INFO("Input | 1 | 2 | 3 | 4 | 5 | 6 |");
NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |",
(resis_combination_tab[i].mask & 1 << 0),
(resis_combination_tab[i].mask & 1 << 1) >> 1,
(resis_combination_tab[i].mask & 1 << 2) >> 2,
(resis_combination_tab[i].mask & 1 << 3) >> 3,
(resis_combination_tab[i].mask & 1 << 4) >> 4,
(resis_combination_tab[i].mask & 1 << 5) >> 5);
NRF_LOG_INFO("Input | 7 | 8 | 9 | 10 | 11 | 12 |");
NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |",
(resis_combination_tab[i].mask & 1 << 6) >> 6,
(resis_combination_tab[i].mask & 1 << 7) >> 7,
(resis_combination_tab[i].mask & 1 << 8) >> 8,
(resis_combination_tab[i].mask & 1 << 9) >> 9,
(resis_combination_tab[i].mask & 1 << 10) >> 10,
(resis_combination_tab[i].mask & 1 << 11) >> 11);
set_resistor_to_default();
_load_set(resis_combination_tab[i].mask);
}
}
}
void pel_select_resistor_combinations_mode(uint8_t *ins)
{
#define SET_A_SPECIFIC_RESISTOR_COMBINATION 0x00
#define SET_ALL_RESISTORS_AT_ONCE 0x01
uint16_t set_resistor_type = (ins[4] & 0xF0) >> 4;
uint16_t val = ((ins[4] & 0x0F) << 8) | ins[5];
if (set_resistor_type == 0)
{
set_a_specific_resistor_combination(val);
}
else if (set_resistor_type == 1)
{
typedef union
{
struct
{
uint32_t input1 : 1;
uint32_t input2 : 1;
uint32_t input3 : 1;
uint32_t input4 : 1;
uint32_t input5 : 1;
uint32_t input6 : 1;
uint32_t input7 : 1;
uint32_t input8 : 1;
uint32_t input9 : 1;
uint32_t input10 : 1;
uint32_t input11 : 1;
uint32_t input12 : 1;
};
uint32_t val;
} resis_t;
resis_t resis;
resis.input1 = (val & 0b0000100000000000) >> 11;
resis.input2 = (val & 0b0000010000000000) >> 10;
resis.input3 = (val & 0b0000001000000000) >> 9;
resis.input4 = (val & 0b0000000100000000) >> 8;
resis.input5 = (val & 0b0000000010000000) >> 7;
resis.input6 = (val & 0b0000000001000000) >> 6;
resis.input7 = (val & 0b0000000000100000) >> 5;
resis.input8 = (val & 0b0000000000010000) >> 4;
resis.input9 = (val & 0b0000000000001000) >> 3;
resis.input10 = (val & 0b0000000000000100) >> 2;
resis.input11 = (val & 0b0000000000000010) >> 1;
resis.input12 = (val & 0b0000000000000001) >> 0;
NRF_LOG_INFO("Set_all_resistors_at_once: 0x%03X(FW) ", resis.val);
NRF_LOG_INFO("Input | 1 | 2 | 3 | 4 | 5 | 6 |");
NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |",
(resis.val & 1 << 0),
(resis.val & 1 << 1) >> 1,
(resis.val & 1 << 2) >> 2,
(resis.val & 1 << 3) >> 3,
(resis.val & 1 << 4) >> 4,
(resis.val & 1 << 5) >> 5);
NRF_LOG_INFO("Input | 7 | 8 | 9 | 10 | 11 | 12 |");
NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |",
(resis.val & 1 << 6) >> 6,
(resis.val & 1 << 7) >> 7,
(resis.val & 1 << 8) >> 8,
(resis.val & 1 << 9) >> 9,
(resis.val & 1 << 10) >> 10,
(resis.val & 1 << 11) >> 11);
set_resistor_to_default();
_load_set(resis.val);
}
else
{
printf("No this cmd...");
}
}
#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 0x62: {
pel_select_resistor_combinations_mode(ins);
break;
}
case 0xF0: {
pel20_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
-42
View File
@@ -1,42 +0,0 @@
#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__ */
-248
View File
@@ -1,248 +0,0 @@
#include "elite_board.h"
#include "nrf_gpio.h"
#include "nrf_gpiote.h"
#include "nrf_spim.h"
#include "nrf_timer.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#if (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
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();
}
#define MIN_PULSE_WIDTH 2
#define MIN_PULSE_IDLE 2
#define MAX_PULSE_WIDTH INT16_MAX
#define MAX_PULSE_IDLE INT16_MAX
typedef struct
{
uint32_t anode_pin;
uint32_t cathode_pin;
uint32_t pulse_idle; // min: 2, max: 32767, unit: us
uint32_t pulse_width; // min: 2, max: 32767, unit: us,
uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF
} pulse_gen_t;
typedef struct
{
uint32_t gpiote_idx[2];
NRF_TIMER_Type *pulse_tmr;
uint32_t pulse_irq_n;
uint32_t pulse_cnt;
} pulse_gen_hw_t;
pulse_gen_hw_t pulse_gen_hw = {
.gpiote_idx = {0, 1},
.pulse_tmr = NRF_TIMER3,
.pulse_irq_n = TIMER3_IRQn,
.pulse_cnt = 0,
};
void TIMER3_IRQHandler(void)
{
if (pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[1])
{
pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[1] = 0;
pulse_gen_hw.pulse_cnt--;
if (pulse_gen_hw.pulse_cnt == 1)
{
pulse_gen_hw.pulse_tmr->SHORTS |= NRF_TIMER_SHORT_COMPARE1_STOP_MASK;
}
}
}
bool pel_pulse_gen(pulse_gen_t *p_pulse_gen)
{
/* hardware limitation */
if (p_pulse_gen->pulse_cnt == 0 ||
p_pulse_gen->pulse_idle < MIN_PULSE_IDLE ||
p_pulse_gen->pulse_width < MIN_PULSE_WIDTH ||
p_pulse_gen->pulse_idle > MAX_PULSE_IDLE ||
p_pulse_gen->pulse_width > MAX_PULSE_WIDTH)
{
return false;
}
pulse_gen_hw.pulse_cnt = p_pulse_gen->pulse_cnt;
pulse_gen_hw.pulse_tmr->TASKS_STOP = 1;
sd_nvic_DisableIRQ(pulse_gen_hw.pulse_irq_n);
sd_nvic_ClearPendingIRQ(pulse_gen_hw.pulse_irq_n);
nrf_gpiote_task_configure(pulse_gen_hw.gpiote_idx[0], p_pulse_gen->anode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
nrf_gpiote_task_configure(pulse_gen_hw.gpiote_idx[1], p_pulse_gen->cathode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_enable(pulse_gen_hw.gpiote_idx[0]);
nrf_gpiote_task_enable(pulse_gen_hw.gpiote_idx[1]);
NRF_PPI->CH[0].EEP = (uint32_t)&pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[0];
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[0]];
NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[1]];
NRF_PPI->CHENSET = (1 << (0));
NRF_PPI->CH[1].EEP = (uint32_t)&pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[1];
NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[0]];
NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[1]];
NRF_PPI->CHENSET = (1 << (1));
pulse_gen_hw.pulse_tmr->TASKS_CLEAR = 1;
pulse_gen_hw.pulse_tmr->PRESCALER = NRF_TIMER_FREQ_16MHz;
pulse_gen_hw.pulse_tmr->MODE = NRF_TIMER_MODE_TIMER;
pulse_gen_hw.pulse_tmr->BITMODE = NRF_TIMER_BIT_WIDTH_32;
pulse_gen_hw.pulse_tmr->CC[0] = p_pulse_gen->pulse_idle * 16;
pulse_gen_hw.pulse_tmr->CC[1] = pulse_gen_hw.pulse_tmr->CC[0] + p_pulse_gen->pulse_width * 16;
pulse_gen_hw.pulse_tmr->SHORTS = pulse_gen_hw.pulse_cnt > 1 ? NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK : NRF_TIMER_SHORT_COMPARE1_STOP_MASK;
pulse_gen_hw.pulse_tmr->INTENSET = NRF_TIMER_INT_COMPARE1_MASK;
sd_nvic_SetPriority(pulse_gen_hw.pulse_irq_n, _PRIO_APP_HIGH);
sd_nvic_EnableIRQ(pulse_gen_hw.pulse_irq_n);
pulse_gen_hw.pulse_tmr->TASKS_START = 1;
return true;
}
void pel_pulse_gen_demo(void)
{
pulse_gen_t pulse_gen = {
.anode_pin = ANODE_PIN,
.cathode_pin = CATHODE_PIN,
.pulse_width = 10,
.pulse_idle = 1000,
.pulse_cnt = 0xFFFFFFFF
};
if (pel_pulse_gen(&pulse_gen) == false)
{
// fail handling
}
}
void pel20_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;
pel_pulse_gen_demo();
}
#endif
-77
View File
@@ -1,77 +0,0 @@
#ifndef __PEL20_IO_H__
#define __PEL20_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_ELITE_PEL_V2_0)
#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, 8)
#define ANODE_PIN NRF_GPIO_PIN_MAP(0, 7)
#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, 2)
#define OUTPUT_VE_PIN NRF_GPIO_PIN_MAP(0, 3)
#define OUTPUT_R1_CHANNEL 7
#define OUTPUT_R2_CHANNEL 4
#define OUTPUT_VO_CHANNEL 5
#define OUTPUT_VC_CHANNEL 0
#define OUTPUT_VE_CHANNEL 1
#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 pel20_io_init(void);
#endif /* ! DEF_ELITE_MODEL */
#ifdef __cplusplus
}
#endif
#endif /* ! __PEL20_IO_H__ */
+117
View File
@@ -0,0 +1,117 @@
#include "nrf_drv_spi.h"
#include "nrf_gpio.h"
#include "nrf_log.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#define SPI1_CLK_PIN NRF_GPIO_PIN_MAP(0, 13)
#define SPI1_MOSI_PIN NRF_GPIO_PIN_MAP(0, 14)
#define SPI2_CLK_PIN NRF_GPIO_PIN_MAP(0, 12)
#define SPI2_MOSI_PIN NRF_GPIO_PIN_MAP(0, 7)
#define SPI2_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
static const nrf_drv_spi_t spim1 = NRF_DRV_SPI_INSTANCE(1); /**< SPI instance. */
static const nrf_drv_spi_t spim2 = NRF_DRV_SPI_INSTANCE(2); /**< SPI instance. */
static SemaphoreHandle_t spim1_sem = NULL;
static SemaphoreHandle_t spim2_sem = NULL;
static SemaphoreHandle_t spim2_mutex = NULL;
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 nrf_drv_spim2_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(spim2_sem, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
break;
default:
break;
}
}
void spi_init(void)
{
spim1_sem = xSemaphoreCreateBinary();
spim2_sem = xSemaphoreCreateBinary();
spim2_mutex = xSemaphoreCreateMutex();
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_1;
spi1_config.frequency = NRF_DRV_SPI_FREQ_1M;
APP_ERROR_CHECK(nrf_drv_spi_init(&spim1, &spi1_config, nrf_drv_spim1_evt_handler, NULL));
nrf_drv_spi_config_t spi2_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi2_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
spi2_config.miso_pin = SPI2_MISO_PIN;
spi2_config.mosi_pin = SPI2_MOSI_PIN;
spi2_config.sck_pin = SPI2_CLK_PIN;
spi2_config.mode = NRF_DRV_SPI_MODE_1;
spi2_config.frequency = NRF_DRV_SPI_FREQ_1M;
APP_ERROR_CHECK(nrf_drv_spi_init(&spim2, &spi2_config, nrf_drv_spim2_evt_handler, NULL));
}
void spi1_write(uint8_t *p_tx_buffer, uint8_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);
}
static void virtual_data(uint8_t *p_rx_buf, uint8_t rx_buffer_length)
{
uint8_t virtual_data_buff[20] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
if (rx_buffer_length == 0)
return;
memcpy(p_rx_buf, virtual_data_buff, rx_buffer_length);
}
void spi2_write(uint32_t cs_pin, uint8_t *p_tx_buffer, uint8_t tx_buffer_length, uint8_t *p_rx_buf, uint8_t rx_buffer_length)
{
xSemaphoreTake(spim2_mutex, portMAX_DELAY);
nrf_gpio_pin_clear(cs_pin);
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spim2, p_tx_buffer, tx_buffer_length, p_rx_buf, rx_buffer_length));
if (xSemaphoreTake(spim2_sem, pdMS_TO_TICKS(100)) == pdFALSE)
{
// TODO... spi treansfer timeout.
}
nrf_gpio_pin_set(cs_pin);
xSemaphoreGive(spim2_mutex);
NRF_LOG_INFO("spi(W)");
NRF_LOG_HEXDUMP_INFO(p_tx_buffer, tx_buffer_length);
// virtual_data(p_rx_buf, rx_buffer_length);
if (rx_buffer_length > 0)
{
NRF_LOG_INFO("spi(R)");
NRF_LOG_HEXDUMP_INFO(p_rx_buf, rx_buffer_length);
}
}
-67
View File
@@ -1,67 +0,0 @@
#include "sw_drv.h"
#if (DEF_ADGS1412_ENABLED)
#include "adgs1412.h"
const sw_drv_if_t *p_inst = &adgs1412;
#elif (DEF_MAX14802_ENABLED)
#include "max14802.h"
const sw_drv_if_t *p_inst = &max14802;
#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 */
-36
View File
@@ -1,36 +0,0 @@
#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
View File
@@ -1,96 +0,0 @@
#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__ */
-48
View File
@@ -1,48 +0,0 @@
#include "tw1508.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "FreeRTOS.h"
#include "task.h"
#if (DEF_TW1508_ENABLED)
void tw1508_set(uint16_t out_0, uint16_t out_1)
{
typedef struct
{
uint32_t scki_pin;
uint32_t sdi_pin;
uint32_t val;
} tw1805_t;
tw1805_t tw1508[2] = {
{TW_SCKI_0_PIN, TW_SDI_PIN, out_0},
{TW_SCKI_1_PIN, TW_SDI_PIN, out_1},
};
nrf_gpio_pin_write(tw1508[0].scki_pin, 0);
nrf_gpio_pin_write(tw1508[1].scki_pin, 0);
for (uint32_t i = 0; i < COUNTOF(tw1508); i++)
{
for (uint16_t j = 0b1000000000; j > 0; j >>= 1)
{
nrf_delay_us(1);
nrf_gpio_pin_write(tw1508[i].sdi_pin, j & tw1508[i].val);
nrf_delay_us(1);
nrf_gpio_pin_write(tw1508[i].scki_pin, 1);
nrf_delay_us(1);
nrf_gpio_pin_write(tw1508[i].scki_pin, 0);
}
}
nrf_delay_us(256);
}
void tw1508_init(void)
{
tw1508_set(0, 0);
}
#endif /* ! DEF_TW1508_ENABLED */
-21
View File
@@ -1,21 +0,0 @@
#ifndef __TW1508_H__
#define __TW1508_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_config.h"
#include "elite_board.h"
#if (DEF_TW1508_ENABLED)
void tw1508_set(uint16_t out_0, uint16_t out_1);
void tw1508_init(void);
#endif /* ! DEF_TW1508_ENABLED */
#ifdef __cplusplus
}
#endif
#endif /* ! __CPG_H__ */