pulse_cnt: new driver for PCNT peripheral

This commit is contained in:
morris
2022-01-17 14:42:09 +08:00
parent 6e405cc209
commit ec8defaa96
36 changed files with 1829 additions and 375 deletions

View File

@@ -1,16 +1,8 @@
// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*******************************************************************************
* NOTICE
@@ -22,6 +14,7 @@
#pragma once
#include <limits.h>
#include <stdlib.h>
#include <stdbool.h>
#include "soc/pcnt_struct.h"
@@ -31,19 +24,23 @@
extern "C" {
#endif
#define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
#define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
#define PCNT_LL_MAX_GLITCH_WIDTH 1023
#define PCNT_LL_MAX_LIM SHRT_MAX
#define PCNT_LL_MIN_LIN SHRT_MIN
typedef enum {
PCNT_LL_EVENT_THRES1,
PCNT_LL_EVENT_THRES0,
PCNT_LL_EVENT_LOW_LIMIT,
PCNT_LL_EVENT_HIGH_LIMIT,
PCNT_LL_EVENT_ZERO_CROSS,
PCNT_LL_EVENT_MAX
} pcnt_ll_event_id_t;
PCNT_LL_WATCH_EVENT_INVALID = -1,
PCNT_LL_WATCH_EVENT_THRES1,
PCNT_LL_WATCH_EVENT_THRES0,
PCNT_LL_WATCH_EVENT_LOW_LIMIT,
PCNT_LL_WATCH_EVENT_HIGH_LIMIT,
PCNT_LL_WATCH_EVENT_ZERO_CROSS,
PCNT_LL_WATCH_EVENT_MAX
} pcnt_ll_watch_event_id_t;
#define PCNT_LL_EVENT_MASK ((1 << PCNT_LL_EVENT_MAX) - 1)
#define PCNT_LL_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1)
#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id))
/**
* @brief Set PCNT channel edge action
@@ -156,7 +153,8 @@ static inline void pcnt_ll_enable_intr(pcnt_dev_t *hw, uint32_t unit_mask, bool
* @param hw Peripheral PCNT hardware instance address.
* @return Interrupt status word
*/
__attribute__((always_inline)) static inline uint32_t pcnt_ll_get_intr_status(pcnt_dev_t *hw)
__attribute__((always_inline))
static inline uint32_t pcnt_ll_get_intr_status(pcnt_dev_t *hw)
{
return hw->int_st.val;
}
@@ -167,7 +165,8 @@ __attribute__((always_inline)) static inline uint32_t pcnt_ll_get_intr_status(pc
* @param hw Peripheral PCNT hardware instance address.
* @param status value to clear interrupt status
*/
__attribute__((always_inline)) static inline void pcnt_ll_clear_intr_status(pcnt_dev_t *hw, uint32_t status)
__attribute__((always_inline))
static inline void pcnt_ll_clear_intr_status(pcnt_dev_t *hw, uint32_t status)
{
hw->int_clr.val = status;
}
@@ -233,7 +232,7 @@ static inline void pcnt_ll_enable_thres_event(pcnt_dev_t *hw, uint32_t unit, uin
*/
static inline void pcnt_ll_disable_all_events(pcnt_dev_t *hw, uint32_t unit)
{
hw->conf_unit[unit].conf0.val &= ~(PCNT_LL_EVENT_MASK << 11);
hw->conf_unit[unit].conf0.val &= ~(PCNT_LL_WATCH_EVENT_MASK << 11);
}
/**
@@ -344,13 +343,14 @@ static inline uint32_t pcnt_ll_get_unit_status(pcnt_dev_t *hw, uint32_t unit)
}
/**
* @brief Get PCNT count sign
* @brief Get PCNT zero cross mode
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @return Count sign
* @return Zero cross mode
*/
static inline pcnt_unit_count_sign_t pcnt_ll_get_count_sign(pcnt_dev_t *hw, uint32_t unit)
__attribute__((always_inline))
static inline pcnt_unit_zero_cross_mode_t pcnt_ll_get_zero_cross_mode(pcnt_dev_t *hw, uint32_t unit)
{
return hw->status_unit[unit].val & 0x03;
}
@@ -362,6 +362,7 @@ static inline pcnt_unit_count_sign_t pcnt_ll_get_count_sign(pcnt_dev_t *hw, uint
* @param unit PCNT unit number
* @return Event status word
*/
__attribute__((always_inline))
static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, uint32_t unit)
{
return hw->status_unit[unit].val >> 2;
@@ -404,6 +405,18 @@ static inline void pcnt_ll_enable_glitch_filter(pcnt_dev_t *hw, uint32_t unit, b
hw->conf_unit[unit].conf0.filter_en = enable;
}
/**
* @brief Get interrupt status register address.
*
* @param hw Beginning address of the peripheral registers.
*
* @return Interrupt status register address
*/
static inline volatile void *pcnt_ll_get_intr_status_reg(pcnt_dev_t *hw)
{
return &hw->int_st.val;
}
#ifdef __cplusplus
}
#endif