V1.0
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "ringbuffer.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Implementation of ring buffer functions.
|
||||
*/
|
||||
void ring_buffer_create(ring_buffer_t *rb, uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
if ((rb == NULL) || (buffer == NULL) || (size == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
rb->buffer = buffer;
|
||||
rb->size = size;
|
||||
rb->tail_index = 0;
|
||||
rb->head_index = 0;
|
||||
rb->rx_lock = false;
|
||||
}
|
||||
|
||||
|
||||
void ring_buffer_queue(ring_buffer_t *rb, uint8_t data)
|
||||
{
|
||||
/* Is buffer full? */
|
||||
if (ring_buffer_is_full(rb)) {
|
||||
/* Is going to overwrite the oldest byte */
|
||||
/* Increase tail index */
|
||||
rb->tail_index = ((rb->tail_index + 1) & (rb->size - 1));
|
||||
}
|
||||
|
||||
/* Place data in buffer */
|
||||
rb->buffer[rb->head_index] = data;
|
||||
|
||||
rb->head_index = ((rb->head_index + 1) & (rb->size - 1));
|
||||
}
|
||||
|
||||
void ring_buffer_queue_arr(ring_buffer_t *rb, uint8_t *data,
|
||||
ring_buffer_size_t size)
|
||||
{
|
||||
/* Add bytes; one by one */
|
||||
ring_buffer_size_t i;
|
||||
for (i = 0; i < size; i++) {
|
||||
ring_buffer_queue(rb, data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ring_buffer_size_t ring_buffer_dequeue(ring_buffer_t *rb, uint8_t *data)
|
||||
{
|
||||
if (ring_buffer_is_empty(rb)) {
|
||||
/* No items */
|
||||
return 0;
|
||||
}
|
||||
|
||||
*data = rb->buffer[rb->tail_index];
|
||||
|
||||
rb->tail_index = ((rb->tail_index + 1) & (rb->size - 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ring_buffer_size_t ring_buffer_dequeue_arr(ring_buffer_t *rb, uint8_t *data,
|
||||
ring_buffer_size_t len)
|
||||
{
|
||||
if (ring_buffer_is_empty(rb)) {
|
||||
/* No items */
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *data_ptr = data;
|
||||
ring_buffer_size_t cnt = 0;
|
||||
while ((cnt < len) && ring_buffer_dequeue(rb, data_ptr)) {
|
||||
cnt++;
|
||||
data_ptr++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
ring_buffer_size_t ring_buffer_peek(ring_buffer_t *rb, uint8_t *data,
|
||||
ring_buffer_size_t index)
|
||||
{
|
||||
if (index >= ring_buffer_num_items(rb)) {
|
||||
/* No items at index */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add index to pointer */
|
||||
ring_buffer_size_t data_index = ((rb->tail_index + index) & (rb->size - 1));
|
||||
*data = rb->buffer[data_index];
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern inline ring_buffer_size_t ring_buffer_is_empty(ring_buffer_t *rb);
|
||||
extern inline ring_buffer_size_t ring_buffer_is_full(ring_buffer_t *rb);
|
||||
extern inline ring_buffer_size_t ring_buffer_num_items(ring_buffer_t *rb);
|
||||
@@ -0,0 +1,165 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Prototypes and structures for the ring buffer module.
|
||||
*/
|
||||
|
||||
#ifndef __RINGBUFFER_H__
|
||||
#define __RINGBUFFER_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* The size of a ring buffer.
|
||||
* Due to the design only <tt> RING_BUFFER_SIZE-1 </tt> items
|
||||
* can be contained in the buffer.
|
||||
* The buffer size must be a power of two.
|
||||
*/
|
||||
// #define RING_BUFFER_SIZE 256U//512
|
||||
//
|
||||
// #if (RING_BUFFER_SIZE & (RING_BUFFER_SIZE - 1)) != 0
|
||||
// #error "RING_BUFFER_SIZE must be a power of two"
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* The type which is used to hold the size
|
||||
* and the indicies of the buffer.
|
||||
* Must be able to fit \c RING_BUFFER_SIZE .
|
||||
*/
|
||||
typedef uint32_t ring_buffer_size_t;
|
||||
|
||||
/**
|
||||
* Used as a modulo operator
|
||||
* as <tt> a % b = (a & (b − 1)) </tt>
|
||||
* where \c a is a positive index in the buffer and
|
||||
* \c b is the (power of two) size of the buffer.
|
||||
*/
|
||||
// #define RING_BUFFER_MASK (RING_BUFFER_SIZE-1)
|
||||
|
||||
/**
|
||||
* Structure which holds a ring buffer.
|
||||
* The buffer contains a buffer array
|
||||
* as well as metadata for the ring buffer.
|
||||
*/
|
||||
typedef struct ring_buffer
|
||||
{
|
||||
/** Buffer memory. */
|
||||
uint8_t *buffer;
|
||||
/** Buffer size. */
|
||||
ring_buffer_size_t size;
|
||||
/** Index of tail. */
|
||||
ring_buffer_size_t tail_index;
|
||||
/** Index of head. */
|
||||
ring_buffer_size_t head_index;
|
||||
/** Rx Locker. */
|
||||
bool rx_lock;
|
||||
} ring_buffer_t;
|
||||
// typedef struct ring_buffer {
|
||||
// /** Buffer memory. */
|
||||
//// uint8_t *buffer;
|
||||
// unsigned char buffer[RING_BUFFER_SIZE];
|
||||
// /** Index of tail. */
|
||||
// ring_buffer_size_t tail_index;
|
||||
// /** Index of head. */
|
||||
// ring_buffer_size_t head_index;
|
||||
// /** Rx Locker. */
|
||||
// bool rx_lock;
|
||||
//}ring_buffer_t;
|
||||
|
||||
// typedef struct ring_buffer {
|
||||
// /** Buffer memory. */
|
||||
//// uint8_t *buffer;
|
||||
// unsigned char buffer[RING_BUFFER_SIZE];
|
||||
// /** Index of tail. */
|
||||
// ring_buffer_size_t tail_index;
|
||||
// /** Index of head. */
|
||||
// ring_buffer_size_t head_index;
|
||||
// /** Rx Locker. */
|
||||
// bool rx_lock;
|
||||
//}ring_buffer_t;
|
||||
|
||||
/**
|
||||
* Initializes the ring buffer pointed to by <em>buffer</em>.
|
||||
* This function can also be used to empty/reset the buffer.
|
||||
* @param buffer The ring buffer to initialize.
|
||||
*/
|
||||
// void ring_buffer_init(ring_buffer_t *buffer);
|
||||
void ring_buffer_create(ring_buffer_t *rb, uint8_t *buffer, uint32_t size);
|
||||
|
||||
/**
|
||||
* Adds a byte to a ring buffer.
|
||||
* @param buffer The buffer in which the data should be placed.
|
||||
* @param data The byte to place.
|
||||
*/
|
||||
void ring_buffer_queue(ring_buffer_t *rb, uint8_t data);
|
||||
|
||||
/**
|
||||
* Adds an array of bytes to a ring buffer.
|
||||
* @param buffer The buffer in which the data should be placed.
|
||||
* @param data A pointer to the array of bytes to place in the queue.
|
||||
* @param size The size of the array.
|
||||
*/
|
||||
void ring_buffer_queue_arr(ring_buffer_t *rb, uint8_t *data,
|
||||
ring_buffer_size_t size);
|
||||
|
||||
/**
|
||||
* Returns the oldest byte in a ring buffer.
|
||||
* @param buffer The buffer from which the data should be returned.
|
||||
* @param data A pointer to the location at which the data should be placed.
|
||||
* @return 1 if data was returned; 0 otherwise.
|
||||
*/
|
||||
ring_buffer_size_t ring_buffer_dequeue(ring_buffer_t *rb, uint8_t *data);
|
||||
|
||||
/**
|
||||
* Returns the <em>len</em> oldest bytes in a ring buffer.
|
||||
* @param buffer The buffer from which the data should be returned.
|
||||
* @param data A pointer to the array at which the data should be placed.
|
||||
* @param len The maximum number of bytes to return.
|
||||
* @return The number of bytes returned.
|
||||
*/
|
||||
ring_buffer_size_t ring_buffer_dequeue_arr(ring_buffer_t *rb, uint8_t *data,
|
||||
ring_buffer_size_t len);
|
||||
/**
|
||||
* Peeks a ring buffer, i.e. returns an element without removing it.
|
||||
* @param buffer The buffer from which the data should be returned.
|
||||
* @param data A pointer to the location at which the data should be placed.
|
||||
* @param index The index to peek.
|
||||
* @return 1 if data was returned; 0 otherwise.
|
||||
*/
|
||||
ring_buffer_size_t ring_buffer_peek(ring_buffer_t *rb, uint8_t *data,
|
||||
ring_buffer_size_t index);
|
||||
|
||||
/**
|
||||
* Returns whether a ring buffer is empty.
|
||||
* @param buffer The buffer for which it should be returned whether it is empty.
|
||||
* @return 1 if empty; 0 otherwise.
|
||||
*/
|
||||
inline ring_buffer_size_t ring_buffer_is_empty(ring_buffer_t *rb)
|
||||
{
|
||||
return (rb->head_index == rb->tail_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a ring buffer is full.
|
||||
* @param buffer The buffer for which it should be returned whether it is full.
|
||||
* @return 1 if full; 0 otherwise.
|
||||
*/
|
||||
inline ring_buffer_size_t ring_buffer_is_full(ring_buffer_t *rb)
|
||||
{
|
||||
return ((rb->head_index - rb->tail_index) & (rb->size - 1)) ==
|
||||
(rb->size - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items in a ring buffer.
|
||||
* @param buffer The buffer for which the number of items should be returned.
|
||||
* @return The number of items in the ring buffer.
|
||||
*/
|
||||
inline ring_buffer_size_t ring_buffer_num_items(ring_buffer_t *rb)
|
||||
{
|
||||
return ((rb->head_index - rb->tail_index) & (rb->size - 1));
|
||||
}
|
||||
|
||||
#endif /* __RINGBUFFER_H__ */
|
||||
@@ -0,0 +1,576 @@
|
||||
/*!
|
||||
* \file xc_drv_adc.c
|
||||
*
|
||||
* \brief Target xc adc driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
#if (ADC_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static uint16_t adc_value[2 * ADC_FIFO_DOUT_LEN] = {0};
|
||||
static uint16_t adc_it_val;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_init
|
||||
* @details ADC initialization
|
||||
* @param[in] adc_cfg £ºThis is the structure parameter that the ADC initializes
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
* @other
|
||||
adc_cfg.Freq = ADC_FREQ_2M;
|
||||
adc_cfg.RefVol = ADC_REF_VOL_3_3V;
|
||||
adc_cfg.SampEdge = ADC_SAMPEDGE_RISE;
|
||||
adc_cfg.ExtDataMode = ADC_EXT_DATA_MODE_32BIT;
|
||||
adc_cfg.ExtEdgeSel = ADC_EXT_EDGE_SEL_INTER;
|
||||
adc_cfg.ExtSampleNum = ADC_EXT_SAMPLE_NUM_8;
|
||||
adc_cfg.ExtTriggerSel = ADC_EXT_TRIGGER_SEL_PWM0;
|
||||
|
||||
adc_init(&adc_cfg);
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_init(ADC_InitCfg_t *adc_cfg)
|
||||
{
|
||||
cpr_rstctl_ctlapb_sw__gpadc_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__gpadc_rstn__setf(RSTCTL_DISABLE);
|
||||
cpr_ctlapbclken_grctl__gpadc_pclk_en__setf(ENABLE);
|
||||
|
||||
cpr_opa_ctrl_reg__bg_5v_ctrl__setf(ENABLE);
|
||||
|
||||
adc_main_ctl__adc_en__setf(ADC_MAIN_CTL_ADC_EN_DISABLE);
|
||||
|
||||
xc_adc_fifo_flush();
|
||||
|
||||
adc_timer0_set(ADC_TIMER);
|
||||
|
||||
adc_main_ctl__edge_sel__setf(adc_cfg->SampEdge);
|
||||
|
||||
xc_adc_freq_set(adc_cfg->Freq);
|
||||
|
||||
xc_adc_refvol_set(adc_cfg->RefVol);
|
||||
|
||||
adc_main_ctl__ext_edge_sel__setf(adc_cfg->ExtEdgeSel);
|
||||
|
||||
adc_main_ctl__ext_sample_num__setf(adc_cfg->ExtSampleNum);
|
||||
|
||||
adc_main_ctl__ext_trigger_sel__setf(adc_cfg->ExtTriggerSel);
|
||||
|
||||
adc_main_ctl__ext_data_mode__setf(adc_cfg->ExtDataMode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_data_average
|
||||
* @details Calculate the average of a set of data
|
||||
* @param[in] data : The data to be averaged len : Take the number of averages
|
||||
* @param[out] void
|
||||
* @retval average
|
||||
***************************************************************************************
|
||||
*/
|
||||
uint16_t xc_adc_data_average(uint16_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t add_cnt = 0;
|
||||
uint32_t sum_data = 0;
|
||||
uint8_t filter_cnt = 0;
|
||||
|
||||
filter_cnt = len / 4;
|
||||
|
||||
for (int i = 0; i < len - 1; i++) {
|
||||
for (int j = 0; j < len - i - 1; j++) {
|
||||
if (data[j] > data[j + 1]) {
|
||||
uint16_t temp = data[j];
|
||||
data[j] = data[j + 1];
|
||||
data[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = filter_cnt; i < len - filter_cnt; i++) {
|
||||
sum_data += data[i];
|
||||
add_cnt++;
|
||||
}
|
||||
|
||||
if (0 == add_cnt)
|
||||
return 0xffff;
|
||||
else
|
||||
return sum_data / add_cnt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_data_average
|
||||
* @details Select and initialize the GPIO port based on the channel
|
||||
* @param[in] Channel : adc Channel
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_channel_gpio_config(ADC_ChannelTypeDef_t Channel)
|
||||
{
|
||||
GPIO_InitCfg_t GPIO_InitCfg;
|
||||
|
||||
GPIO_InitCfg.Mux = GPIO_Mux0;
|
||||
GPIO_InitCfg.FunSel = GPIO_Dx;
|
||||
GPIO_InitCfg.Dir = GPIO_DIR_INPUT;
|
||||
GPIO_InitCfg.Pull = GPIO_NOPULL;
|
||||
GPIO_InitCfg.Int = NOT_INT;
|
||||
|
||||
switch (Channel) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: {
|
||||
GPIO_InitCfg.Pin = GPIO_21 - Channel;
|
||||
} break;
|
||||
|
||||
case 4: {
|
||||
GPIO_InitCfg.Pin = GPIO_0;
|
||||
} break;
|
||||
|
||||
case 5: {
|
||||
GPIO_InitCfg.Pin = GPIO_1;
|
||||
|
||||
} break;
|
||||
|
||||
case 6: {
|
||||
GPIO_InitCfg.Pin = GPIO_4;
|
||||
} break;
|
||||
|
||||
case 7: {
|
||||
GPIO_InitCfg.Pin = GPIO_5;
|
||||
} break;
|
||||
|
||||
case 10: {
|
||||
GPIO_InitCfg.Pin = GPIO_2;
|
||||
} break;
|
||||
|
||||
case 11: {
|
||||
GPIO_InitCfg.Pin = GPIO_3;
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xc_gpio_init(&GPIO_InitCfg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_startgetvalue
|
||||
* @details The corresponding ADC sampling value is obtained according to the channel
|
||||
|
||||
* @param[in] Channel : The ADC sampling channel to be obtained
|
||||
* @param[in] *adc_val: ADC sample storage area
|
||||
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_start_get_value(ADC_ChannelTypeDef_t Channel, uint16_t *adc_val)
|
||||
{
|
||||
uint32_t val;
|
||||
ADC_FIFO_TypeDef_t *fifo_val = NULL;
|
||||
uint32_t time_out = 100000;
|
||||
uint8_t adc_count = 0;
|
||||
|
||||
adc_main_ctl__adc_en__setf(ADC_MAIN_CTL_ADC_EN_DISABLE);
|
||||
|
||||
adc_chan_ctl__select_chan__setf(Channel);
|
||||
|
||||
adc_fifo_ctl__read_req_thresh__setf(ADC_FIFO_CTL_READ_REQ_THRESH_LEN_8);
|
||||
|
||||
xc_adc_fifo_flush();
|
||||
|
||||
adc_int_set(adc_int_get());
|
||||
|
||||
adc_main_ctl__adc_en__setf(ADC_MAIN_CTL_ADC_EN_ENABLE);
|
||||
|
||||
val = adc_int_raw_get();
|
||||
|
||||
while (((val & ADC_INT_READ_REQ_INT_SET) != ADC_INT_READ_REQ_INT_SET) &&
|
||||
time_out) {
|
||||
__nop();
|
||||
|
||||
val = adc_int_raw_get();
|
||||
time_out--;
|
||||
}
|
||||
|
||||
if (time_out == 0) {
|
||||
DEBUG("adc time_out\n");
|
||||
return;
|
||||
}
|
||||
|
||||
adc_main_ctl__adc_en__setf(ADC_MAIN_CTL_ADC_EN_DISABLE);
|
||||
|
||||
fifo_val = (ADC_FIFO_TypeDef_t *)&val;
|
||||
|
||||
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_8; t++) {
|
||||
val = adc_fifo_get();
|
||||
|
||||
if (fifo_val->chanel_1 != fifo_val->chanel_2) {
|
||||
DEBUG("channel error :%d\n", t);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fifo_val->chanel_1 != Channel) {
|
||||
DEBUG("channel error :%d\n", t);
|
||||
return;
|
||||
}
|
||||
|
||||
adc_value[adc_count++] = fifo_val->value_1;
|
||||
adc_value[adc_count++] = fifo_val->value_2;
|
||||
// DEBUG("adc_value :%d\n", fifo_val->value_1);
|
||||
// DEBUG("adc_value :%d\n", fifo_val->value_2);
|
||||
}
|
||||
|
||||
*adc_val = xc_adc_data_average(adc_value, adc_count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_enable
|
||||
* @details Start adc sampling
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_enable(void)
|
||||
{
|
||||
adc_main_ctl__adc_en__setf(ADC_MAIN_CTL_ADC_EN_ENABLE) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_disable
|
||||
* @details Stop adc sampling
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_disable(void)
|
||||
{
|
||||
adc_main_ctl__adc_en__setf(ADC_MAIN_CTL_ADC_EN_DISABLE) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_enable_it
|
||||
* @details Enable adc interrupt
|
||||
* @param[in] it
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_enable_it(uint8_t it)
|
||||
{
|
||||
adc_int_en_set(it) ;
|
||||
}
|
||||
|
||||
void xc_adc_disable_it(uint8_t it)
|
||||
{
|
||||
adc_int_en_set(it) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_fifo_req_len_set
|
||||
* @details fifo receive length Settings for adc
|
||||
* @param[in] len : fifo length
|
||||
(ADC_FIFO_CTL_READ_REQ_THRESH_LEN_1 ~ ADC_FIFO_CTL_READ_REQ_THRESH_LEN_15)
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_fifo_req_len_set(uint8_t len)
|
||||
{
|
||||
adc_fifo_ctl__read_req_thresh__setf(len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_wait_time_set
|
||||
* @details ADC sampling wait time and interval Settings
|
||||
|
||||
* @param[in] timer0: Sampling wait time
|
||||
* @param[in] timer1: Sampling interval time
|
||||
ADC switches automatically when activated:
|
||||
sampling time(sampling frequency) = timer0 + timer1;
|
||||
(1M sampling(1US) = 0X1 + 31)
|
||||
timer0 < timer1
|
||||
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_wait_time_set(uint8_t timer0, uint16_t timer1)
|
||||
{
|
||||
adc_timer1_set(timer1);
|
||||
adc_timer0_set(timer0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_ch_auto_enable
|
||||
* @details The ADC automatic switchover was enabled
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_ch_auto_enable(void)
|
||||
{
|
||||
adc_main_ctl__auto_sw__setf(ADC_MAIN_CTL_AUTO_SW_ENABLE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_ch_auto_enable
|
||||
* @details Disable the ADC automatic switching function
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_ch_auto_disable(void)
|
||||
{
|
||||
adc_main_ctl__auto_sw__setf(ADC_MAIN_CTL_AUTO_SW_DISABLE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_ch_auto_set
|
||||
* @details Set the channel to be switched automatically
|
||||
* @param[in] ch : Automatic switching channel ( 1-->4 channel ¡ê?A bit represents a channel )
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_ch_auto_set(uint8_t ch)
|
||||
{
|
||||
adc_chan_ctl__chan_auto__setf(ch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_ch_auto_set
|
||||
* @details ADC channel selection for non-automatic switching channels
|
||||
* @param[in] ch : 0 - 13(ADC_CH0_PIN21 - ADC_CH13_PIN6)
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_ch_not_auto_set(uint8_t ch)
|
||||
{
|
||||
adc_chan_ctl__select_chan__setf(ch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_it_set
|
||||
* @details ADC Interrupt setting
|
||||
* @param[in] it :
|
||||
* Bits Field Name Reset Value
|
||||
* ----- ------------------ -----------
|
||||
* 1 FIFO_ERROR_INT 0
|
||||
* 0 READ_REQ_INT 0
|
||||
*
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_it_set(uint8_t it)
|
||||
{
|
||||
adc_int_set(it);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_it_get
|
||||
* @details Gets the ADC interrupt enable
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval nterrupt enable register
|
||||
***************************************************************************************
|
||||
*/
|
||||
uint8_t xc_adc_it_get(void)
|
||||
{
|
||||
return adc_int_get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_data_get
|
||||
* @details Get ADC sampling data
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval adc fifo data
|
||||
***************************************************************************************
|
||||
*/
|
||||
uint32_t xc_adc_data_get(void)
|
||||
{
|
||||
return adc_fifo__fifo_dout__getf();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_it_collectval_set
|
||||
* @details ADC interrupts to save data
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_it_collectval_set(uint16_t val) { adc_it_val = val; }
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_it_collectval_get
|
||||
* @details Gets the data saved by the ADC interrupt
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval adc_it_val
|
||||
***************************************************************************************
|
||||
*/
|
||||
uint16_t xc_adc_it_collectval_get(void) { return adc_it_val; }
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief GADC_Handler
|
||||
* @details ADC interrupts the callback function
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void GADC_Handler(void)
|
||||
{
|
||||
adc_intr_callback();
|
||||
adc_int_set(adc_int_get());
|
||||
}
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief adc_intr_callback
|
||||
* @details ADC interrupts the callback function that gets ADC sampled data
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
__WEAK void adc_intr_callback(void)
|
||||
{
|
||||
uint32_t adc_int;
|
||||
uint32_t val;
|
||||
|
||||
uint8_t adc_count = 0;
|
||||
ADC_FIFO_TypeDef_t *fifo_val = NULL;
|
||||
uint8_t channel = adc_chan_ctl__select_chan__getf();
|
||||
|
||||
adc_int = adc_int_get();
|
||||
|
||||
if (!(adc_int & (ADC_INT_READ_REQ_INT_SET | ADC_INT_FIFO_ERROR_INT_SET))) {
|
||||
// DEBUG("adc error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fifo_val = (ADC_FIFO_TypeDef_t *)&val;
|
||||
|
||||
for (int t = 0; t < adc_fifo_ctl__read_req_thresh__getf(); t++) {
|
||||
val = adc_fifo_get();
|
||||
|
||||
if (fifo_val->chanel_1 != fifo_val->chanel_2) {
|
||||
DEBUG("channel error :%d\n", t);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fifo_val->chanel_1 != channel) {
|
||||
DEBUG("channel error :%d\n", t);
|
||||
break;
|
||||
}
|
||||
|
||||
adc_value[adc_count++] = fifo_val->value_1;
|
||||
adc_value[adc_count++] = fifo_val->value_2;
|
||||
}
|
||||
|
||||
val = xc_adc_data_average(adc_value, adc_count);
|
||||
xc_adc_it_collectval_set(val);
|
||||
|
||||
adc_chan_ctl__select_chan__setf(channel);
|
||||
}
|
||||
|
||||
#endif //(ADC_ON)
|
||||
@@ -0,0 +1,250 @@
|
||||
/*!
|
||||
* \file xc_drv_adc.h
|
||||
*
|
||||
* \brief The header of xc_drv_adc.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_ADC_H_
|
||||
#define _XC_DRV_ADC_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define ADC_FIFO_DOUT_LEN 0x10UL
|
||||
#define ADC_TIMER 4
|
||||
|
||||
|
||||
#define ADC_MAIN_CTL_AUTO_SW_ENABLE (0x01UL)
|
||||
#define ADC_MAIN_CTL_AUTO_SW_DISABLE (0x00UL)
|
||||
|
||||
#define ADC_MAIN_CTL_ADC_EN_ENABLE (0x01UL)
|
||||
#define ADC_MAIN_CTL_ADC_EN_DISABLE (0x00UL)
|
||||
|
||||
#define ADC_CHAN_CTL_CHAN_1_SET (0x01UL)
|
||||
#define ADC_CHAN_CTL_CHAN_2_SET (0x02UL)
|
||||
#define ADC_CHAN_CTL_CHAN_3_SET (0x04UL)
|
||||
#define ADC_CHAN_CTL_CHAN_4_SET (0x08UL)
|
||||
|
||||
#define ADC_FIFO_CTL_FIFO_FLUSH_SET (0x01UL)
|
||||
#define ADC_FIFO_CTL_FIFO_FLUSH_RESET (0x00UL)
|
||||
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_1 (0x01UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2 (0x02UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_3 (0x03UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_4 (0x04UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_5 (0x05UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_6 (0x06UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_7 (0x07UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_8 (0x08UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_9 (0x09UL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_10 (0x0AUL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_11 (0x0BUL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_12 (0x0CUL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_13 (0x0DUL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_14 (0x0EUL)
|
||||
#define ADC_FIFO_CTL_READ_REQ_THRESH_LEN_15 (0x0FUL)
|
||||
|
||||
#define ADC_INT_FIFO_ERROR_INT_SET (0x01UL<<0x01UL)
|
||||
#define ADC_INT_READ_REQ_INT_SET (0x01UL<<0x00UL)
|
||||
|
||||
#define ADC_EXT_EDGE_SEL_INTER (0x00UL)
|
||||
#define ADC_EXT_EDGE_SEL_EXTERN_RISE (0x01UL)
|
||||
#define ADC_EXT_EDGE_SEL_EXTERN_FALL (0x02UL)
|
||||
#define ADC_EXT_EDGE_SEL_EXTERN_BOTH (0x03UL)
|
||||
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM0 (0x00UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM1 (0x01UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM2 (0x02UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM3 (0x03UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM4 (0x04UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM5 (0x05UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM_BRK1 (0x06UL)
|
||||
#define ADC_EXT_TRIGGER_SEL_PWM_BRK2 (0x07UL)
|
||||
|
||||
#define ADC_EXT_DATA_MODE_32BIT (0x00UL)
|
||||
#define ADC_EXT_DATA_MODE_LOW16BIT (0x01UL)
|
||||
|
||||
#define ADC_EXT_SAMPLE_NUM_1 (0x00UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_2 (0x01UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_3 (0x02UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_4 (0x03UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_5 (0x04UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_6 (0x05UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_7 (0x06UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_8 (0x07UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_9 (0x08UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_10 (0x09UL)
|
||||
#define ADC_EXT_SAMPLE_NUM_11 (0x0AUL)
|
||||
#define ADC_EXT_SAMPLE_NUM_12 (0x0BUL)
|
||||
#define ADC_EXT_SAMPLE_NUM_13 (0x0CUL)
|
||||
#define ADC_EXT_SAMPLE_NUM_14 (0x0DUL)
|
||||
#define ADC_EXT_SAMPLE_NUM_15 (0x0EUL)
|
||||
#define ADC_EXT_SAMPLE_NUM_16 (0x0FUL)
|
||||
|
||||
#define ADC_RF_CTL_PD_GADC_POWERDOWN (0x01UL)
|
||||
#define ADC_RF_CTL_PD_GADC_WAKWUP (0x00UL)
|
||||
|
||||
#define ADC_RF_CTL_REFSEL_AVDD (0x01UL)
|
||||
#define ADC_RF_CTL_REFSEL_2_4 (0x00UL)
|
||||
|
||||
#define ADC_RF_CTL_ADC_CTL_MUX_DIGITAL (0x01UL)
|
||||
#define ADC_RF_CTL_ADC_CTL_MUX_SPI (0x00UL)
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int value_2 : 12;
|
||||
unsigned int chanel_2 : 4;
|
||||
unsigned int value_1 : 12;
|
||||
unsigned int chanel_1 : 4;
|
||||
} ADC_FIFO_TypeDef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ADC_CH0_PIN21 = 0,
|
||||
ADC_CH1_PIN20 = 1,
|
||||
ADC_CH2_PIN19 = 2,
|
||||
ADC_CH3_PIN18 = 3,
|
||||
ADC_CH4_PIN0 = 4,
|
||||
ADC_CH5_PIN1 = 5,
|
||||
ADC_CH6_PIN4 = 6,
|
||||
ADC_CH7_PIN5 = 7,
|
||||
ADC_CH8_NOPIN = 8, // cmp0
|
||||
ADC_CH9_NOPIN = 9, // cmp1
|
||||
ADC_CH10_NOPIN = 10, // cmp2
|
||||
ADC_CH11_NOPIN = 11, // pga
|
||||
ADC_CH12_PIN2 = 12,
|
||||
ADC_CH13_PIN3 = 13,
|
||||
ADC_CH14_PIN6 = 14,
|
||||
ADC_CH15_PIN7 = 15,
|
||||
} ADC_ChannelTypeDef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ADC_REF_VOL_2_48V = 0,
|
||||
ADC_REF_VOL_3_3V = 1,
|
||||
} ADC_RefVolTypeDef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ADC_FREQ_8M = 0x00,
|
||||
ADC_FREQ_4M = 0x01,
|
||||
ADC_FREQ_2M = 0x03,
|
||||
ADC_FREQ_1M = 0x07,
|
||||
ADC_FREQ_500K = 0x0f,
|
||||
} ADC_FreqTypeDef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// Single-ended mode. PSELN will be ignored, negative input to ADC shorted
|
||||
// to GND.
|
||||
ADC_SAMPMODE_SINGLE_ENDED = 0x00UL,
|
||||
ADC_SAMPMODE_DIFFERENTIAL = 0x01UL // Differential mode.
|
||||
} ADC_SampModeTypeDef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ADC_SAMPEDGE_FALL = 0x00UL, ///< Single-ended mode. PSELN will be ignored,
|
||||
///< negative input to ADC shorted to GND.
|
||||
ADC_SAMPEDGE_RISE = 0x01UL ///< Differential mode.
|
||||
} ADC_SampEdgeTypeDef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ADC_RefVolTypeDef_t RefVol;
|
||||
ADC_FreqTypeDef_t Freq;
|
||||
ADC_SampEdgeTypeDef_t SampEdge;
|
||||
uint32_t ExtSampleNum;
|
||||
uint32_t ExtDataMode;
|
||||
uint32_t ExtTriggerSel;
|
||||
uint32_t ExtEdgeSel;
|
||||
} ADC_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
static __inline void xc_adc_fifo_flush(void)
|
||||
{
|
||||
adc_fifo_ctl__fifo_flush__setf(ADC_FIFO_CTL_FIFO_FLUSH_SET);
|
||||
adc_fifo_ctl__fifo_flush__setf(ADC_FIFO_CTL_FIFO_FLUSH_RESET);
|
||||
}
|
||||
|
||||
static __inline void xc_adc_refvol_set(uint8_t ref_vol)
|
||||
{
|
||||
adc_rf_ctl__pd_adc__setf(DISABLE);
|
||||
|
||||
if (ref_vol == ADC_REF_VOL_2_48V) {
|
||||
adc_rf_ctl__gadc_vref_sel__setf(ADC_RF_CTL_REFSEL_2_4);
|
||||
|
||||
} else {
|
||||
adc_rf_ctl__gadc_vref_sel__setf(ADC_RF_CTL_REFSEL_AVDD);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void xc_adc_freq_set(uint8_t freq)
|
||||
{
|
||||
adc_rf_ctl__adc_clkdiv__setf(freq);
|
||||
adc_rf_ctl__adc_ctl_mux__setf(ADC_RF_CTL_ADC_CTL_MUX_DIGITAL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_adc_init(ADC_InitCfg_t *adc_cfg);
|
||||
void xc_adc_start_get_value(ADC_ChannelTypeDef_t Channel, uint16_t *adc_val);
|
||||
|
||||
void xc_adc_enable_it(uint8_t it);
|
||||
void xc_adc_disable_it(uint8_t it);
|
||||
void xc_adc_fifo_req_len_set(uint8_t len);
|
||||
void xc_adc_wait_time_set(uint8_t timer0, uint16_t timer1);
|
||||
void xc_adc_ch_auto_enable(void);
|
||||
void xc_adc_ch_auto_disable(void);
|
||||
void xc_adc_ch_auto_set(uint8_t ch);
|
||||
void xc_adc_ch_not_auto_set(uint8_t ch);
|
||||
void xc_adc_it_set(uint8_t it);
|
||||
uint8_t xc_adc_it_get(void);
|
||||
void xc_adc_ch_not_auto_set(uint8_t ch);
|
||||
uint32_t xc_adc_data_get(void);
|
||||
void xc_adc_enable(void);
|
||||
void xc_adc_disable(void);
|
||||
uint16_t xc_adc_it_collectval_get(void);
|
||||
void xc_adc_channel_gpio_config(ADC_ChannelTypeDef_t Channel);
|
||||
|
||||
void adc_intr_callback(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,220 @@
|
||||
/*!
|
||||
* \file xc_drv_aotimer.c
|
||||
*
|
||||
* \brief Target xinchip aotimer driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_aotimer.h"
|
||||
#if (AOTIMER_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static bool aotimer_rst_flag = false;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
aotimer_handler_callback aotimer_n_callback[2] = {aotimer0_callback,
|
||||
aotimer1_callback};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_aotimer_init
|
||||
* @details Example Initialize the aotimer according to its number
|
||||
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
|
||||
* @param[in] *init_cfg : This is the structure parameter that the AOTimer initializes
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_aotimer_init(uint8_t reg_idx, AOTimer_InitCfg_t *init_cfg)
|
||||
{
|
||||
if (aotimer_rst_flag == false) {
|
||||
cprao_aon_clken_grctl__timer_ao_pclk_en__setf(ENABLE);
|
||||
aotimer_rst_flag = true;
|
||||
}
|
||||
|
||||
//The clocks for ao timer0 and ao timer1 need to be turned on at the same time.
|
||||
if (AOTIMER0_IDX == reg_idx) {
|
||||
cprao_aon_clken_grctl__timer0_ao_pclk_en__setf(ENABLE);
|
||||
cprao_aon_clken_grctl__timer1_ao_pclk_en__setf(ENABLE);
|
||||
} else if (AOTIMER1_IDX == reg_idx) {
|
||||
cprao_aon_clken_grctl__timer0_ao_pclk_en__setf(ENABLE);
|
||||
cprao_aon_clken_grctl__timer1_ao_pclk_en__setf(ENABLE);
|
||||
}
|
||||
cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);
|
||||
|
||||
aotimer_tcr__tes__setf(reg_idx, DISABLE);
|
||||
aotimer_tcr__tms__setf(reg_idx, (uint8_t)init_cfg->aotimer_mode);
|
||||
(void)aotimer_tic__tic__getf(reg_idx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_aotimer_us_to_ticks
|
||||
* @details Returns the number of ticks according to the time to be set by the aotimer
|
||||
* @param[in] us : Time set by the timer (Microsecond is the smallest unit)
|
||||
|
||||
* @param[out] void
|
||||
* @retval ticks ( Tick count )
|
||||
***************************************************************************************
|
||||
*/
|
||||
static uint32_t xc_aotimer_us_to_ticks(uint32_t us)
|
||||
{
|
||||
uint32_t ticks = AOTIMER_TICK_CAL(us);
|
||||
|
||||
if (ticks < AOTIMER_MIN_TLC_VAL)
|
||||
ticks = AOTIMER_MIN_TLC_VAL;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_aotimer_set_value
|
||||
* @details Set the timing time according to the aotimer number
|
||||
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
|
||||
* @param[in] us : Time set by the timer (Microsecond is the smallest unit)
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_aotimer_set_value(uint8_t reg_idx, uint32_t us)
|
||||
{
|
||||
uint32_t ticks = xc_aotimer_us_to_ticks(us);
|
||||
|
||||
aotimer_tcr__tes__setf(reg_idx, AOTIMER_TCR_TES_DISABLE);
|
||||
|
||||
aotimer_tlc_set(reg_idx, ticks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_aotimer_start
|
||||
* @details Start the timer according to the aotimer number
|
||||
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_aotimer_start(uint8_t reg_idx)
|
||||
{
|
||||
NVIC_EnableIRQ( (IRQn_Type)(TIMER_AO0_IRQn+reg_idx) );
|
||||
aotimer_tcr__tim__setf(reg_idx, 0);
|
||||
aotimer_tcr__tes__setf(reg_idx, ENABLE);
|
||||
// Wait for timer enable
|
||||
while(aotimer_tcr__tes__getf(reg_idx) != ENABLE)
|
||||
{
|
||||
__nop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_aotimer_stop
|
||||
* @details Stop the timer according to the aotimer number
|
||||
* @param[in] reg_idx : aotimer number idx; AOTIMER0_IDX or AOTIMER1_IDX
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_aotimer_stop(uint8_t reg_idx)
|
||||
{
|
||||
aotimer_tcr__tes__setf(reg_idx, DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief AOTIMER0_Handler
|
||||
* @details AOTIMER0 Interrupt function
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void AOTIMER0_Handler(void)
|
||||
{
|
||||
cprao_aon_reg1__timer_ao_sleep_clksw__setf(0);
|
||||
(void)aotimer_tic__tic__getf(AOTIMER0_IDX);
|
||||
if (aotimer_n_callback[0] != NULL)
|
||||
aotimer_n_callback[0](NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief AOTIMER1_Handler
|
||||
* @details AOTIMER1 Interrupt function
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void AOTIMER1_Handler(void)
|
||||
{
|
||||
cprao_aon_reg1__timer_ao_sleep_clksw__setf(0);
|
||||
(void)aotimer_tic__tic__getf(AOTIMER1_IDX);
|
||||
if (aotimer_n_callback[1] != NULL)
|
||||
aotimer_n_callback[1](NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief aotimer0_callback
|
||||
* @details AOTIMER0 Interrupt the callback function
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
__WEAK void aotimer0_callback(void *context)
|
||||
{ /* AOTimer0 中断回调处理事件 */
|
||||
}
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief aotimer1_callback
|
||||
* @details AOTIMER1 Interrupt the callback function
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
__WEAK void aotimer1_callback(void *context)
|
||||
{ /* AOTimer1 中断回调处理事件 */
|
||||
}
|
||||
#endif //(AOTIMER_ON)
|
||||
@@ -0,0 +1,78 @@
|
||||
/*!
|
||||
* \file xc_drv_aotimer.h
|
||||
*
|
||||
* \brief The header of xc_drv_aotimer.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_AOTIMER_H_
|
||||
#define _XC_DRV_AOTIMER_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define AOTIMER_MIN_TLC_VAL 0x04
|
||||
|
||||
#define AOTIMER_TCR_TIM_DISABLE (0x00UL)
|
||||
#define AOTIMER_TCR_TIM_ENABLE (0x01UL)
|
||||
|
||||
#define AOTIMER_TCR_TES_ENABLE (0x01UL)
|
||||
#define AOTIMER_TCR_TES_DISABLE (0x00UL)
|
||||
|
||||
#define AOTIMER_TICK_CAL(us) ((CLOCK_RC_LFCLK_IN_32K / 1000) * us / 1000)
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AOTIMER_MODE_SINGLE = 0,
|
||||
AOTIMER_MODE_CYCLE = 1,
|
||||
} AOTimer_ModeTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AOTimer_ModeTypeDef aotimer_mode;
|
||||
|
||||
} AOTimer_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef void (*aotimer_handler_callback)(void *context);
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_aotimer_init(uint8_t reg_idx, AOTimer_InitCfg_t *init_cfg);
|
||||
void xc_aotimer_set_value(uint8_t reg_idx, uint32_t us);
|
||||
void xc_aotimer_start(uint8_t reg_idx);
|
||||
void xc_aotimer_stop(uint8_t reg_idx);
|
||||
|
||||
void aotimer0_callback(void *context);
|
||||
void aotimer1_callback(void *context);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,424 @@
|
||||
/*!
|
||||
* \file xc_drv_calib.c
|
||||
*
|
||||
* \brief Target xc calib driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_calib.h"
|
||||
#if (CALIB_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define RC_ADJ_VAL_MIN 0x0
|
||||
#define RC_ADJ_VAL_MID 0x1fff
|
||||
#define RC_ADJ_VAL_MAX 0x3fff
|
||||
|
||||
#define RANGE_LPO_RTM 0x400
|
||||
#define GEARS_HZ 1.56f
|
||||
#define _32K_STAND_HZ 32000
|
||||
|
||||
#define CALIB_NUM 50 // ms
|
||||
|
||||
#define CALIB_TIME_MS 10 // ms
|
||||
#define CALIB_DELAY_CHECK (CALIB_TIME_MS + 20) // ms
|
||||
|
||||
#define CALIB_STEP_CYCLE_32K (CALIB_TIME_MS * 32)
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static volatile uint32_t mid = RC_ADJ_VAL_MID; // MID_LPO_RTM;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief xc_rc32k_calib_init
|
||||
* @details RC32k calibration initialization
|
||||
*
|
||||
* @param uint16_t - rc_adj_val
|
||||
* @retval void
|
||||
*/
|
||||
|
||||
void xc_rc32k_calib_init(uint16_t rc_adj_val)
|
||||
{
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M)) {
|
||||
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(4U);
|
||||
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)) {
|
||||
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(2U);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M)) {
|
||||
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1UL);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(8U);
|
||||
}
|
||||
|
||||
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(0x1UL);
|
||||
|
||||
cprao_aon_clken_grctl__rtc_clk_en__setf(0x1UL);
|
||||
|
||||
rtc_rccal_lfcfg_set(0x100031);
|
||||
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
|
||||
rtc_rccal_hfcfg_set(25000);
|
||||
rtc_rccal_lim1_set(3);
|
||||
rtc_rccal_lim2_set(13);
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)) {
|
||||
|
||||
rtc_rccal_hfcfg_set(37500);
|
||||
rtc_rccal_lim1_set(4);
|
||||
rtc_rccal_lim2_set(19);
|
||||
}
|
||||
|
||||
rtc_rccal_adj_step_set(0x1404);
|
||||
rtc_rccal_adj_val_set(0x1fff);
|
||||
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | rc_adj_val);
|
||||
rtc_rccal_intsta_set(0x03);
|
||||
rtc_rccal_inten_set(0x01);
|
||||
for (uint16_t dly = 0; dly < 1000; dly++)
|
||||
;
|
||||
rtc_rccal_en_set(0x01);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_flfclk_calcu
|
||||
* @details Frequency lfclk value calculation
|
||||
*
|
||||
* @param uint32_t - hfcnt_val
|
||||
* @retval uint16_t - f_lfclk
|
||||
*/
|
||||
uint16_t xc_flfclk_calcu(uint32_t hfcnt_val)
|
||||
{
|
||||
uint32_t hfcnt_load = rtc_rccal_hfcfg_get();
|
||||
uint32_t lfdiv = rtc_rccal_lfcfg_get();
|
||||
|
||||
uint8_t hfcnt_dir = (hfcnt_val >> 31);
|
||||
uint16_t f_lfclk = 0;
|
||||
|
||||
if (hfcnt_dir == 0) {
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk =
|
||||
CLOCK_HFCLK_IN_16M * (lfdiv + 1) / (hfcnt_load - hfcnt_val);
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)) {
|
||||
f_lfclk = 24000000 * (lfdiv + 1) / (hfcnt_load - hfcnt_val);
|
||||
}
|
||||
} else {
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk = CLOCK_HFCLK_IN_16M * (lfdiv + 1) /
|
||||
(hfcnt_load + hfcnt_val - 0x80000000);
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)) {
|
||||
f_lfclk =
|
||||
24000000 * (lfdiv + 1) / (hfcnt_load + hfcnt_val - 0x80000000);
|
||||
}
|
||||
}
|
||||
|
||||
return f_lfclk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_rc32k_freq_scope
|
||||
* @details RC32k frequency scope
|
||||
*
|
||||
* @param uint16_t - freq
|
||||
* @retval eLFREQ_Sta - ret
|
||||
*/
|
||||
eLFREQ_Sta xc_rc32k_freq_scope(uint16_t freq)
|
||||
{
|
||||
eLFREQ_Sta ret = LFREQ_UNKNOW;
|
||||
uint16_t offset = (CLOCK_RC_LFCLK_IN_32K * 2 / 100);
|
||||
uint16_t rc32_offset_min = (CLOCK_RC_LFCLK_IN_32K - offset);
|
||||
uint16_t rc32_offset_max = CLOCK_RC_LFCLK_IN_32K;
|
||||
|
||||
if (freq < rc32_offset_min)
|
||||
ret = LFREQ_LOWER;
|
||||
else if (freq >= rc32_offset_max)
|
||||
ret = LFREQ_HIGHER;
|
||||
else
|
||||
ret = LFREQ_GOOD;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RC32k_Calib_by_hw
|
||||
* @details Calibrating RC32k through hardware.
|
||||
*
|
||||
* @param uint16_t - freq
|
||||
* @retval eLFREQ_Sta - ret
|
||||
*/
|
||||
void xc_rc32k_calib_by_hw(void)
|
||||
{
|
||||
uint16_t f_lfclk = 0;
|
||||
uint8_t rccal_int_sta;
|
||||
eLFREQ_Sta f_lf_sta;
|
||||
|
||||
xc_rc32k_calib_init(mid);
|
||||
|
||||
while (1) {
|
||||
|
||||
do {
|
||||
rccal_int_sta = rtc_rccal_intsta_get();
|
||||
} while (!(rccal_int_sta & 0x01));
|
||||
|
||||
rtc_rccal_inten_set(0x00);
|
||||
rtc_rccal_intsta_set(rccal_int_sta);
|
||||
|
||||
f_lfclk = xc_flfclk_calcu(rtc_rccal_hfcnt_val_get());
|
||||
|
||||
f_lf_sta = xc_rc32k_freq_scope(f_lfclk);
|
||||
if (LFREQ_GOOD != f_lf_sta) {
|
||||
rtc_rccal_en_set(0x00);
|
||||
// XC_RTC->RCCAL_EN = 0x00;
|
||||
if (f_lf_sta == LFREQ_LOWER) {
|
||||
mid += 100;
|
||||
if (mid > RC_ADJ_VAL_MAX) {
|
||||
mid = RC_ADJ_VAL_MIN;
|
||||
}
|
||||
} else {
|
||||
mid -= 10;
|
||||
if (mid < 10) {
|
||||
mid = RC_ADJ_VAL_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
rtc_rccal_inten_set(0x01);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
} else {
|
||||
DEBUG("f_lfclk: %d\n", f_lfclk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x00001fff);
|
||||
rtc_rccal_adj_cfg__freq_adj_offset__setf(mid);
|
||||
rtc_rccal_adj_cfg__freq_adj_hw_clr__setf(0x01);
|
||||
rtc_rccal_intsta_set(0x03);
|
||||
|
||||
for (uint16_t dly = 0; dly < 1000; dly++)
|
||||
;
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief rc32k_calib_by_soft
|
||||
* @details Calibrate RC32k by software.
|
||||
*
|
||||
* @param uint16_t - freq
|
||||
* @retval eLFREQ_Sta - ret
|
||||
*/
|
||||
void xc_rc32k_calib_by_soft(void)
|
||||
{
|
||||
uint32_t f_lfclk = 0;
|
||||
uint32_t t32k_cnt = 0;
|
||||
uint8_t ao_intr;
|
||||
|
||||
xc_rc32k_calib_init(mid);
|
||||
|
||||
rtc_rccal_inten_set(0x00);
|
||||
rtc_rccal_intsta_set(0x03);
|
||||
while (1) {
|
||||
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(CALIB_STEP_CYCLE_32K);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
||||
|
||||
do {
|
||||
|
||||
ao_intr = rtc_all_intr_ao_get();
|
||||
} while ((ao_intr & 0x20) == 0);
|
||||
|
||||
t32k_cnt = rtc_freq_32k_timer_val_get();
|
||||
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk = (uint32_t)((((float)((16.0) * CALIB_STEP_CYCLE_32K)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)) {
|
||||
f_lfclk = (uint32_t)((((float)((24.0) * CALIB_STEP_CYCLE_32K)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
}
|
||||
|
||||
if (f_lfclk > _32K_STAND_HZ) {
|
||||
mid = mid - ((uint32_t)(((float)(f_lfclk - _32K_STAND_HZ)) /
|
||||
(float)GEARS_HZ));
|
||||
} else if (f_lfclk < _32K_STAND_HZ) {
|
||||
mid = mid + ((uint32_t)(((float)(_32K_STAND_HZ - f_lfclk)) /
|
||||
(float)GEARS_HZ));
|
||||
}
|
||||
DEBUG("f_lfclk: %d\n", f_lfclk);
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
|
||||
if (f_lfclk == _32K_STAND_HZ)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_rc32k_soft_calib_start
|
||||
* @details Calibrate RC32k by software.only for 32M
|
||||
*
|
||||
* @param
|
||||
* @retval
|
||||
*/
|
||||
void xc_rc32k_soft_calib_start(void)
|
||||
{
|
||||
|
||||
uint32_t f_lfclk = 0;
|
||||
uint32_t t32k_cnt = 0;
|
||||
uint8_t ao_intr;
|
||||
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(32);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
||||
|
||||
do {
|
||||
ao_intr = rtc_all_intr_ao_get();
|
||||
} while ((ao_intr & 0x20) == 0);
|
||||
|
||||
t32k_cnt = rtc_freq_32k_timer_val_get();
|
||||
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
|
||||
f_lfclk = (uint32_t)((((512000000)) / t32k_cnt)); //16.0*32
|
||||
|
||||
if (f_lfclk > 32000) {
|
||||
mid = mid - ((uint32_t)(((float)(f_lfclk - 32000)) /
|
||||
(float)GEARS_HZ));
|
||||
} else if (f_lfclk < 32000) {
|
||||
mid = mid + ((uint32_t)(((float)(32000 - f_lfclk)) /
|
||||
(float)GEARS_HZ));
|
||||
}
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
|
||||
}
|
||||
|
||||
#define TIME_32K_CNT (32*2)
|
||||
#define ADJ_MAX (2)
|
||||
void xc_rc32k_soft_calib_enable(void)
|
||||
{
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_value__setf(TIME_32K_CNT);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(1);
|
||||
NVIC_EnableIRQ(RTC_IRQn);
|
||||
}
|
||||
|
||||
void xc_rc32k_soft_calib_disable(void)
|
||||
{
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
rtc_ao_timer_ctl__rtc_freq_timer_en__setf(0);
|
||||
NVIC_DisableIRQ(RTC_IRQn);
|
||||
}
|
||||
|
||||
void xc_rc32k_soft_calib_set(void)
|
||||
{
|
||||
uint32_t f_lfclk = 0;
|
||||
uint32_t t32k_cnt = 0;
|
||||
|
||||
t32k_cnt = rtc_freq_32k_timer_val_get();
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(0x1UL);
|
||||
rtc_ao_timer_ctl_set(0);
|
||||
|
||||
if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_16M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M)) {
|
||||
f_lfclk = (uint32_t)((((float)((16.0) * TIME_32K_CNT)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
} else if ((xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) ||
|
||||
(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_96M)) {
|
||||
f_lfclk = (uint32_t)((((float)((24.0) * TIME_32K_CNT)) /
|
||||
t32k_cnt) *
|
||||
1000000);
|
||||
}
|
||||
|
||||
if (f_lfclk > 32000) {
|
||||
uint32_t diff = (uint32_t)(((float)(f_lfclk - 32000)) /
|
||||
(float)GEARS_HZ);
|
||||
if(diff > ADJ_MAX){
|
||||
diff = ADJ_MAX;
|
||||
}
|
||||
mid = mid - diff;
|
||||
} else if (f_lfclk < 32000) {
|
||||
uint32_t diff = (uint32_t)(((float)(32000 - f_lfclk)) /
|
||||
(float)GEARS_HZ);
|
||||
if(diff > ADJ_MAX){
|
||||
diff = ADJ_MAX;
|
||||
}
|
||||
mid = mid + diff;
|
||||
}
|
||||
|
||||
rtc_rccal_en_set(0x00);
|
||||
rtc_rccal_adj_cfg_set(0x1fff4000 | mid);
|
||||
|
||||
rtc_rccal_en_set(0x01);
|
||||
}
|
||||
#endif //(CALIB_ON)
|
||||
@@ -0,0 +1,73 @@
|
||||
/*!
|
||||
* \file xc_drv_calib.h
|
||||
*
|
||||
* \brief The header of xc_drv_calib.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_CALIB_H_
|
||||
#define _XC_DRV_CALIB_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define RC32K_CALIB_BY_HW 0
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LFREQ_GOOD = 0,
|
||||
LFREQ_LOWER,
|
||||
LFREQ_HIGHER,
|
||||
LFREQ_UNKNOW = 0xff
|
||||
} eLFREQ_Sta;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOCK_RC_LFCLK_IN_32K = 32000,
|
||||
CLOCK_XTAL_LFCLK_IN_32K = 32768,
|
||||
} CLOCK_LowFreq_In_Typedef;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_rc32k_calib_by_hw(void);
|
||||
void xc_rc32k_calib_by_soft(void);
|
||||
|
||||
#endif // _XC_DRV_AOTIMER_H_
|
||||
@@ -0,0 +1,518 @@
|
||||
/*!
|
||||
* \file xc_drv_clock.c
|
||||
*
|
||||
* \brief Target xinchip clock driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_clock.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
CLOCK_InitCfg_t clock_cb;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_bbpll_common_cfg
|
||||
* @details Common Settings for frequency doubling
|
||||
* @param[in] void
|
||||
* @param[in] void
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_bbpll_common_cfg(void)
|
||||
{
|
||||
cpr_bt_clk_ctl__bt_clk_en__setf(ENABLE);
|
||||
cpr_ctlapbclken_grctl__bt_pclk_en__setf(ENABLE);
|
||||
bt_rf_pm_reg__bt_en_pm__setf(ENABLE);
|
||||
cprao_aon_coreldo_en_set(ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_bbpll_freq_cfg
|
||||
* @details Initializes the frequency doubling clock
|
||||
* @param[in] hfclk_src :Source clock
|
||||
* @param[in] loopdiv :clock multiplier factor
|
||||
* @param[in] clk_div :Frequency division coefficient
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_bbpll_freq_cfg(CLOCK_HFCLK_Src_Typedef hfclk_src, uint16_t loopdiv,
|
||||
uint8_t clk_div)
|
||||
{
|
||||
if (CLOCK_HFCLK_SRC_RC == hfclk_src)
|
||||
rf_ana27__bbpll_16m_sel__setf(ENABLE);
|
||||
else
|
||||
rf_ana27__bbpll_16m_sel__setf(DISABLE);
|
||||
|
||||
if(loopdiv != 0x03)
|
||||
rf_ana27__bbpll_core_96m_en__setf(ENABLE);
|
||||
else
|
||||
rf_ana27__bbpll_core_96m_en__setf(DISABLE);
|
||||
rf_ana26__bbpll_loopdiv__setf(loopdiv);
|
||||
rf_ana26__clk_bbpll_en__setf(ENABLE);
|
||||
rf_ana26__clk_bbpll_rstn__setf(ENABLE);
|
||||
rf_ana26__bbpll_en__setf(ENABLE);
|
||||
rf_ana26__bbpll_core_64m_en__setf(ENABLE);
|
||||
|
||||
cpr_rf_reg4__bbpll_clk_div__setf(clk_div);
|
||||
cpr_rf_reg4__bbpll_clk_en__setf(ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_rc16m
|
||||
* @details The clock is set to RC16M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_rc16m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_RC16M);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_16M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_16M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_rc16m_bbpll_32m
|
||||
* @details RC16M clock overclocked to 32M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_rc16m_bbpll_32m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x08, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL_DIV);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_32M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_32M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_rc16m_bbpll_48m
|
||||
* @details RC16M clock overclocked to 48M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_rc16m_bbpll_48m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x0C, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL_DIV);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_48M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_48M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_rc16m_bbpll_64m
|
||||
* @details RC16M clock overclocked to 64M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_rc16m_bbpll_64m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x08, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_64M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_64M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_rc16m_bbpll_96m
|
||||
* @details RC16M clock overclocked to 96M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_rc16m_bbpll_96m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x0C, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_96M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_96M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m_bbpll_16m
|
||||
* @details osc32M Clock overclocked to 16M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m_bbpll_16m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x06, 0x05);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL_DIV);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_16M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_16M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m_div_16m
|
||||
* @details osc32M Clock divided into 16M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m_div_16m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
//M0_FCLK
|
||||
cpr_m0_fclk_ctl__m0_fclk_div_p__setf(0x1);
|
||||
cpr_m0_fclk_ctl__m0_fclk_direct_sw__setf(0x1);
|
||||
//CTL_PCLK
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr__setf(0x8);
|
||||
cpr_ctl_pclk_grctl__ctl_pclk_gr_upd__setf(0x1);
|
||||
|
||||
cprao_aon_bbldo_adj_set(0x3c);
|
||||
/* The value needs to be configured to 7,
|
||||
otherwise the current drop will be slower during sleep
|
||||
and the clock accuracy of the rc32k will be affected.
|
||||
*/
|
||||
cprao_aon_lpoldo_adj_set(0x7);
|
||||
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_16M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_16M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m
|
||||
* @details The clock is set to osc32M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_OSC32M);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_32M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_32M;
|
||||
}
|
||||
|
||||
#if (CONFIG_HFCLK_IS_OSC32M_PLL_32M)
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m_bbpll_32m
|
||||
* @details osc32M Clock overclocked to 64M and hflck is 32M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m_bbpll_32m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x04, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL_DIV);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_32M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_32M;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m_bbpll_48m
|
||||
* @details osc32M Clock overclocked to 48M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m_bbpll_48m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x03, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL_DIV);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_48M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_48M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m_bbpll_64m
|
||||
* @details osc32M Clock overclocked to 64M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m_bbpll_64m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x04, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_64M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_64M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_set_osc32m_bbpll_96m
|
||||
* @details osc32M Clock overclocked to 96M
|
||||
* @param[in] CLOCK_InitCfg_t *cb
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_set_osc32m_bbpll_96m(CLOCK_InitCfg_t *cb)
|
||||
{
|
||||
xc_clock_bbpll_common_cfg();
|
||||
xc_clock_bbpll_freq_cfg(cb->hfclk_src, 0x03, 0x01);
|
||||
|
||||
cpr_rf_reg3__mclk_src_sel__setf(CLOCK_SRC_BBPLL);
|
||||
cb->hfclk_in = CLOCK_HFCLK_IN_96M;
|
||||
cb->systick_unit = SYSTICK_UNIT_IN_96M;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_hfclk_set
|
||||
* @details High speed clock setting
|
||||
* @param[in] CLOCK_HFCLK_Src_Typedef hfclk_src
|
||||
* @param[in] CLOCK_HFCLK_In_Typedef hfclk_in
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_hfclk_set(CLOCK_HFCLK_Src_Typedef hfclk_src,
|
||||
CLOCK_HFCLK_In_Typedef hfclk_in)
|
||||
{
|
||||
uint32_t baudrate, uart_clk, div, mul, clk_ctl, adj_div, m0_fclk_div;
|
||||
CLOCK_InitCfg_t *pclock_cb = &clock_cb;
|
||||
pclock_cb->hfclk_src = hfclk_src;
|
||||
|
||||
switch (hfclk_src) {
|
||||
case CLOCK_HFCLK_SRC_RC: {
|
||||
if (CLOCK_HFCLK_IN_16M == hfclk_in) {
|
||||
xc_clock_set_rc16m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_32M == hfclk_in) {
|
||||
xc_clock_set_rc16m_bbpll_32m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_48M == hfclk_in) {
|
||||
xc_clock_set_rc16m_bbpll_48m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_64M == hfclk_in) {
|
||||
xc_clock_set_rc16m_bbpll_64m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_96M == hfclk_in) {
|
||||
xc_clock_set_rc16m_bbpll_96m(pclock_cb);
|
||||
}
|
||||
} break;
|
||||
|
||||
case CLOCK_HFCLK_SRC_XTAL: {
|
||||
// if(cpr_m0_fclk_ctl__m0_fclk_div__getf( )) {
|
||||
// cpr_m0_fclk_ctl__m0_fclk_div_p__setf(0);
|
||||
// cpr_m0_fclk_ctl__m0_fclk_direct_sw__setf(0x1);
|
||||
// }
|
||||
|
||||
if (CLOCK_HFCLK_IN_16M == hfclk_in) {
|
||||
xc_clock_set_osc32m_div_16m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_32M == hfclk_in) {
|
||||
#if (CONFIG_HFCLK_IS_OSC32M_PLL_32M)
|
||||
xc_clock_set_osc32m_bbpll_32m(pclock_cb);
|
||||
#else
|
||||
xc_clock_set_osc32m(pclock_cb);
|
||||
#endif
|
||||
} else if (CLOCK_HFCLK_IN_48M == hfclk_in) {
|
||||
xc_clock_set_osc32m_bbpll_48m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_64M == hfclk_in) {
|
||||
xc_clock_set_osc32m_bbpll_64m(pclock_cb);
|
||||
} else if (CLOCK_HFCLK_IN_96M == hfclk_in) {
|
||||
xc_clock_set_osc32m_bbpll_96m(pclock_cb);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
m0_fclk_div = cpr_m0_fclk_ctl__m0_fclk_div__getf( );
|
||||
uart_clk = xc_clock_hfclk_in_get() * (m0_fclk_div+1);
|
||||
baudrate = cpr_uart0_clk_ctl_get();
|
||||
mul = (baudrate >> 16) & 0xFFFF;
|
||||
div = (baudrate & 0xFFFF);
|
||||
|
||||
adj_div = uart_clk / 1000000;
|
||||
clk_ctl = (mul << 16) | (div * adj_div / 32);
|
||||
cpr_uart0_clk_ctl_set(clk_ctl);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_lfclk_set
|
||||
* @details Low speed clock setting
|
||||
* @param[in] CLOCK_LFCLK_Src_Typedef lfclk_src
|
||||
* @param[in] CLOCK_LFCLK_In_Typedef lfclk_in
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_lfclk_set(CLOCK_LFCLK_Src_Typedef lfclk_src,
|
||||
CLOCK_LFCLK_In_Typedef lfclk_in)
|
||||
{
|
||||
clock_cb.lfclk_src = lfclk_src;
|
||||
clock_cb.lfclk_in = lfclk_in;
|
||||
|
||||
if(lfclk_src == CLOCK_LFCLK_SRC_XTAL)
|
||||
{
|
||||
GPIO_InitCfg_t gpio_cfg = {0};
|
||||
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
gpio_cfg.FunSel = GPIO_Dx;
|
||||
gpio_cfg.Dir = GPIO_DIR_INPUT;
|
||||
gpio_cfg.Pull = GPIO_NOPULL;
|
||||
gpio_cfg.Int = NOT_INT;
|
||||
gpio_cfg.Pin = 20;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
gpio_cfg.Pin = 21;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
cprao_aon_xtl32k_val__xtl32k_v__setf(0x01);
|
||||
cprao_aon_xtl32k_val__xtl32k_en__setf(ENABLE);
|
||||
cprao_aon_ctl_clk32k__osc32k_sel__setf(2);
|
||||
|
||||
}
|
||||
else if(lfclk_src == CLOCK_LFCLK_SRC_RC)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_init_cfg
|
||||
* @details Configure the clock initially
|
||||
* @param[in] CLOCK_InitCfg_t *clock_cfg
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_clock_init_cfg(CLOCK_InitCfg_t *clock_cfg)
|
||||
{
|
||||
xc_clock_hfclk_set(clock_cfg->hfclk_src, clock_cfg->hfclk_in);
|
||||
xc_clock_lfclk_set(clock_cfg->lfclk_src, clock_cfg->lfclk_in);
|
||||
xc_pwr_vol_set();
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_hfclk_in_get
|
||||
* @details Gets the current high speed clock ( system clock )
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval clock_cb.hfclk_in
|
||||
****************************************************************************************
|
||||
*/
|
||||
CLOCK_HFCLK_In_Typedef xc_clock_hfclk_in_get(void) { return clock_cb.hfclk_in; }
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_lfclk_in_get
|
||||
* @details Gets the current low speed clock ( Low power clock )
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval clock_cb.lfclk_in
|
||||
****************************************************************************************
|
||||
*/
|
||||
CLOCK_LFCLK_In_Typedef xc_clock_lfclk_in_get(void) { return clock_cb.lfclk_in; }
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_hfclk_src_get
|
||||
* @details Obtain the current high-speed source clock
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval clock_cb.hfclk_src
|
||||
****************************************************************************************
|
||||
*/
|
||||
CLOCK_HFCLK_Src_Typedef xc_clock_hfclk_src_get(void) { return clock_cb.hfclk_src; }
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_clock_lfclk_src_get
|
||||
* @details Obtain the current low-speed source clock
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval clock_cb.lfclk_src
|
||||
****************************************************************************************
|
||||
*/
|
||||
CLOCK_LFCLK_Src_Typedef xc_clock_lfclk_src_get(void) { return clock_cb.lfclk_src; }
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief xc_systick_unit_get
|
||||
* @details Obtain the current systick unit
|
||||
* @param[in]
|
||||
* @param[out] void
|
||||
* @retval clock_cb.lfclk_src
|
||||
****************************************************************************************
|
||||
*/
|
||||
Systick_Unit_Typedef xc_systick_unit_get(void) { return clock_cb.systick_unit; }
|
||||
@@ -0,0 +1,113 @@
|
||||
/*!
|
||||
* \file xc_drv_clock.h
|
||||
*
|
||||
* \brief The header of xc_drv_clock.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_CLOCK_H_
|
||||
#define _XC_DRV_CLOCK_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define CLOCK_SRC_OSC32M 0x00
|
||||
#define CLOCK_SRC_BBPLL 0x01
|
||||
#define CLOCK_SRC_BBPLL_DIV 0x02
|
||||
#define CLOCK_SRC_RC16M 0x03
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOCK_LFCLK_SRC_RC = 0, /* Internal 32 KHz RC oscillator. */
|
||||
CLOCK_LFCLK_SRC_XTAL = 1, /* External 32 KHz crystal oscillator. */
|
||||
} CLOCK_LFCLK_Src_Typedef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOCK_LFCLK_IN_32K = 32000,
|
||||
CLOCK_LFCLK_IN_32768 = 32768,
|
||||
} CLOCK_LFCLK_In_Typedef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOCK_HFCLK_SRC_RC = 0, /* Internal 16 MHz RC oscillator. */
|
||||
CLOCK_HFCLK_SRC_XTAL = 1, /* External 32 MHz crystal oscillator. */
|
||||
} CLOCK_HFCLK_Src_Typedef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOCK_HFCLK_IN_16M = 16000000,
|
||||
CLOCK_HFCLK_IN_32M = 32000000,
|
||||
CLOCK_HFCLK_IN_48M = 48000000,
|
||||
CLOCK_HFCLK_IN_64M = 64000000,
|
||||
CLOCK_HFCLK_IN_96M = 96000000,
|
||||
CLOCK_HFCLK_IN_128M = 128000000,
|
||||
|
||||
} CLOCK_HFCLK_In_Typedef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SYSTICK_UNIT_IN_16M = 16,
|
||||
SYSTICK_UNIT_IN_32M = 32,
|
||||
SYSTICK_UNIT_IN_48M = 48,
|
||||
SYSTICK_UNIT_IN_64M = 64,
|
||||
SYSTICK_UNIT_IN_96M = 96
|
||||
|
||||
} Systick_Unit_Typedef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLOCK_HFCLK_Src_Typedef hfclk_src;
|
||||
CLOCK_HFCLK_In_Typedef hfclk_in;
|
||||
|
||||
CLOCK_LFCLK_Src_Typedef lfclk_src;
|
||||
CLOCK_LFCLK_In_Typedef lfclk_in;
|
||||
|
||||
Systick_Unit_Typedef systick_unit;
|
||||
|
||||
} CLOCK_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern CLOCK_InitCfg_t clock_cb;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_clock_bbpll_common_cfg(void);
|
||||
void xc_clock_init_cfg(CLOCK_InitCfg_t *clock_cfg);
|
||||
CLOCK_HFCLK_In_Typedef xc_clock_hfclk_in_get(void);
|
||||
CLOCK_LFCLK_In_Typedef xc_clock_lfclk_in_get(void);
|
||||
CLOCK_HFCLK_Src_Typedef xc_clock_hfclk_src_get(void);
|
||||
CLOCK_LFCLK_Src_Typedef xc_clock_lfclk_src_get(void);
|
||||
Systick_Unit_Typedef xc_systick_unit_get(void);
|
||||
|
||||
#endif // _XC_DRV_CLOCK_H_
|
||||
@@ -0,0 +1,208 @@
|
||||
/*!
|
||||
* \file xc6xxx_conf.h
|
||||
*
|
||||
* \brief The header of xc6xxx config
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC6xxx_CONF_H__
|
||||
#define __XC6xxx_CONF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection
|
||||
* ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
|
||||
#define HAL_CLOCK_MODULE_ENABLED
|
||||
|
||||
#define HAL_SYSTICK_MODULE_ENABLED
|
||||
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
#define HAL_AOTIMER_MODULE_ENABLED
|
||||
|
||||
#define HAL_TIMER_MODULE_ENABLED
|
||||
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
|
||||
#define HAL_UART_DMA_MODULE_ENABLED
|
||||
|
||||
#define HAL_QDEC_MODULE_ENABLED
|
||||
|
||||
#define HAL_DMAC_MODULE_ENABLED
|
||||
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
|
||||
#define HAL_FMC_SPI_MODULE_ENABLED
|
||||
|
||||
#define HAL_FMC_SPI_DMA_MODULE_ENABLED
|
||||
|
||||
#define HAL_SPI_DMA_MODULE_ENABLED
|
||||
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
|
||||
#define HAL_WDT_MODULE_ENABLED
|
||||
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
|
||||
#define HAL_CAN_MODULE_ENABLED
|
||||
|
||||
#define SW_I2C_MODULE_ENABLED
|
||||
|
||||
#define HAL_PWM_MODULE_ENABLED
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_reg_cpr.h"
|
||||
#include "xc_reg_cprao.h"
|
||||
#include "xc_reg_offset.h"
|
||||
#include "xc_reg_rf.h"
|
||||
|
||||
#include "xc_reg_adc.h"
|
||||
#include "xc_reg_aotimer.h"
|
||||
#include "xc_reg_dma.h"
|
||||
#include "xc_reg_fmc.h"
|
||||
#include "xc_reg_fmc_cache.h"
|
||||
#include "xc_reg_gpio.h"
|
||||
#include "xc_reg_i2c.h"
|
||||
#include "xc_reg_qdec.h"
|
||||
#include "xc_reg_pwm.h"
|
||||
#include "xc_reg_pwm_comn.h"
|
||||
#include "xc_reg_rtc.h"
|
||||
#include "xc_reg_spi.h"
|
||||
#include "xc_reg_timer.h"
|
||||
#include "xc_reg_uart.h"
|
||||
#include "xc_reg_wdt.h"
|
||||
#include "xc_reg_pwm_timer.h"
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_CLOCK_MODULE_ENABLED
|
||||
#include "xc_drv_calib.h"
|
||||
#include "xc_drv_clock.h"
|
||||
|
||||
#endif /* HAL_CLOCK_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SYSTICK_MODULE_ENABLED
|
||||
#include "xc_drv_systick.h"
|
||||
#endif /* HAL_SYSTICK_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "xc_drv_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "xc_drv_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_AOTIMER_MODULE_ENABLED
|
||||
#include "xc_drv_aotimer.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_TIMER_MODULE_ENABLED
|
||||
#include "xc_drv_timer.h"
|
||||
#endif /* HAL_TIMER_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
|
||||
#include "xc_drv_rtc.h"
|
||||
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "xc_drv_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QDEC_MODULE_ENABLED
|
||||
#include "xc_reg_qdec.h"
|
||||
#endif /* HAL_QDEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMAC_MODULE_ENABLED
|
||||
#include "xc_drv_dma.h"
|
||||
#endif /* HAL_DMAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "xc_drv_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_DMA_MODULE_ENABLED
|
||||
#include "xc_drv_spi_dma.h"
|
||||
#endif /* HAL_SPI_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMC_SPI_MODULE_ENABLED
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
#include "xc6xxx_fmc_spi.h"
|
||||
#else
|
||||
#include "xc_drv_fmc_spi.h"
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
#endif /* HAL_FMC_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMC_SPI_DMA_MODULE_ENABLED
|
||||
#include "xc_drv_fmc_spi_dma.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAL_UART_DMA_MODULE_ENABLED
|
||||
#include "xc_drv_uart_dma.h"
|
||||
#endif /* HAL_UART_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "xc_drv_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef SW_I2C_MODULE_ENABLED
|
||||
#include "xc_drv_sw_i2c.h"
|
||||
#endif /* SW_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WDT_MODULE_ENABLED
|
||||
#include "xc_drv_wdt.h"
|
||||
#endif /* HAL_WDT_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "xc_drv_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWM_MODULE_ENABLED
|
||||
#include "xc_drv_pwm.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __XC6xxx_CONF_H__ */
|
||||
@@ -0,0 +1,823 @@
|
||||
/*!
|
||||
* \file xc_drv_dma.c
|
||||
*
|
||||
* \brief Target xinchip dma driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_dma.h"
|
||||
#if (DMA_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
DMA_Instance_t DMA_Instance;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief xc_dma_set_test_mode
|
||||
* @details DMAC test mode set
|
||||
*
|
||||
* @param uint8_t - mode
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE void xc_dma_set_test_mode(uint8_t mode)
|
||||
{
|
||||
dma_test_reg_set(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_set_channel_priority_order
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE void xc_dma_set_channel_priority_order(DMA_Instance_t *inst)
|
||||
{
|
||||
uint8_t priority[DMA_MAX_CHANNELS];
|
||||
uint8_t i, ch_priority, order;
|
||||
|
||||
for (i = 0; i < DMA_MAX_CHANNELS; i++) {
|
||||
priority[i] = 0;
|
||||
inst->Ch_Order[i] = i;
|
||||
}
|
||||
|
||||
for (uint8_t ch_num = 0; ch_num < DMA_MAX_CHANNELS; ch_num++) {
|
||||
// read the priority of the current channel
|
||||
ch_priority = dma_cfg_l__ch_prior__getf(ch_num);
|
||||
|
||||
// Check the channel order array to see what position
|
||||
// this channel comes in the priority list.
|
||||
for (i = 0; i <= DMA_MAX_CHANNELS; i++) {
|
||||
if (A_MAXEQ_B(ch_priority, priority[i]) || i == DMA_MAX_CHANNELS) {
|
||||
order = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we know the order for this channel insert in the correct
|
||||
// array position and shift current priority ordering to suite.
|
||||
for (i = ch_num; i > order; i--) {
|
||||
priority[i] = priority[i - 1];
|
||||
inst->Ch_Order[i] = inst->Ch_Order[i - 1];
|
||||
}
|
||||
priority[order] = ch_priority;
|
||||
inst->Ch_Order[order] = ch_num;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_reset_instance
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE void xc_dma_reset_instance(DMA_Instance_t *inst)
|
||||
{
|
||||
for (uint8_t i = 0; i < DMA_MAX_CHANNELS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
inst->Ch[i].ch_num = DMA_CHANNEL0;
|
||||
break;
|
||||
case 1:
|
||||
inst->Ch[i].ch_num = DMA_CHANNEL1;
|
||||
break;
|
||||
case 2:
|
||||
inst->Ch[i].ch_num = DMA_CHANNEL2;
|
||||
break;
|
||||
case 3:
|
||||
inst->Ch[i].ch_num = DMA_CHANNEL3;
|
||||
break;
|
||||
}
|
||||
|
||||
inst->Ch[i].userCallback = NULL;
|
||||
inst->Ch[i].userListener = NULL;
|
||||
}
|
||||
|
||||
// Set the channel priority order
|
||||
xc_dma_set_channel_priority_order(inst);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_check_channel_range
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_check_channel_range(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
|
||||
if (ch_num == DMA_NO_CHANNEL || ch_num > DMA_ALL_CHANNELS) {
|
||||
errorCode = DMA_ECHRNG;
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_check_channel_busy
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_check_channel_busy(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
|
||||
if (ch_num == DMA_NO_CHANNEL || ch_num & (~DMA_ALL_CHANNELS)) {
|
||||
errorCode = DMA_ECHRNG;
|
||||
} else {
|
||||
if (((uint16_t)dma_ch_en_reg_get( )) & ch_num) {
|
||||
errorCode = DMA_EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_get_channel_index
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_get_channel_index(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t ch_enum = 1;
|
||||
uint8_t ch_index = 0;
|
||||
|
||||
ch_num &= (DMA_ALL_CHANNELS >> 8);
|
||||
while (ch_index < DMA_MAX_CHANNELS) {
|
||||
if (ch_enum == ch_num) {
|
||||
break;
|
||||
}
|
||||
ch_enum *= 2;
|
||||
ch_index++;
|
||||
}
|
||||
|
||||
return ch_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_enable
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE void xc_dma_enable(void) { dma_cfg_reg_set(ENABLE); }
|
||||
|
||||
/**
|
||||
* @brief xc_dma_disable
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_disable(void)
|
||||
{
|
||||
uint8_t errorCode = 0;
|
||||
uint8_t dma_en = dma_cfg_reg__dma_en__getf( );
|
||||
|
||||
if (dma_en != 0) {
|
||||
dma_cfg_reg_set(DISABLE);
|
||||
|
||||
// Ensure that the DMA was disabled
|
||||
// May not disable due to split response on one
|
||||
// of the DMA channels
|
||||
if (dma_cfg_reg_get( )) {
|
||||
errorCode = DMA_EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_is_enable
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
bool xc_dma_is_enable(void)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
ret = (bool)dma_cfg_reg__dma_en__getf( );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_enable_channel
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_enable_channel(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t errorCode = 0;
|
||||
|
||||
// Check for valid channel number and not busy
|
||||
errorCode = xc_dma_check_channel_busy(ch_num);
|
||||
if (errorCode == 0) {
|
||||
// The dw_dmac_channel_number enum is declared such that
|
||||
// the enumerated value maps exactly to the value that
|
||||
// needs to be written into the ChEnReg for enabling.
|
||||
dma_ch_en_reg_set(ch_num);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_disable_channel
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_disable_channel(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t errorCode = 0;
|
||||
uint32_t enabled_ch;
|
||||
|
||||
// Check for valid channel number
|
||||
errorCode = xc_dma_check_channel_range(ch_num);
|
||||
|
||||
if (errorCode == 0) {
|
||||
enabled_ch = (dma_ch_en_reg_get( ) & ch_num);
|
||||
if (enabled_ch != 0) {
|
||||
dma_ch_en_reg_set((ch_num & (DMA_ALL_CHANNELS << 8)));
|
||||
|
||||
// Ensure that the channel(s) was disabled.
|
||||
// Channel may not disable due to a split response.
|
||||
if (dma_ch_en_reg_get( ) & ch_num) {
|
||||
errorCode = DMA_EBUSY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_is_channel_enabled
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
bool xc_dma_is_channel_enabled(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t ch_index;
|
||||
bool ret;
|
||||
|
||||
ch_index = xc_dma_get_channel_index(ch_num);
|
||||
|
||||
// Allow only ONE channel to be specified
|
||||
if (ch_index == DMA_MAX_CHANNELS)
|
||||
return false;
|
||||
|
||||
// Check that the specified channel is in range
|
||||
if (ch_num & (~DMA_ALL_CHANNELS))
|
||||
return false;
|
||||
|
||||
ret = (bool)REG_BIT_VAL_GET(dma_ch_en_reg__ch_en__getf( ), 1 << ch_index, ch_index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_enable_channel_irq
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_enable_channel_irq(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
|
||||
// Check for valid channel number and not busy
|
||||
errorCode = xc_dma_check_channel_busy(ch_num);
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Loop through each channel in turn and disable
|
||||
// the channel Irq for the selected channels.
|
||||
for (uint8_t x = 0; x < DMA_MAX_CHANNELS; x++) {
|
||||
if (ch_num & (1 << x)) {
|
||||
if (dma_ctl_l__int_en__getf(x) != 0x1) {
|
||||
dma_ctl_l__int_en__setf(x, ENABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_disable_channel_irq
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_disable_channel_irq(eDMA_Ch_Num ch_num)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
|
||||
// Check for valid channel number and not busy
|
||||
errorCode = xc_dma_check_channel_busy(ch_num);
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Loop through each channel in turn and disable
|
||||
// the channel Irq for the selected channels.
|
||||
for (uint8_t x = 0; x < DMA_MAX_CHANNELS; x++) {
|
||||
if (ch_num & (1 << x)) {
|
||||
if (dma_ctl_l__int_en__getf(x) != 0x0) {
|
||||
dma_ctl_l__int_en__setf(x, DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_mask_irq
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_mask_irq(eDMA_Ch_Num ch_num, eDMA_Irq ch_irq)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
uint16_t reg;
|
||||
|
||||
// Check for valid channel number
|
||||
errorCode = xc_dma_check_channel_range(ch_num);
|
||||
if (errorCode == 0) {
|
||||
// Loop through and clear the selected channel Irq
|
||||
// for the targeted channels.
|
||||
reg = (ch_num & (DMA_ALL_CHANNELS << 8));
|
||||
for (uint8_t x = 0; x < DMA_MAX_INTERRUPTS; x++) {
|
||||
if (ch_irq & (1 << x)) {
|
||||
if(x == 0){
|
||||
dma_mask_tfr_set(reg);
|
||||
}else if(x == 1){
|
||||
dma_mask_block_set(reg);
|
||||
}else if(x == 2){
|
||||
dma_mask_src_tran_set(reg);
|
||||
}else if(x == 3){
|
||||
dma_mask_dst_tran_set(reg);
|
||||
}else if(x == 4){
|
||||
dma_mask_err_set(reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_unmask_irq
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_unmask_irq(eDMA_Ch_Num ch_num, eDMA_Irq ch_irq)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
uint16_t reg;
|
||||
|
||||
// Check for valid channel number
|
||||
errorCode = xc_dma_check_channel_range(ch_num);
|
||||
if (errorCode == 0) {
|
||||
// Loop through and clear the selected channel Irq
|
||||
// for the targeted channels.
|
||||
reg = ch_num;
|
||||
for (uint8_t x = 0; x < DMA_MAX_INTERRUPTS; x++) {
|
||||
if (ch_irq & (1 << x)) {
|
||||
if(x == 0){
|
||||
dma_mask_tfr_set(reg);
|
||||
}else if(x == 1){
|
||||
dma_mask_block_set(reg);
|
||||
}else if(x == 2){
|
||||
dma_mask_src_tran_set(reg);
|
||||
}else if(x == 3){
|
||||
dma_mask_dst_tran_set(reg);
|
||||
}else if(x == 4){
|
||||
dma_mask_err_set(reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_clear_irq
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_clear_irq(eDMA_Ch_Num ch_num, eDMA_Irq ch_irq)
|
||||
{
|
||||
uint8_t errorCode = DMA_OK;
|
||||
uint16_t reg;
|
||||
|
||||
// Check for valid channel number
|
||||
errorCode = xc_dma_check_channel_range(ch_num);
|
||||
if (errorCode == 0) {
|
||||
// Loop through and clear the selected channel Irq
|
||||
// for the targeted channels.
|
||||
reg = (ch_num & (DMA_ALL_CHANNELS >> 8));
|
||||
for (uint8_t x = 0; x < DMA_MAX_INTERRUPTS; x++) {
|
||||
if (ch_irq & (1 << x)) {
|
||||
if(x == 0){
|
||||
dma_clear_tfr_set(reg);
|
||||
}else if(x == 1){
|
||||
dma_clear_block_set(reg);
|
||||
}else if(x == 2){
|
||||
dma_clear_src_tran_set(reg);
|
||||
}else if(x == 3){
|
||||
dma_clear_dst_tran_set(reg);
|
||||
}else if(x == 4){
|
||||
dma_clear_err_set(reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_init
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_init(void)
|
||||
{
|
||||
// Remove from test mode
|
||||
xc_dma_set_test_mode(DISABLE);
|
||||
// Reset the DMA instance structure
|
||||
xc_dma_reset_instance(&DMA_Instance);
|
||||
// Disable the DMA controller
|
||||
uint8_t errorCode = xc_dma_disable( );
|
||||
if (errorCode == 0) {
|
||||
// Disable all DMA channels
|
||||
errorCode = xc_dma_disable_channel(DMA_ALL_CHANNELS);
|
||||
}
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Disable all channel interrupts
|
||||
errorCode = xc_dma_disable_channel_irq(DMA_ALL_CHANNELS);
|
||||
}
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Mask all channel interrupts
|
||||
errorCode = xc_dma_mask_irq(DMA_ALL_CHANNELS, DMA_IRQ_ALL);
|
||||
}
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Clear any pending interrupts
|
||||
errorCode = xc_dma_clear_irq(DMA_ALL_CHANNELS, DMA_IRQ_ALL);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_set_channel_config
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_set_channel_config(eDMA_Ch_Num ch_num,
|
||||
DMA_Chx_Cfg_t *ch)
|
||||
{
|
||||
uint8_t errorCode;
|
||||
uint8_t ch_index;
|
||||
|
||||
ch_index = xc_dma_get_channel_index(ch_num);
|
||||
|
||||
// Check for valid channel number and not busy
|
||||
errorCode = xc_dma_check_channel_busy(ch_num);
|
||||
if (errorCode == 0) {
|
||||
// Set the control register
|
||||
dma_ctl_l_pack(ch_index, ch->ctl_tt_fc, ch->ctl_src_msize, ch->ctl_dst_msize,
|
||||
ch->ctl_sinc, ch->ctl_dinc, ch->ctl_src_tr_width, ch->ctl_dst_tr_width,
|
||||
0);
|
||||
|
||||
dma_ctl_h__block_ts__setf(ch_index, ch->ctl_block_ts);
|
||||
|
||||
// Set the config register
|
||||
dma_cfg_l__hs_sel_src__setf(ch_index, ch->cfg_hs_sel_src);
|
||||
dma_cfg_l__hs_sel_dst__setf(ch_index, ch->cfg_hs_sel_dst);
|
||||
|
||||
dma_cfg_h_pack(ch_index, (ch->cfg_dst_per & 0xf), (ch->cfg_src_per & 0xf), (ch->cfg_fifo_mode & 0x1));
|
||||
|
||||
// set the SAR/DAR registers
|
||||
dma_sar_set(ch_index, ch->sar);
|
||||
dma_dar_set(ch_index, ch->dar);
|
||||
};
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_set_listener
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE bool xc_dma_set_listener(eDMA_Ch_Num ch_num,
|
||||
DMA_Callback userFunction)
|
||||
{
|
||||
uint8_t ch_index;
|
||||
DMA_Instance_t *inst = &DMA_Instance;
|
||||
|
||||
ch_index = xc_dma_get_channel_index(ch_num);
|
||||
|
||||
// Allow only ONE channel to be specified
|
||||
if (ch_index == DMA_MAX_CHANNELS)
|
||||
return false;
|
||||
|
||||
// Check that the specified channel is in range
|
||||
if (ch_num & (~DMA_ALL_CHANNELS))
|
||||
return false;
|
||||
|
||||
inst->Ch[ch_index].userListener = userFunction;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief xc_dma_start_transfer
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE uint8_t xc_dma_start_transfer(eDMA_Ch_Num ch_num, DMA_Callback cb_func)
|
||||
{
|
||||
uint8_t errorCode;
|
||||
uint8_t ch_index;
|
||||
|
||||
DMA_Instance_t *inst = &DMA_Instance;
|
||||
// Update the channel instance
|
||||
ch_index = xc_dma_get_channel_index(ch_num);
|
||||
|
||||
// Allow only ONE channel to be specified
|
||||
if (ch_index == DMA_MAX_CHANNELS) {
|
||||
errorCode = DMA_ECHRNG;
|
||||
} else {
|
||||
// Check for valid channel number and not busy
|
||||
errorCode = xc_dma_check_channel_busy(ch_num);
|
||||
}
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Disable the channels interrupts
|
||||
errorCode = xc_dma_disable_channel_irq(ch_num);
|
||||
}
|
||||
|
||||
if (errorCode == 0) {
|
||||
// set the call back function, the number of blocks
|
||||
// in the transfer and the source and destination states.
|
||||
inst->Ch[ch_index].userCallback = cb_func;
|
||||
|
||||
// always want to unmask the tfr, block and err interrupts
|
||||
xc_dma_unmask_irq(ch_num, DMA_IRQ_TRF);
|
||||
xc_dma_unmask_irq(ch_num, DMA_IRQ_ERR);
|
||||
|
||||
// Enable the channel interrupts for the type of transfer
|
||||
errorCode = xc_dma_enable_channel_irq(ch_num);
|
||||
|
||||
if (errorCode == 0) {
|
||||
// Enable the DMA channel
|
||||
errorCode = xc_dma_enable_channel(ch_num);
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief dma_irq_handler
|
||||
* @details
|
||||
*
|
||||
* @param
|
||||
* @param
|
||||
* @return void
|
||||
* @retval void
|
||||
* @retval void
|
||||
* @note
|
||||
*/
|
||||
__RAM_CODE bool dma_irq_handler(DMA_Instance_t *inst)
|
||||
{
|
||||
bool retval;
|
||||
uint8_t i, ch_index, callbackArg;
|
||||
uint32_t reg, mask;
|
||||
DMA_Callback userCallback;
|
||||
|
||||
// Assume an interrupt will be processed. The return value will be
|
||||
// set to false if an active interrupt is not found.
|
||||
retval = true;
|
||||
|
||||
// ERR INTERRUPT
|
||||
if (dma_status_int__err__getf( )) {
|
||||
reg = dma_status_err_get( );
|
||||
|
||||
// Loop through the channels until we find
|
||||
// active interrupt. We start at the highest priority
|
||||
// channel and work down to the lowest priority.
|
||||
for (i = 0; i < DMA_MAX_CHANNELS; i++) {
|
||||
mask = 1 << inst->Ch_Order[i];
|
||||
if (reg & mask) {
|
||||
ch_index = inst->Ch_Order[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// run the listener function
|
||||
if (inst->Ch[ch_index].userListener != NULL) {
|
||||
userCallback = inst->Ch[ch_index].userListener;
|
||||
callbackArg = DMA_IRQ_ERR;
|
||||
userCallback(callbackArg);
|
||||
}
|
||||
|
||||
// clear the interrupt
|
||||
dma_clear_err_set(mask);
|
||||
}
|
||||
// TFR INTERRUPT
|
||||
else if (dma_status_int__tfr__getf( )) {
|
||||
reg = dma_status_tfr_get( );
|
||||
|
||||
// Loop through the channels until we find
|
||||
// active interrupt. We start at the highest priority
|
||||
// channel and work down to the lowest priority.
|
||||
for (i = 0; i < DMA_MAX_CHANNELS; i++) {
|
||||
mask = 1 << inst->Ch_Order[i];
|
||||
if (reg & mask) {
|
||||
ch_index = inst->Ch_Order[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable all channel interrupts
|
||||
xc_dma_disable_channel_irq(inst->Ch[ch_index].ch_num);
|
||||
|
||||
// clear any pending block/srcTran/dstTran interrupts
|
||||
dma_clear_block_set(mask);
|
||||
dma_clear_src_tran_set(mask);
|
||||
dma_clear_dst_tran_set(mask);
|
||||
xc_dma_clear_irq(inst->Ch[ch_index].ch_num, DMA_IRQ_TRF);
|
||||
|
||||
// Mask all channel interrupts
|
||||
xc_dma_mask_irq(inst->Ch[ch_index].ch_num, DMA_IRQ_ALL);
|
||||
|
||||
// run the callback function
|
||||
if (inst->Ch[ch_index].userCallback != NULL) {
|
||||
userCallback = inst->Ch[ch_index].userCallback;
|
||||
callbackArg = 0;
|
||||
userCallback(callbackArg);
|
||||
}
|
||||
|
||||
} else {
|
||||
// If we've reached this point, either the enabling and
|
||||
// disabling of DW_ahb_dmac interrupts is not being handled
|
||||
// properly or this function is being called unnecessarily.
|
||||
retval = false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
__RAM_CODE void DMA_Handler(void) { dma_irq_handler(&DMA_Instance); }
|
||||
|
||||
#endif //(DMA_ON)
|
||||
@@ -0,0 +1,286 @@
|
||||
/*!
|
||||
* \file xc_drv_dma.h
|
||||
*
|
||||
* \brief The header of xc_drv_dma.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_DMA_H_
|
||||
#define _XC_DRV_DMA_H_
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
// Macro definitions for DMA operation return code
|
||||
#define DMA_OK 0 // operation normal
|
||||
#define DMA_EPERM 1 // operation not permitted
|
||||
#define DMA_EIO 5 // I/O error
|
||||
#define DMA_ENXIO 6 // no such device or address
|
||||
#define DMA_ENOMEM 12 // out of memory
|
||||
#define DMA_EACCES 13 // permission denied
|
||||
#define DMA_EBUSY 16 // device or resource busy
|
||||
#define DMA_ENODEV 19 // no such device
|
||||
#define DMA_EINVAL 22 // invalid argument
|
||||
#define DMA_ENOSPC 28 // no space left on device
|
||||
#define DMA_ENOSYS 38 // function not implemented/supported
|
||||
#define DMA_ECHRNG 44 // channel number out of range
|
||||
#define DMA_ENODATA 61 // no data available
|
||||
#define DMA_ETIME 62 // timer expired
|
||||
#define DMA_EPROTO 71 // protocol error
|
||||
|
||||
// Macro definitions for DMA controller limits
|
||||
#define DMA_MAX_CHANNELS 4U //5A 2 CH; 5B 4 CH
|
||||
#define DMA_MAX_INTERRUPTS 5U
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef void (*DMA_Callback)(uint8_t eCode);
|
||||
|
||||
typedef enum dmac_channel_number
|
||||
{
|
||||
// 4 channel configuration
|
||||
DMA_NO_CHANNEL = 0x0000,
|
||||
DMA_CHANNEL0 = 0x0101,
|
||||
DMA_CHANNEL1 = 0x0202,
|
||||
DMA_CHANNEL2 = 0x0404,
|
||||
DMA_CHANNEL3 = 0x0808,
|
||||
DMA_ALL_CHANNELS = 0x0f0f
|
||||
} eDMA_Ch_Num;
|
||||
|
||||
typedef enum dmac_src_dst_select
|
||||
{
|
||||
DMA_SRC = 0x1,
|
||||
DMA_DST = 0x2,
|
||||
DMA_SRC_DST = 0x3
|
||||
} eDMA_Src_Dst_Select;
|
||||
|
||||
typedef enum dmac_ch_state
|
||||
{
|
||||
DMA_IDLE = 0x0,
|
||||
DMA_SINGLE_REGION = 0x1,
|
||||
DMA_BURST_REGION = 0x2
|
||||
} eDMA_CH_State;
|
||||
|
||||
typedef enum dmac_transfer_type
|
||||
{
|
||||
DMA_TRANSFER_ROW1 = 0x1, /* single block or last multi-block */
|
||||
/* no write back */
|
||||
DMA_TRANSFER_ROW2 = 0x2, /* multi-block auto-reload DAR */
|
||||
/* contiguous SAR no write back */
|
||||
DMA_TRANSFER_ROW3 = 0x3, /* multi-block auto reload SAR */
|
||||
/* contiguous DAR no write back */
|
||||
DMA_TRANSFER_ROW4 = 0x4, /* multi-block auto-reload SAR DAR */
|
||||
/* no write back */
|
||||
DMA_TRANSFER_ROW5 = 0x5, /* single block or last multi-block */
|
||||
/* with write back */
|
||||
DMA_TRANSFER_ROW6 = 0x6, /* multi-block linked list DAR */
|
||||
/* contiguous SAR with write back */
|
||||
DMA_TRANSFER_ROW7 = 0x7, /* multi-block linked list DAR auto */
|
||||
/* reload SAR with write back */
|
||||
DMA_TRANSFER_ROW8 = 0x8, /* multi-block linked list SAR */
|
||||
/* contiguous DAR with write back */
|
||||
DMA_TRANSFER_ROW9 = 0x9, /* multi-block linked list SAR auto */
|
||||
/* reload DAR with write back */
|
||||
DMA_TRANSFER_ROW10 = 0xa /* multi-block linked list SAR DAR */
|
||||
/* with write back */
|
||||
} eDMA_Trans_Type;
|
||||
|
||||
typedef enum dw_dmac_irq
|
||||
{
|
||||
DMA_IRQ_NONE = 0x00, // no interrupts
|
||||
DMA_IRQ_TRF = 0x01, // transfer complete
|
||||
DMA_IRQ_BLOCK = 0x02, // block transfer complete
|
||||
DMA_IRQ_SRCTRAN = 0x04, // source transaction complete
|
||||
DMA_IRQ_DSTTRAN = 0x08, // destination transaction complete
|
||||
DMA_IRQ_ERR = 0x10, // error
|
||||
DMA_IRQ_ALL = 0x1f // all interrupts
|
||||
} eDMA_Irq;
|
||||
|
||||
typedef enum dmac_burst_trans_length
|
||||
{
|
||||
DMA_MSIZE_1 = 0x0,
|
||||
DMA_MSIZE_4 = 0x1,
|
||||
DMA_MSIZE_8 = 0x2,
|
||||
DMA_MSIZE_16 = 0x3,
|
||||
DMA_MSIZE_32 = 0x4,
|
||||
DMA_MSIZE_64 = 0x5,
|
||||
DMA_MSIZE_128 = 0x6,
|
||||
DMA_MSIZE_256 = 0x7
|
||||
} eDMA_Burst_Trans_Len;
|
||||
|
||||
typedef enum dmac_address_increment
|
||||
{
|
||||
DMA_ADDR_INCREMENT = 0x0,
|
||||
DMA_ADDR_DECREMENT = 0x1,
|
||||
DMA_ADDR_NOCHANGE = 0x2
|
||||
} eDMA_Addr_Increment;
|
||||
|
||||
typedef enum dmac_transfer_width
|
||||
{
|
||||
DMA_TRANS_WIDTH_8 = 0x0,
|
||||
DMA_TRANS_WIDTH_16 = 0x1,
|
||||
DMA_TRANS_WIDTH_32 = 0x2,
|
||||
DMA_TRANS_WIDTH_64 = 0x3,
|
||||
DMA_TRANS_WIDTH_128 = 0x4,
|
||||
DMA_TRANS_WIDTH_256 = 0x5
|
||||
} eDMA_Trans_Width;
|
||||
|
||||
typedef enum dw_dmac_sw_hw_hs_select
|
||||
{
|
||||
DMA_HS_HARDWARE = 0x0,
|
||||
DMA_HS_SOFTWARE = 0x1
|
||||
} eDMA_SW_HW_HS_Select;
|
||||
|
||||
typedef enum dmac_hs_interface
|
||||
{
|
||||
UART0_DMA_TX_HS_IF0 = 0x0,
|
||||
UART1_DMA_TX_HS_IF1 = 0x1,
|
||||
SSI0_DMA_TX_HS_IF2 = 0x2,
|
||||
SSI1_DMA_TX_HS_IF3 = 0x3,
|
||||
SSI2_DMA_TX_HS_IF4 = 0x4,
|
||||
I2S_DMA_TX_HS_IF5 = 0x5,
|
||||
DMA_HS_IF6 = 0x6,
|
||||
DMA_HS_IF7 = 0x7,
|
||||
UART0_DMA_RX_HS_IF8 = 0x8,
|
||||
UART1_DMA_RX_HS_IF9 = 0x9,
|
||||
SSI0_DMA_RX_HS_IF10 = 0xa,
|
||||
SSI1_DMA_RX_HS_IF11 = 0xb,
|
||||
GPADC_DMA_RX_HS_IF12 = 0xc,
|
||||
CDC_DMA_RX_HS_IF13 = 0xd,
|
||||
SSI2_DMA_RX_HS_IF14 = 0xe,
|
||||
I2S_DMA_RX_HS_IF15 = 0xf
|
||||
} eDMA_HS_Interface;
|
||||
|
||||
typedef enum dmac_transfer_flow
|
||||
{
|
||||
DMA_MEM2MEM_DMA = 0x0, /* mem to mem - DMA flow ctlr */
|
||||
DMA_MEM2PRF_DMA = 0x1, /* mem to prf - DMA flow ctlr */
|
||||
DMA_PRF2MEM_DMA = 0x2, /* prf to mem - DMA flow ctlr */
|
||||
DMA_PRF2PRF_DMA = 0x3, /* prf to prf - DMA flow ctlr */
|
||||
DMA_PRF2MEM_PRF = 0x4, /* prf to mem - periph flow ctlr */
|
||||
DMA_PRF2PRF_SRCPRF = 0x5, /* prf to prf - source flow ctlr */
|
||||
DMA_MEM2PRF_PRF = 0x6, /* mem to prf - periph flow ctlr */
|
||||
DMA_PRF2PRF_DSTPRF = 0x7 /* prf to prf - dest flow ctlr */
|
||||
} eDMA_Trans_Flow;
|
||||
|
||||
typedef enum dmac_fifo_mode
|
||||
{
|
||||
DMA_FIFO_MODE_SINGLE = 0x0,
|
||||
DMA_FIFO_MODE_HALF = 0x1
|
||||
} eDMA_Fifo_Mode;
|
||||
|
||||
typedef enum dw_dmac_channel_priority
|
||||
{
|
||||
DMA_PRIORITY_0 = 0x0,
|
||||
DMA_PRIORITY_1 = 0x1,
|
||||
DMA_PRIORITY_2 = 0x2,
|
||||
DMA_PRIORITY_3 = 0x3,
|
||||
DMA_PRIORITY_4 = 0x4,
|
||||
DMA_PRIORITY_5 = 0x5,
|
||||
DMA_PRIORITY_6 = 0x6,
|
||||
DMA_PRIORITY_7 = 0x7
|
||||
} eDMA_CH_Priority;
|
||||
|
||||
typedef struct dmac_channel_config
|
||||
{
|
||||
uint32_t sar;
|
||||
uint32_t dar;
|
||||
eDMA_Burst_Trans_Len ctl_src_msize;
|
||||
eDMA_Burst_Trans_Len ctl_dst_msize;
|
||||
eDMA_Addr_Increment ctl_sinc;
|
||||
eDMA_Addr_Increment ctl_dinc;
|
||||
eDMA_Trans_Width ctl_src_tr_width;
|
||||
eDMA_Trans_Width ctl_dst_tr_width;
|
||||
eDMA_HS_Interface cfg_dst_per;
|
||||
eDMA_HS_Interface cfg_src_per;
|
||||
uint32_t ctl_block_ts;
|
||||
eDMA_Trans_Flow ctl_tt_fc;
|
||||
eDMA_Fifo_Mode cfg_fifo_mode;
|
||||
eDMA_SW_HW_HS_Select cfg_hs_sel_src;
|
||||
eDMA_SW_HW_HS_Select cfg_hs_sel_dst;
|
||||
eDMA_CH_Priority cfg_ch_prior;
|
||||
} DMA_Chx_Cfg_t;
|
||||
|
||||
typedef struct dmac_param_s
|
||||
{
|
||||
bool encoded_params; /* include encoded hardware parameters */
|
||||
uint8_t num_channels; /* number of DMA channels */
|
||||
uint8_t num_hs_int; /* number of handshaking interfaces */
|
||||
uint8_t intr_io; /* individual or combined interrupts */
|
||||
bool big_endian; /* big or little endian 1=big */
|
||||
uint16_t s_hdata_width; /* AHB slave data bus width */
|
||||
|
||||
} DMA_Params_t;
|
||||
|
||||
typedef struct dma_instance_s
|
||||
{
|
||||
struct
|
||||
{
|
||||
eDMA_Ch_Num ch_num; // channel number
|
||||
DMA_Callback userCallback; // callback functon for IRQ handler
|
||||
DMA_Callback userListener; // listener functon for IRQ handler
|
||||
} Ch[DMA_MAX_CHANNELS];
|
||||
uint8_t Ch_Order[DMA_MAX_CHANNELS];
|
||||
} DMA_Instance_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern DMA_Instance_t DMA_Instance;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
uint8_t xc_dma_init(void);
|
||||
void xc_dma_enable(void);
|
||||
uint8_t xc_dma_disable(void);
|
||||
bool xc_dma_is_enable(void);
|
||||
uint8_t xc_dma_enable_channel(eDMA_Ch_Num ch_num);
|
||||
uint8_t xc_dma_disable_channel(eDMA_Ch_Num ch_num);
|
||||
bool xc_dma_is_channel_enabled(eDMA_Ch_Num ch_num);
|
||||
uint8_t xc_dma_enable_channel_irq(eDMA_Ch_Num ch_num);
|
||||
uint8_t xc_dma_set_channel_config(eDMA_Ch_Num ch_num, DMA_Chx_Cfg_t *ch);
|
||||
bool xc_dma_set_listener(eDMA_Ch_Num ch_num, DMA_Callback userFunction);
|
||||
uint8_t xc_dma_start_transfer(eDMA_Ch_Num ch_num, DMA_Callback cb_func);
|
||||
|
||||
void xc_dma_set_test_mode(uint8_t mode);
|
||||
|
||||
void xc_dma_set_channel_priority_order(DMA_Instance_t *inst);
|
||||
void xc_dma_reset_instance(DMA_Instance_t *inst);
|
||||
uint8_t xc_dma_check_channel_range(eDMA_Ch_Num ch_num);
|
||||
uint8_t xc_dma_check_channel_range(eDMA_Ch_Num ch_num);
|
||||
uint8_t xc_dma_get_channel_index(eDMA_Ch_Num ch_num);
|
||||
|
||||
bool dma_irq_handler(DMA_Instance_t *inst);
|
||||
|
||||
|
||||
#endif /* _XC_DRV_DMA_H_ */
|
||||
@@ -0,0 +1,107 @@
|
||||
/*!
|
||||
* \file xc_drv_flash.h
|
||||
*
|
||||
* \brief The header of flash operation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_FLASH_H_
|
||||
#define _XC_DRV_FLASH_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define CMD_READ_DATA (uint8_t)0x03
|
||||
#define CMD_READ_STATUS (uint8_t)0x05
|
||||
#define CMD_CHIP_ERASE (uint8_t)0xc7
|
||||
#define CMD_WRITE_ENABLE (uint8_t)0x06
|
||||
#define CMD_WRITE_DISABLE (uint8_t)0x04
|
||||
#define CMD_PAGE_PROGRAM (uint8_t)0x02
|
||||
#define CMD_BLOCK_ERASE (uint8_t)0xD8
|
||||
#define CMD_SECTOR_ERASE (uint8_t)0x20
|
||||
#define CMD_PAGE_ERASE (uint8_t)0x81
|
||||
#define CMD_RELEASE_PWRDWN (uint8_t)0xAB
|
||||
#define CMD_PWRDWN (uint8_t)0xB9
|
||||
#define CMD_RUID (uint8_t)0x4B
|
||||
#define CMD_RDID (uint8_t)0x9F
|
||||
#define CMD_QREMS (uint8_t)0x94
|
||||
#define CMD_WRITE_STATUS_REG (uint8_t)0x01
|
||||
|
||||
#define FLASH_PAGE_SIZE 256
|
||||
#define FLASH_SECTOR_SIZE 4096
|
||||
|
||||
#define PUYA_FLASH_STATUS_WIP_SET (0x01UL)
|
||||
#define PUYA_FLASH_STATUS_WIP_RESET (0x00UL)
|
||||
|
||||
#define CUR_PAGE_NUM(addr) (addr / FLASH_PAGE_SIZE)
|
||||
#define CUR_START_PSR(addr) (addr % FLASH_PAGE_SIZE)
|
||||
#define CUR_SECTOR_NUM(addr) (addr / FLASH_SECTOR_SIZE)
|
||||
#define CUR_SECTOR_PSR(addr) (addr % FLASH_SECTOR_SIZE)
|
||||
#define CUR_SECTOR_PAGE_ADDR(SECTOR_IDX, PAGE_IDX) (((SECTOR_IDX) << 12) + ((PAGE_IDX) << 8))
|
||||
|
||||
#define CMD_ERASE_SECURITY_REG (uint8_t)0x44
|
||||
#define CMD_READ_SECURITY_REG (uint8_t)0x48
|
||||
#define CMD_PROGRAM_SECURITY_REG (uint8_t)0x42
|
||||
|
||||
#define OTP_PROGRAM_PAGE_0 (uint8_t)0x0
|
||||
#define OTP_PROGRAM_PAGE_1 (uint8_t)0x10
|
||||
#define OTP_PROGRAM_PAGE_2 (uint8_t)0x20
|
||||
#define OTP_PROGRAM_PAGE_3 (uint8_t)0x30
|
||||
|
||||
#define FLASH_2M_FLAG 0x15
|
||||
#define FLASH_1M_FLAG 0x14
|
||||
#define FLASH_512K_FLAG 0x13
|
||||
#define FLASH_256K_FLAG 0x12
|
||||
#define FLASH_128K_FLAG 0x11
|
||||
|
||||
#define FLASH_2M_SIZE 1024 * 2048
|
||||
#define FLASH_1M_SIZE 1024 * 1024
|
||||
#define FLASH_512K_SIZE 1024 * 512
|
||||
#define FLASH_256K_SIZE 1024 * 256
|
||||
#define FLASH_128K_SIZE 1024 * 128
|
||||
|
||||
#define YOUCUN_FLASH 0x60B3
|
||||
#define PURAN_128K_FLASH 0x4485
|
||||
#define GD25WD40_512K_FLASH 0x64C8
|
||||
|
||||
#define FLASH_PAGE_SIZE 256
|
||||
#define FLASH_SECTOR_SIZE 4096
|
||||
|
||||
typedef struct board_c
|
||||
{
|
||||
uint32_t adc2v4_cail;
|
||||
uint32_t adc2v4_reverse_verif;
|
||||
uint32_t flash_id;
|
||||
uint32_t flash_id_reverse_verif;
|
||||
uint32_t ft_rest;
|
||||
uint32_t ft_rest_reverse_verif;
|
||||
uint32_t chip_cnt;
|
||||
uint32_t chip_cnt_reverse_verif;
|
||||
uint32_t rc_cail;
|
||||
uint32_t rc_cail_reverse_verif;
|
||||
} board_card_t;
|
||||
|
||||
#endif /* _XC_DRV_DMA_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
/*!
|
||||
* \file xc_drv_fmc_spi.h
|
||||
*
|
||||
* \brief The header of xc_drv_fmc_spi.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC_DRV_FMC_SPI_H_
|
||||
#define __XC_DRV_FMC_SPI_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "xc6xxx.h"
|
||||
#include "xc_drv_flash.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define __RAM_CODE __attribute__((section("ram_code")))
|
||||
|
||||
#define __WRITE_REG32(REG, VAL) ((*REG) = (VAL))
|
||||
#define __READ_REG32(REG, VAL) ((VAL) = (*REG))
|
||||
#define __SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
#define __CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_4BIT (0x03UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_5BIT (0x04UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_6BIT (0x05UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_7BIT (0x06UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_8BIT (0x07UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_9BIT (0x08UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_10BIT (0x09UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_11BIT (0x0aUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_12BIT (0x0bUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_13BIT (0x0cUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_14BIT (0x0dUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_15BIT (0x0eUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_16BIT (0x0fUL)
|
||||
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_17BIT (0x10UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_18BIT (0x11UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_19BIT (0x12UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_20BIT (0x13UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_21BIT (0x14UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_22BIT (0x15UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_23BIT (0x16UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_24BIT (0x17UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_25BIT (0x18UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_26BIT (0x19UL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_27BIT (0x1AUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_28BIT (0x1BUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_29BIT (0x1CUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_30BIT (0x1DUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_31BIT (0x1EUL)
|
||||
#define FMC_SSI_CTRL0_DFS_LEN_32BIT (0x1FUL)
|
||||
|
||||
#define FMC_SSI_CTRL0_FRF_MOTOROLA (0x0UL)
|
||||
#define FMC_SSI_CTRL0_FRF_TI (0x1UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SCPHA_LEAD (0x0UL)
|
||||
#define FMC_SSI_CTRL0_SCPHA_TRAIL (0x1UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SCPOL_HIGH (0x1UL)
|
||||
#define FMC_SSI_CTRL0_SCPOL_LOW (0x0UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_TMOD_WR (0x0UL)
|
||||
#define FMC_SSI_CTRL0_TMOD_W (0x1UL)
|
||||
#define FMC_SSI_CTRL0_TMOD_R (0x2UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SLV_OE_ENABLE (0x0UL)
|
||||
#define FMC_SSI_CTRL0_SLV_OE_DISABLE (0x1UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SRL_NORMAL (0x0UL)
|
||||
#define FMC_SSI_CTRL0_SRL_LOOKBACK (0x1UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SSTE_ENABLE (0x1UL)
|
||||
#define FMC_SSI_CTRL0_SSTE_DISABLE (0x0UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_01 (0x0UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_02 (0x1UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_03 (0x2UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_04 (0x3UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_05 (0x4UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_06 (0x5UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_07 (0x6UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_08 (0x7UL)
|
||||
#define FMC_SSI_CTRL0_CFS_SIZE_Bit_09 (0x8UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SPI_FRF_STANDARD (0x0UL)
|
||||
|
||||
#define FMC_SSI_CTRL0_SPI_FRF_DUAL (0x1UL)
|
||||
#define FMC_SSI_CTRL0_SPI_FRF_QUAD (0x2UL)
|
||||
#define FMC_SSI_CTRL0_SPI_FRF_OCTAL (0x3UL)
|
||||
|
||||
#define FMC_SSI_EN_SEN_ENABLE (0x1UL)
|
||||
#define FMC_SSI_EN_SEN_DISABLE (0x0UL)
|
||||
|
||||
#define FMC_SSI_SE_SS0_SELECT_YES (0x1UL)
|
||||
#define FMC_SSI_SE_SS0_SELECT_NO (0x0UL)
|
||||
|
||||
#define FMC_SSI_BAUD_DIV_2 (0x02UL)
|
||||
#define FMC_SSI_BAUD_DIV_4 (0x04UL)
|
||||
#define FMC_SSI_BAUD_DIV_6 (0x06UL)
|
||||
#define FMC_SSI_BAUD_DIV_8 (0x08UL)
|
||||
#define FMC_SSI_BAUD_DIV_10 (0x10UL)
|
||||
#define FMC_SSI_BAUD_DIV_12 (0x12UL)
|
||||
|
||||
#define FMC_SSI_TXFTL_FIFO_0 (0x00UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_1 (0x01UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_2 (0x02UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_3 (0x03UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_4 (0x04UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_5 (0x05UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_6 (0x06UL)
|
||||
#define FMC_SSI_TXFTL_FIFO_7 (0x07UL)
|
||||
|
||||
#define FMC_SSI_RXFTL_FIFO_0 (0x00UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_1 (0x01UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_2 (0x02UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_3 (0x03UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_4 (0x04UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_5 (0x05UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_6 (0x06UL)
|
||||
#define FMC_SSI_RXFTL_FIFO_7 (0x07UL)
|
||||
|
||||
#define FMC_SSI_STS_BUSY_SET (0x1UL << BUSY_POS)
|
||||
#define FMC_SSI_STS_BUSY_RESET (0x0UL << BUSY_POS)
|
||||
|
||||
#define FMC_SSI_STS_TFNF_SET (0x1UL << TFNF_POS)
|
||||
#define FMC_SSI_STS_TFNF_RESET (0x0UL << TFNF_POS)
|
||||
|
||||
#define FMC_SSI_STS_TFE_SET (0x1UL << TFE_POS)
|
||||
#define FMC_SSI_STS_TFE_RESET (0x0UL << TFE_POS)
|
||||
|
||||
#define FMC_SSI_STS_RFNE_SET (0x1UL << RFNE_POS)
|
||||
#define FMC_SSI_STS_RFNE_RESET (0x0UL << RFNE_POS)
|
||||
|
||||
#define FMC_SSI_STS_RFF_SET (0x1UL << RFF_POS)
|
||||
#define FMC_SSI_STS_RFF_RESET (0x0UL << RFF_POS)
|
||||
|
||||
#define FMC_SSI_STS_TXE_SET (0x1UL << TXE_POS)
|
||||
#define FMC_SSI_STS_TXE_RESET (0x0UL << TXE_POS)
|
||||
|
||||
#define FMC_SSI_IE_TXEIE_ENABLE (0x1UL << TXEIE_POS)
|
||||
#define FMC_SSI_IE_TXEIE_DISABLE (0x0UL << TXEIE_POS)
|
||||
|
||||
#define FMC_SSI_IE_TXOIE_ENABLE (0x1UL << TXOIE_POS)
|
||||
#define FMC_SSI_IE_TXOIE_DISABLE (0x0UL << TXOIE_POS)
|
||||
|
||||
#define FMC_SSI_IE_RXUIE_ENABLE (0x1UL << RXUIE_POS)
|
||||
#define FMC_SSI_IE_RXUIE_DISABLE (0x0UL << RXUIE_POS)
|
||||
|
||||
#define FMC_SSI_IE_RXOIE_ENABLE (0x1UL << RXOIE_POS)
|
||||
#define FMC_SSI_IE_RXOIE_DISABLE (0x0UL << RXOIE_POS)
|
||||
|
||||
#define FMC_SSI_IE_RXFIE_ENABLE (0x1UL << RXFIE_POS)
|
||||
#define FMC_SSI_IE_RXFIE_DISABLE (0x0UL << RXFIE_POS)
|
||||
|
||||
#define FMC_SSI_IS_TXEIS_SET (0x1UL << TXEIS_POS)
|
||||
#define FMC_SSI_IS_TXEIS_RESET (0x0UL << TXEIS_POS)
|
||||
|
||||
#define FMC_SSI_IS_TXOIS_SET (0x1UL << TXOIS_POS)
|
||||
#define FMC_SSI_IS_TXOIS_RESET (0x0UL << TXOIS_POS)
|
||||
|
||||
#define FMC_SSI_IS_RXUIS_SET (0x1UL << RXUIS_POS)
|
||||
#define FMC_SSI_IS_RXUIS_RESET (0x0UL << RXUIS_POS)
|
||||
|
||||
#define FMC_SSI_IS_RXOIS_SET (0x1UL << RXOIS_POS)
|
||||
#define FMC_SSI_IS_RXOIS_RESET (0x0UL << RXOIS_POS)
|
||||
|
||||
#define FMC_SSI_SSI_IS_RXFIS_SET (0x1UL << RXFIS_POS)
|
||||
#define FMC_SSI_SSI_IS_RXFIS_RESET (0x0UL << RXFIS_POS)
|
||||
|
||||
#define FMC_SSI_RIS_TXEIR_SET (0x1UL << TXEIR_POS)
|
||||
#define FMC_SSI_RIS_TXEIR_RESET (0x0UL << TXEIR_POS)
|
||||
|
||||
#define FMC_SSI_RIS_TXOIR_SET (0x1UL << TXOIR_POS)
|
||||
#define FMC_SSI_RIS_TXOIR_RESET (0x0UL << TXOIR_POS)
|
||||
|
||||
#define FMC_SSI_RIS_RXUIR_SET (0x1UL << RXUIR_POS)
|
||||
#define FMC_SSI_RIS_RXUIR_RESET (0x0UL << RXUIR_POS)
|
||||
|
||||
#define FMC_SSI_RIS_RXOIR_SET (0x1UL << RXOIR_POS)
|
||||
#define FMC_SSI_RIS_RXOIR_RESET (0x0UL << RXOIR_POS)
|
||||
|
||||
#define FMC_SSI_RIS_RXFIR_SET (0x1UL << RXFIR_POS)
|
||||
#define FMC_SSI_RIS_RXFIR_RESET (0x0UL << RXFIR_POS)
|
||||
|
||||
|
||||
#define BLE_COMMON_BASE 0x53022000UL
|
||||
#define BLE_COMN_AGC_REG_OUT0 ((volatile uint32_t *)(BLE_COMMON_BASE + 0x28))
|
||||
#define FMC_IDLE_STATUS ((uint32_t)0x01 << 31)
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_fmc_spi_init_oprt(void);
|
||||
void xc_fmc_spi_flash_power_down(void);
|
||||
void xc_fmc_spi_flash_wake_up(void);
|
||||
void xc_fmc_spi_flash_wait_busy(void);
|
||||
void xc_fmc_spi_flash_write_enable(void);
|
||||
void xc_fmc_spi_flash_erase_sector(uint32_t addr);
|
||||
void xc_fmc_spi_flash_erase_page(uint32_t addr);
|
||||
void xc_fmc_spi_flash_write_page(uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
void xc_fmc_spi_flash_read_page(uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
void xc_fmc_spi_otp_read_page(uint32_t addr, uint8_t *data,
|
||||
uint16_t size);
|
||||
uint8_t xc_fmc_spi_flash_write(uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
uint8_t xc_fmc_spi_flash_read(uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
void xc_fmc_spi_flash_ruid(uint8_t *ruid);
|
||||
void xc_fmc_spi_flash_rdid(uint8_t *rdid);
|
||||
bool flash_size_and_type_get(uint32_t *flash_size, uint16_t *flash_type);
|
||||
bool xc_adc_2v4_calibrate_read(uint16_t * adc_calibrate);
|
||||
bool xc_unique_identification_read(uint8_t *unique_id);
|
||||
|
||||
#endif /* __XC6xxx_FMC_SPI_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
||||
/*!
|
||||
* \file xc_drv_fmc_spi_dma.h
|
||||
*
|
||||
* \brief The header of xc_drv_fmc_spi_dma.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC_DRV_FMC_SPI_DMA_H_
|
||||
#define __XC_DRV_FMC_SPI_DMA_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
#include "xc_drv_flash.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define FMC_SSI_DMAC_RDMAE_DISABLE DISABLE
|
||||
#define FMC_SSI_DMAC_RDMAE_ENABLE ENABLE
|
||||
|
||||
#define FMC_SSI_DMAC_TDMAE_DISABLE DISABLE
|
||||
#define FMC_SSI_DMAC_TDMAE_ENABLE ENABLE
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
__RAM_CODE void xc_fmc_spi_init(void);
|
||||
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_power_down(void);
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_wake_up(void);
|
||||
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_erase_sector(uint32_t Dst_Addr);
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_erase_page(uint32_t Dst_Addr);
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_read_page(uint32_t ReadAddr, uint8_t *data,
|
||||
uint16_t size);
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_write_page(uint32_t WriteAddr, uint8_t *data,
|
||||
uint16_t size);
|
||||
__RAM_CODE eXC_RESULT xc_fmc_spi_dma_flash_read(uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
__RAM_CODE eXC_RESULT xc_fmc_spi_dma_flash_write(uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
__RAM_CODE void xc_fmc_spi_dma_write_and_read_data(
|
||||
uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size);
|
||||
__RAM_CODE void xc_fmc_spi_dma_read_and_write_data(
|
||||
uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size);
|
||||
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_rdid(uint8_t *rdid);
|
||||
__RAM_CODE void xc_fmc_spi_dma_flash_ruid(uint8_t *ruid);
|
||||
|
||||
|
||||
#endif /* __XC_DRV_FMC_SPI_DMA_H_ */
|
||||
@@ -0,0 +1,312 @@
|
||||
/*!
|
||||
* \file xc_drv_aotimer.c
|
||||
*
|
||||
* \brief Target xc aotimer driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_gpio.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_gpio_init
|
||||
* @details Initializes the GPIO port based on structure parameters
|
||||
* @param[in] init_cfg :This is the structure parameter that the GPIO initializes
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
* @other
|
||||
GPIO_InitCfg.Mux = GPIO_Mux0;
|
||||
GPIO_InitCfg.FunSel = GPIO_Dx;
|
||||
GPIO_InitCfg.Pull = GPIO_NOPULL;
|
||||
// Board Led1 Initialization
|
||||
GPIO_InitCfg.Dir = GPIO_DIR_OUTPUT;
|
||||
GPIO_InitCfg.Int = NOT_INT;
|
||||
GPIO_InitCfg.Pin = GPIO_0;
|
||||
xc_gpio_init(&GPIO_InitCfg);
|
||||
// Gpio NVIC Enable
|
||||
//NVIC_EnableIRQ(GPIO_IRQn);
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_gpio_init(GPIO_InitCfg_t *init_cfg)
|
||||
{
|
||||
xc_gpio_mux_ctl(init_cfg->Pin, init_cfg->Mux);
|
||||
xc_gpio_fun_sel(init_cfg->Pin, init_cfg->FunSel);
|
||||
|
||||
xc_gpio_direction_config(init_cfg->Pin, init_cfg->Dir);
|
||||
xc_gpio_it_config(init_cfg->Pin, init_cfg->Int);
|
||||
|
||||
xc_gpio_pull_config(init_cfg->Pin, init_cfg->Pull);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_gpio_init
|
||||
* @details GPIO Function Selection
|
||||
|
||||
* @param[in] num : GPIO number (GPIO_0 -> GPIO_35)
|
||||
* @param[in] mux : Function Selection
|
||||
* @param[out] void
|
||||
* @retval void
|
||||
* @other
|
||||
- GPIO0 : < mux=0 gpio_d[0] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO1 : < mux=0 gpio_d[1] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO2 : < mux=0 gpio_d[2] > < mux=1 test_pin[2] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO3 : < mux=0 gpio_d[3] > < mux=1 pwm_capture[0] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO4 : < mux=0 gpio_d[4] > < mux=1 pwm_brk[0] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO5 : < mux=0 gpio_d[5] > < mux=1 pwm_brk[1] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO6 : < mux=0 gpio_d[6] > < mux=1 pwm_brk[2] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO7 : < mux=0 gpio_d[7] > < mux=1 fmc_d[2] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO8 : < mux=0 gpio_d[8] > < mux=1 pwm_capture[1] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO9 : < mux=0 gpio_d[9] > < mux=1 pwm_capture[2] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO10: < mux=0 gpio_d[10] > < mux=1 fmc_d[3] > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO11: < mux=0 BOOT_CTL > < mux=1 NA > < mux=2 txen > < mux=3 NA >
|
||||
- GPIO12: < mux=0 SWI的 SWCK > < mux=1 NA > < mux=2 rxen > < mux=3 NA >
|
||||
- GPIO13: < mux=0 SWI的 SWD > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO14: < mux=0 gpio_d[14] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO15: < mux=0 gpio_d[15] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO16: < mux=0 gpio_d[16] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO17: < mux=0 gpio_d[17] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO18: < mux=0 gpio_d[18] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO19: < mux=0 gpio_d[19] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO20: < mux=0 gpio_d[20] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO21: < mux=0 gpio_d[21] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO22: < mux=0 gpio_d[22] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO23: < mux=0 gpio_d[23] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO24: < mux=0 gpio_d[24] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO25: < mux=0 gpio_d[25] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO27: < mux=0 gpio_d[27] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO28: < mux=0 gpio_d[28] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO29: < mux=0 gpio_d[29] > < mux=1 gpio_d[29] > < mux=1 NA > < mux=2 NA >
|
||||
- GPIO30: < mux=0 gpio_d[30] > < mux=1 gpio_d[30] > < mux=1 NA > < mux=2 NA >
|
||||
- GPIO31: < mux=0 gpio_d[31] > < mux=1 gpio_d[31] > < mux=1 NA > < mux=2 NA >
|
||||
- GPIO32: < mux=0 gpio_d[32] > < mux=1 NA > < mux=2 NA > < mux=3 NA >
|
||||
- GPIO33: < mux=0 gpio_d[33] > < mux=1 gpio_d[29] > < mux=1 NA > < mux=2 NA >
|
||||
- GPIO34: < mux=0 gpio_d[34] > < mux=1 gpio_d[30] > < mux=1 NA > < mux=2 NA >
|
||||
- GPIO35: < mux=0 gpio_d[35] > < mux=1 gpio_d[31] > < mux=1 NA > < mux=2 NA >
|
||||
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_gpio_mux_ctl(uint8_t num, GPIO_MUX_TypeDef mux)
|
||||
{
|
||||
uint8_t reg_idx = num >> 4UL;
|
||||
uint8_t pin_idx = num & 0xFUL;
|
||||
|
||||
uint32_t val;
|
||||
|
||||
if (mux > 3)
|
||||
return;
|
||||
if (num >= 35)
|
||||
return;
|
||||
|
||||
if (reg_idx == 0) {
|
||||
val = cpr_ctl_muxctl1_get();
|
||||
val = (val & (~(0x3 << (pin_idx << 1)))) | (mux << (pin_idx << 1));
|
||||
cpr_ctl_muxctl1_set(val);
|
||||
} else if (reg_idx == 1) {
|
||||
val = cpr_ctl_muxctl2_get();
|
||||
val = (val & (~(0x3 << (pin_idx << 1)))) | (mux << (pin_idx << 1));
|
||||
cpr_ctl_muxctl2_set(val);
|
||||
} else if (reg_idx == 2) {
|
||||
val = cpr_ctl_muxctl3_get();
|
||||
val = (val & (~(0x3 << (pin_idx << 1)))) | (mux << (pin_idx << 1));
|
||||
cpr_ctl_muxctl3_set(val);
|
||||
}
|
||||
}
|
||||
|
||||
void xc_gpio_fun_sel(uint8_t num, GPIO_FUN_SEL_TypeDef sel)
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t reg_idx = num >> 2UL;
|
||||
uint8_t pin_idx = num & 0x3UL;
|
||||
|
||||
if (num > 28)
|
||||
return;
|
||||
|
||||
val = cpr_gpio_fun_sel_get(reg_idx);
|
||||
|
||||
val = (val & ~(0x1FUL << (pin_idx << 3UL))) | (sel << (pin_idx << 3UL));
|
||||
|
||||
cpr_gpio_fun_sel_set(reg_idx, val);
|
||||
}
|
||||
|
||||
void xc_gpio_pull_config(uint8_t num, GPIO_PULL_TypeDef pull)
|
||||
{
|
||||
uint8_t reg_idx;
|
||||
uint8_t pin_idx;
|
||||
uint32_t val;
|
||||
|
||||
reg_idx = num >> 4UL;
|
||||
pin_idx = num & 0xFUL;
|
||||
|
||||
if (num >= 32) {
|
||||
pin_idx += 2;
|
||||
}
|
||||
|
||||
if (GPIO_PULLUP == pull) {
|
||||
if (reg_idx == 0) {
|
||||
val = cprao_aon_pectrl1_get();
|
||||
SET_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
CLEAR_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_pectrl1_set(val);
|
||||
} else if (reg_idx == 1) {
|
||||
|
||||
val = cprao_aon_pectrl2_get();
|
||||
SET_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
CLEAR_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_pectrl2_set(val);
|
||||
} else if (reg_idx == 2) {
|
||||
|
||||
val = cprao_aon_puctrl1_get();
|
||||
SET_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
CLEAR_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_puctrl1_set(val);
|
||||
}
|
||||
} else if (GPIO_PULLDOWN == pull) {
|
||||
if (reg_idx == 0) {
|
||||
val = cprao_aon_pectrl1_get();
|
||||
CLEAR_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
SET_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_pectrl1_set(val);
|
||||
} else if (reg_idx == 1) {
|
||||
|
||||
val = cprao_aon_pectrl2_get();
|
||||
CLEAR_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
SET_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_pectrl2_set(val);
|
||||
} else if (reg_idx == 2) {
|
||||
|
||||
val = cprao_aon_puctrl1_get();
|
||||
CLEAR_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
SET_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_puctrl1_set(val);
|
||||
}
|
||||
} else if (GPIO_NOPULL == pull) {
|
||||
if (reg_idx == 0) {
|
||||
val = cprao_aon_pectrl1_get();
|
||||
CLEAR_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
CLEAR_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_pectrl1_set(val);
|
||||
} else if (reg_idx == 1) {
|
||||
|
||||
val = cprao_aon_pectrl2_get();
|
||||
CLEAR_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
CLEAR_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_pectrl2_set(val);
|
||||
} else if (reg_idx == 2) {
|
||||
|
||||
val = cprao_aon_puctrl1_get();
|
||||
CLEAR_BIT(val, 1 << ((pin_idx << 1) + 1));
|
||||
CLEAR_BIT(val, 1 << (pin_idx << 1));
|
||||
cprao_aon_puctrl1_set(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xc_gpio_it_config(uint8_t num, GPIO_INT_TypeDef inter)
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t reg_idx = num >> 2UL;
|
||||
uint8_t pin_idx = num & 0x3UL;
|
||||
|
||||
val = gpio_intr_ctrl_get(reg_idx);
|
||||
val = (val & ~(0xF0000UL) & ~(0xFUL << (pin_idx << 2UL))) |
|
||||
(inter << (pin_idx << 2UL)) | ((0x01UL << pin_idx) << 16UL);
|
||||
gpio_intr_ctrl_set(reg_idx, val);
|
||||
}
|
||||
|
||||
void xc_gpio_direction_config(uint8_t num, GPIO_DIR_TypeDef direction)
|
||||
{
|
||||
uint8_t reg_idx = num >> 4UL;
|
||||
uint8_t pin_idx = num & 0xFUL;
|
||||
uint32_t val;
|
||||
|
||||
val = (direction << pin_idx) | (1 << 16 << pin_idx);
|
||||
|
||||
gpio_port_ddr_set(reg_idx, val);
|
||||
}
|
||||
|
||||
uint32_t xc_gpio_read_pin(uint8_t num)
|
||||
{
|
||||
uint8_t reg_idx = num >> 5UL;
|
||||
uint8_t pin_idx = num & 0x1FUL;
|
||||
|
||||
uint32_t value = gpio_ext_port_get(reg_idx);
|
||||
|
||||
return (value & (0x01UL << pin_idx)) ? (1) : (0);
|
||||
}
|
||||
|
||||
void xc_gpio_write_pin(uint8_t num, GPIO_PinState pin_state)
|
||||
{
|
||||
uint8_t reg_idx = num >> 4UL;
|
||||
uint8_t pin_idx = num & 0xFUL;
|
||||
|
||||
gpio_port_dr_set(reg_idx, (1 << DR_WE_LSB | pin_state) << pin_idx);
|
||||
}
|
||||
|
||||
void xc_gpio_toggle_pin(uint8_t num)
|
||||
{
|
||||
uint8_t reg_idx = num >> 4UL;
|
||||
uint8_t pin_idx = num & 0xFUL;
|
||||
|
||||
if ((gpio_port_dr_get(reg_idx) & (1 << pin_idx)) != GPIO_PIN_RESET) {
|
||||
gpio_port_dr_set(reg_idx, (1 << DR_WE_LSB | GPIO_PIN_RESET) << pin_idx);
|
||||
} else {
|
||||
gpio_port_dr_set(reg_idx, (1 << DR_WE_LSB | GPIO_PIN_SET) << pin_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void GPIO_Handler(void)
|
||||
{
|
||||
uint64_t intr_sta;
|
||||
uint64_t val;
|
||||
|
||||
intr_sta = gpio_intr_status_c_get(0);
|
||||
val = intr_sta;
|
||||
gpio_intr_clr_set(0, (uint32_t)intr_sta);
|
||||
|
||||
intr_sta = gpio_intr_status_c_get(1);
|
||||
val |= intr_sta << 32;
|
||||
gpio_intr_clr_set(1, (uint32_t)intr_sta);
|
||||
|
||||
gpio_intr_callback(val);
|
||||
}
|
||||
|
||||
__WEAK void gpio_intr_callback(uint64_t intr_sta)
|
||||
{
|
||||
/* Gpio 中断回调处理函数 */
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*!
|
||||
* \file xc_drv_aotimer.h
|
||||
*
|
||||
* \brief The header of xc_drv_aotimer.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_GPIO_H_
|
||||
#define _XC_DRV_GPIO_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
GPIO_PIN_RESET = 0u,
|
||||
GPIO_PIN_SET
|
||||
} GPIO_PinState;
|
||||
|
||||
enum
|
||||
{
|
||||
GPIO_0,
|
||||
GPIO_1,
|
||||
GPIO_2,
|
||||
GPIO_3,
|
||||
GPIO_4,
|
||||
GPIO_5,
|
||||
GPIO_6,
|
||||
GPIO_7,
|
||||
GPIO_8,
|
||||
GPIO_9,
|
||||
GPIO_10,
|
||||
GPIO_11,
|
||||
GPIO_12,
|
||||
GPIO_13,
|
||||
GPIO_14,
|
||||
GPIO_15,
|
||||
GPIO_16,
|
||||
GPIO_17,
|
||||
GPIO_18,
|
||||
GPIO_19,
|
||||
GPIO_20,
|
||||
GPIO_21,
|
||||
GPIO_22,
|
||||
GPIO_23,
|
||||
GPIO_24,
|
||||
GPIO_25,
|
||||
GPIO_26,
|
||||
GPIO_27,
|
||||
GPIO_28,
|
||||
GPIO_29,
|
||||
GPIO_30,
|
||||
GPIO_31,
|
||||
GPIO_32,
|
||||
GPIO_33,
|
||||
GPIO_34,
|
||||
GPIO_35,
|
||||
GPIO_36,
|
||||
GPIO_37,
|
||||
GPIO_38,
|
||||
GPIO_39,
|
||||
GPIO_MAX,
|
||||
GPIO_NONE
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPIO_Mux0 = 0,
|
||||
GPIO_Mux1,
|
||||
GPIO_Mux2,
|
||||
GPIO_Mux3
|
||||
} GPIO_MUX_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPIO_Dx = 0,
|
||||
UART0_TX,
|
||||
UART0_RX,
|
||||
UART0_CTS,
|
||||
UART0_RTS,
|
||||
I2C_SCL,
|
||||
I2C_SDA,
|
||||
UART1_RX,
|
||||
UART1_TX,
|
||||
SIM_IO,
|
||||
SIM_RST,
|
||||
SIM_CLK_OUT,
|
||||
PWM0,
|
||||
PWM1,
|
||||
SSI1_CLK,
|
||||
SSI1_SSN,
|
||||
SSI1_RX,
|
||||
SSI1_TX,
|
||||
PWM0_INV,
|
||||
PWM1_INV,
|
||||
PWM2_INV,
|
||||
PWM3_INV,
|
||||
} GPIO_FUN_SEL_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPIO_PULLUP = 0,
|
||||
GPIO_PULLDOWN = 1,
|
||||
GPIO_NOPULL = 2,
|
||||
} GPIO_PULL_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GPIO_DIR_INPUT = 0,
|
||||
GPIO_DIR_OUTPUT
|
||||
} GPIO_DIR_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NOT_INT = 0,
|
||||
NA1_INT,
|
||||
NA2_INT,
|
||||
NA3_INT,
|
||||
NA4_INT,
|
||||
RIS_EDGE_INT,
|
||||
NA6_INT,
|
||||
FAIL_EDGE_INT,
|
||||
NA8_INT,
|
||||
RIS_FAIL_EDGE_INT,
|
||||
} GPIO_INT_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Pin;
|
||||
GPIO_MUX_TypeDef Mux;
|
||||
GPIO_FUN_SEL_TypeDef FunSel;
|
||||
GPIO_DIR_TypeDef Dir;
|
||||
GPIO_PULL_TypeDef Pull;
|
||||
GPIO_INT_TypeDef Int;
|
||||
} GPIO_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_gpio_init(GPIO_InitCfg_t *init_cfg);
|
||||
void xc_gpio_mux_ctl(uint8_t num, GPIO_MUX_TypeDef mux);
|
||||
void xc_gpio_fun_sel(uint8_t num, GPIO_FUN_SEL_TypeDef sel);
|
||||
void xc_gpio_pull_config(uint8_t num, GPIO_PULL_TypeDef pull);
|
||||
void xc_gpio_it_config(uint8_t num, GPIO_INT_TypeDef inter);
|
||||
void xc_gpio_direction_config(uint8_t num, GPIO_DIR_TypeDef direction);
|
||||
uint32_t xc_gpio_read_pin(uint8_t num);
|
||||
void xc_gpio_write_pin(uint8_t num, GPIO_PinState pin_state);
|
||||
void xc_gpio_toggle_pin(uint8_t num);
|
||||
|
||||
void gpio_intr_callback(uint64_t intr_sta);
|
||||
#endif // _XC_DRV_AOTIMER_H_
|
||||
@@ -0,0 +1,274 @@
|
||||
/*!
|
||||
* \file xc_drv_i2c.c
|
||||
*
|
||||
* \brief Target xc i2c driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
/*------------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_i2c.h"
|
||||
#if (I2C_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
I2C_Block_t i2c_ctl_block;
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_i2c_ctl_block_reset(void);
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_i2c_init(I2C_InitCfg_t *init_cfg)
|
||||
{
|
||||
cpr_ctlapbclken_grctl__i2c_pclk_en__setf(ENABLE);
|
||||
|
||||
cpr_rstctl_subrst_sw__i2c_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__i2c_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_i2c_clk_ctl__i2c_clk_en__setf(ENABLE);
|
||||
cpr_i2c_clk_ctl__i2c_clk_div__setf(init_cfg->DivClk);
|
||||
|
||||
i2c_flag_status_get(I2C_STATUS_ACTIVITY_SET);
|
||||
|
||||
i2c_enable__enable__setf(I2C_ENABLE_EN_DISABLE);
|
||||
|
||||
i2c_rx_tl__rx_tl__setf(I2C_RX_TL_FIFO_1);
|
||||
i2c_tx_tl__tx_tl__setf(I2C_TX_TL_FIFO_0);
|
||||
|
||||
i2c_intr_en_set(I2C_INTR_EN_RX_UNDER_DISABLE | I2C_INTR_EN_RX_OVER_DISABLE | I2C_INTR_EN_RX_FULL_DISABLE |
|
||||
I2C_INTR_EN_TX_OVER_DISABLE | I2C_INTR_EN_TX_EMPTY_DISABLE | I2C_INTR_EN_RD_REQ_DISABLE |
|
||||
I2C_INTR_EN_TX_ABRT_DISABLE | I2C_INTR_EN_RX_DONE_DISABLE | I2C_INTR_EN_ACTIVITY_DISABLE |
|
||||
I2C_INTR_EN_STOP_DET_DISABLE | I2C_INTR_EN_START_DET_DISABLE | I2C_INTR_EN_GEN_CALL_DISABLE);
|
||||
|
||||
i2c_tar__i2c_10bitaddr_master__setf(I2C_TAR_I2C_7BITADDR_MODE);
|
||||
|
||||
if (init_cfg->I2C_Mode == I2C_MODE_MASTER) {
|
||||
|
||||
i2c_tar__i2c_tar__setf(init_cfg->I2C_SlaveAddr);
|
||||
i2c_con__master_mode__setf(I2C_CON_MASTER_MODE_ENABLE);
|
||||
i2c_con__slave_disable__setf(I2C_CON_SLAVE_DISABLE_DISABLE);
|
||||
|
||||
} else if (init_cfg->I2C_Mode == I2C_MODE_SLAVE) {
|
||||
i2c_sar__setf(init_cfg->I2C_SlaveAddr);
|
||||
i2c_con__master_mode__setf(I2C_CON_MASTER_MODE_DISABLE);
|
||||
i2c_con__slave_disable__setf(I2C_CON_SLAVE_DISABLE_ENABLE);
|
||||
|
||||
i2c_con__addr_10bit_slave__setf(I2C_CON_7BITADDR_SLAVE_MODE);
|
||||
|
||||
i2c_con__restart_en__setf(I2C_CON_RESTART_EN_DISABLE);
|
||||
}
|
||||
|
||||
xc_i2c_ctl_block_reset();
|
||||
|
||||
if (init_cfg->I2C_ClockSpeed == I2C_FREQUENCY_100K) {
|
||||
i2c_con__speed__setf(I2C_CON_SPEED_STANDARD_MODE);
|
||||
|
||||
if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) {
|
||||
i2c_ss_scl_hcnt__ss_scl_hcnt__setf(I2C_MLCK32M_FREQUENCY_HCNT_100K);
|
||||
i2c_ss_scl_lcnt__ss_scl_lcnt__setf(I2C_MLCK32M_FREQUENCY_LCNT_100K);
|
||||
} else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) {
|
||||
i2c_ss_scl_hcnt__ss_scl_hcnt__setf(I2C_MLCK48M_FREQUENCY_HCNT_100K);
|
||||
i2c_ss_scl_lcnt__ss_scl_lcnt__setf(I2C_MLCK48M_FREQUENCY_LCNT_100K);
|
||||
} else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M) {
|
||||
i2c_ss_scl_hcnt__ss_scl_hcnt__setf(I2C_MLCK64M_FREQUENCY_HCNT_100K);
|
||||
i2c_ss_scl_lcnt__ss_scl_lcnt__setf(I2C_MLCK64M_FREQUENCY_LCNT_100K);
|
||||
}
|
||||
} else if (init_cfg->I2C_ClockSpeed == I2C_FREQUENCY_400K) {
|
||||
i2c_con__speed__setf(I2C_CON_SPEED_FAST_MODE);
|
||||
|
||||
if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) {
|
||||
i2c_fs_scl_hcnt__fs_scl_hcnt__setf(I2C_MLCK32M_FREQUENCY_HCNT_400K);
|
||||
i2c_fs_scl_lcnt__fs_scl_lcnt__setf(I2C_MLCK32M_FREQUENCY_LCNT_400K);
|
||||
} else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) {
|
||||
i2c_fs_scl_hcnt__fs_scl_hcnt__setf(I2C_MLCK48M_FREQUENCY_HCNT_400K);
|
||||
i2c_fs_scl_lcnt__fs_scl_lcnt__setf(I2C_MLCK48M_FREQUENCY_LCNT_400K);
|
||||
|
||||
} else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M) {
|
||||
i2c_fs_scl_hcnt__fs_scl_hcnt__setf(I2C_MLCK64M_FREQUENCY_HCNT_400K);
|
||||
i2c_fs_scl_lcnt__fs_scl_lcnt__setf(I2C_MLCK64M_FREQUENCY_LCNT_400K);
|
||||
}
|
||||
} else {
|
||||
i2c_con__speed__setf(I2C_CON_SPEED_FAST_MODE);
|
||||
|
||||
if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M) {
|
||||
i2c_fs_scl_hcnt__fs_scl_hcnt__setf(I2C_MLCK32M_FREQUENCY_HCNT_1M);
|
||||
i2c_fs_scl_lcnt__fs_scl_lcnt__setf(I2C_MCLK32M_FREQUENCY_LCNT_1M);
|
||||
} else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_48M) {
|
||||
i2c_fs_scl_hcnt__fs_scl_hcnt__setf(I2C_MLCK48M_FREQUENCY_HCNT_1M);
|
||||
i2c_fs_scl_lcnt__fs_scl_lcnt__setf(I2C_MCLK48M_FREQUENCY_LCNT_1M);
|
||||
} else if (xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_64M) {
|
||||
i2c_fs_scl_hcnt__fs_scl_hcnt__setf(I2C_MLCK64M_FREQUENCY_HCNT_1M);
|
||||
i2c_fs_scl_lcnt__fs_scl_lcnt__setf(I2C_MCLK64M_FREQUENCY_LCNT_1M);
|
||||
}
|
||||
}
|
||||
|
||||
i2c_flag_status_get(I2C_STATUS_ACTIVITY_SET);
|
||||
|
||||
i2c_enable__enable__setf(I2C_ENABLE_EN_ENABLE);
|
||||
}
|
||||
|
||||
void xc_i2c_enable_it(uint32_t val) { i2c_intr_en_set(val); }
|
||||
|
||||
void xc_i2c_fifo_rxtl_set(uint32_t val) { i2c_rx_tl__rx_tl__setf(val); }
|
||||
|
||||
void xc_i2c_fifo_txtl_set(uint32_t val) { i2c_tx_tl__tx_tl__setf(val); }
|
||||
|
||||
void xc_i2c_ctl_block_reset(void)
|
||||
{
|
||||
memset(&i2c_ctl_block, 0, sizeof(i2c_ctl_block));
|
||||
i2c_ctl_block.i2c_read_cb = NULL;
|
||||
i2c_ctl_block.i2c_write_cb = NULL;
|
||||
}
|
||||
|
||||
void xc_i2c_register_read_cb(i2c_read_callback i2c_cb) { i2c_ctl_block.i2c_read_cb = i2c_cb; }
|
||||
|
||||
void xc_i2c_register_write_cb(i2c_write_callback i2c_cb) { i2c_ctl_block.i2c_write_cb = i2c_cb; }
|
||||
|
||||
void xc_i2c_slave_addr_set(uint8_t addr)
|
||||
{
|
||||
i2c_enable__enable__setf(I2C_ENABLE_EN_DISABLE);
|
||||
i2c_tar__i2c_tar__setf(addr);
|
||||
i2c_enable__enable__setf(I2C_ENABLE_EN_ENABLE);
|
||||
}
|
||||
|
||||
uint32_t xc_i2c_write_block(uint8_t dev_addr, uint8_t *src, size_t len, uint16_t reset, uint16_t stop)
|
||||
{
|
||||
xc_i2c_slave_addr_set(dev_addr);
|
||||
|
||||
uint32_t abort_reason = 0;
|
||||
|
||||
uint16_t timeout = 0xFFFF;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
i2c_data_cmd_set(I2C_DATA_CMD_CMD_WRITE | stop | reset | *src++);
|
||||
|
||||
do {
|
||||
|
||||
} while (timeout-- && !(i2c_raw_intr_stat_get() & I2C_RAW_INTR_STAT_TX_EMPTY_SET));
|
||||
|
||||
if (!timeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
abort_reason = i2c_tx_abrt_source_get();
|
||||
if (abort_reason) {
|
||||
i2c_clr_tx_abrt_get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return abort_reason;
|
||||
}
|
||||
|
||||
uint32_t xc_i2c_read_block(uint8_t dev_addr, uint8_t *dst, size_t len, uint16_t reset, uint16_t stop)
|
||||
{
|
||||
xc_i2c_slave_addr_set(dev_addr);
|
||||
|
||||
uint32_t abort_reason;
|
||||
uint16_t timeout = 0xFFFF;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
while (!(I2C_FIFO_LEN - i2c_txflr_get()))
|
||||
;
|
||||
|
||||
i2c_data_cmd_set(I2C_DATA_CMD_CMD_READ | stop | reset);
|
||||
|
||||
do {
|
||||
|
||||
} while (timeout-- && !i2c_rxflr_get());
|
||||
|
||||
if (!timeout) {
|
||||
DEBUG("xc_i2c_read_block timeout\n");
|
||||
break;
|
||||
}
|
||||
|
||||
abort_reason = i2c_tx_abrt_source_get();
|
||||
if (abort_reason) {
|
||||
DEBUG("xc_i2c_read_block tx_abrt\n");
|
||||
i2c_clr_tx_abrt_get();
|
||||
break;
|
||||
}
|
||||
|
||||
*dst++ = i2c_data_cmd_get();
|
||||
}
|
||||
|
||||
return abort_reason;
|
||||
}
|
||||
|
||||
void i2c_user_handler()
|
||||
{
|
||||
uint8_t val;
|
||||
uint32_t stat;
|
||||
|
||||
stat = i2c_intr_stat_get();
|
||||
val = i2c_clr_intr_get();
|
||||
|
||||
if (stat & I2C_INTR_STAT_RX_DONE_SET) {
|
||||
}
|
||||
if (stat & I2C_INTR_STAT_RX_FULL_SET) {
|
||||
val = i2c_data_cmd__dat__getf();
|
||||
|
||||
if (i2c_ctl_block.i2c_read_cb != NULL) {
|
||||
i2c_ctl_block.i2c_read_cb(&val, 1);
|
||||
}
|
||||
}
|
||||
if (stat & I2C_INTR_STAT_RD_REQ_SET) {
|
||||
|
||||
if (i2c_ctl_block.i2c_write_cb != NULL) {
|
||||
i2c_ctl_block.i2c_write_cb();
|
||||
}
|
||||
}
|
||||
if (stat & I2C_INTR_STAT_TX_EMPTY_SET) {
|
||||
}
|
||||
if (stat & I2C_INTR_STAT_STOP_DET_SET) {
|
||||
}
|
||||
}
|
||||
|
||||
FlagStatus i2c_flag_status_get(uint32_t i2c_flag)
|
||||
{
|
||||
FlagStatus bitstatus = RESET;
|
||||
|
||||
if ((i2c_status_get() & i2c_flag) != (uint32_t)RESET) {
|
||||
bitstatus = SET;
|
||||
} else {
|
||||
bitstatus = RESET;
|
||||
}
|
||||
|
||||
return bitstatus;
|
||||
}
|
||||
|
||||
void I2C_Handler() { i2c_user_handler(); }
|
||||
|
||||
#endif //(I2C_ON)
|
||||
@@ -0,0 +1,312 @@
|
||||
/*!
|
||||
* \file xc_drv_i2c.h
|
||||
*
|
||||
* \brief The header of xc_drv_i2c.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_I2C_H_
|
||||
#define _XC_DRV_I2C_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
#define I2C_FIFO_LEN 16
|
||||
|
||||
/* I2C Init structure definition */
|
||||
typedef struct
|
||||
{
|
||||
|
||||
uint32_t I2C_ClockSpeed;
|
||||
|
||||
uint16_t I2C_Mode;
|
||||
|
||||
uint16_t I2C_SlaveAddr;
|
||||
|
||||
uint8_t DivClk;
|
||||
} I2C_InitCfg_t;
|
||||
|
||||
enum
|
||||
{
|
||||
I2C_FREQUENCY_100K = 0,
|
||||
I2C_FREQUENCY_400K = 1,
|
||||
I2C_FREQUENCY_1M = 2,
|
||||
};
|
||||
|
||||
typedef void (*i2c_write_callback)(void);
|
||||
typedef void (*i2c_read_callback)(uint8_t* buff, uint16_t len);
|
||||
|
||||
typedef struct{
|
||||
i2c_read_callback i2c_read_cb;
|
||||
i2c_write_callback i2c_write_cb;
|
||||
} I2C_Block_t;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define I2C_CON_MASTER_MODE_ENABLE (0x1UL)
|
||||
#define I2C_CON_MASTER_MODE_DISABLE (0x0UL)
|
||||
|
||||
#define I2C_CON_SPEED_STANDARD_MODE (0x1UL)
|
||||
#define I2C_CON_SPEED_FAST_MODE (0x2UL)
|
||||
|
||||
#define I2C_CON_10BITADDR_SLAVE_MODE (0x1UL)
|
||||
#define I2C_CON_7BITADDR_SLAVE_MODE (0x0UL)
|
||||
|
||||
#define I2C_CON_10BITADDR_MASTER_MODE (0x1UL)
|
||||
#define I2C_CON_7BITADDR_MASTER_MODE (0x0UL)
|
||||
|
||||
#define I2C_CON_RESTART_EN_ENABLE (0x1UL)
|
||||
#define I2C_CON_RESTART_EN_DISABLE (0x0UL)
|
||||
|
||||
#define I2C_CON_SLAVE_DISABLE_ENABLE (0x0UL)
|
||||
#define I2C_CON_SLAVE_DISABLE_DISABLE (0x1UL)
|
||||
|
||||
#define I2C_TAR_GC_OR_START_GC (0x0UL)
|
||||
#define I2C_TAR_GC_OR_START_Start (0x1UL)
|
||||
|
||||
#define I2C_TAR_SPECIA_EXECUTE (0x1UL)
|
||||
#define I2C_TAR_SPECIA_IGNORE (0x0UL)
|
||||
|
||||
#define I2C_TAR_I2C_10BITADDR_MODE (0x1UL)
|
||||
#define I2C_TAR_I2C_7BITADDR_MODE (0x0UL)
|
||||
|
||||
#define I2C_DATA_CMD_CMD_READ (0x1UL << CMD_POS)
|
||||
#define I2C_DATA_CMD_CMD_WRITE (0x0UL << CMD_POS)
|
||||
|
||||
#define I2C_DATA_CMD_STOP_SET (0x1UL << I2C_STOP_POS)
|
||||
#define I2C_DATA_CMD_STOP_RESET (0x0UL << I2C_STOP_POS)
|
||||
|
||||
#define I2C_DATA_CMD_RESTART_SET (0x1UL << RESTART_POS)
|
||||
#define I2C_DATA_CMD_RESTART_RESET (0x0UL << RESTART_POS)
|
||||
|
||||
#define I2C_DATA_CMD_DAT_SET (0x1UL << DAT_LSB)
|
||||
#define I2C_DATA_CMD_DAT_RESET (0x0UL << DAT_LSB)
|
||||
|
||||
#define I2C_MLCK32M_FREQUENCY_HCNT_100K (0x8EUL)
|
||||
#define I2C_MLCK32M_FREQUENCY_LCNT_100K (0x9EUL)
|
||||
#define I2C_MLCK32M_FREQUENCY_HCNT_400K (0x18UL)
|
||||
#define I2C_MLCK32M_FREQUENCY_LCNT_400K (0x25UL)
|
||||
#define I2C_MLCK32M_FREQUENCY_HCNT_1M (0x07UL)
|
||||
#define I2C_MCLK32M_FREQUENCY_LCNT_1M (0x0AUL)
|
||||
|
||||
#define I2C_MLCK48M_FREQUENCY_HCNT_100K (0xDBUL)
|
||||
#define I2C_MLCK48M_FREQUENCY_LCNT_100K (0xEBUL)
|
||||
#define I2C_MLCK48M_FREQUENCY_HCNT_400K (0x28UL)
|
||||
#define I2C_MLCK48M_FREQUENCY_LCNT_400K (0x38UL)
|
||||
#define I2C_MLCK48M_FREQUENCY_HCNT_1M (0x0DUL)
|
||||
#define I2C_MCLK48M_FREQUENCY_LCNT_1M (0x0FUL)
|
||||
|
||||
#define I2C_MLCK64M_FREQUENCY_HCNT_100K (0x128UL)
|
||||
#define I2C_MLCK64M_FREQUENCY_LCNT_100K (0x138UL)
|
||||
#define I2C_MLCK64M_FREQUENCY_HCNT_400K (0x39UL)
|
||||
#define I2C_MLCK64M_FREQUENCY_LCNT_400K (0x49UL)
|
||||
#define I2C_MLCK64M_FREQUENCY_HCNT_1M (0x10UL)
|
||||
#define I2C_MCLK64M_FREQUENCY_LCNT_1M (0x14UL)
|
||||
|
||||
#define I2C_INTR_STAT_RX_UNDER_RESET (0x0UL << R_RX_UNDER_POS)
|
||||
#define I2C_INTR_STAT_RX_UNDER_SET (0x1UL << R_RX_UNDER_POS)
|
||||
|
||||
#define I2C_INTR_STAT_RX_OVER_RESET (0x0UL << R_RX_OVER_POS)
|
||||
#define I2C_INTR_STAT_RX_OVER_SET (0x1UL << R_RX_OVER_POS)
|
||||
|
||||
#define I2C_INTR_STAT_RX_FULL_RESET (0x0UL << R_RX_FULL_POS)
|
||||
#define I2C_INTR_STAT_RX_FULL_SET (0x1UL << R_RX_FULL_POS)
|
||||
|
||||
#define I2C_INTR_STAT_TX_OVER_RESET (0x0UL << R_TX_OVER_POS)
|
||||
#define I2C_INTR_STAT_TX_OVER_SET (0x1UL << R_TX_OVER_POS)
|
||||
|
||||
#define I2C_INTR_STAT_TX_EMPTY_RESET (0x0UL << R_TX_EMPTY_POS)
|
||||
#define I2C_INTR_STAT_TX_EMPTY_SET (0x1UL << R_TX_EMPTY_POS)
|
||||
|
||||
#define I2C_INTR_STAT_RD_REQ_RESET (0x0UL << R_RD_REQ_POS)
|
||||
#define I2C_INTR_STAT_RD_REQ_SET (0x1UL << R_RD_REQ_POS)
|
||||
|
||||
#define I2C_INTR_STAT_TX_ABRT_RESET (0x0UL << R_TX_ABRT_POS)
|
||||
#define I2C_INTR_STAT_TX_ABRT_SET (0x1UL << R_TX_ABRT_POS)
|
||||
|
||||
#define I2C_INTR_STAT_RX_DONE_RESET (0x0UL << R_RX_DONE_POS)
|
||||
#define I2C_INTR_STAT_RX_DONE_SET (0x1UL << R_RX_DONE_POS)
|
||||
|
||||
#define I2C_INTR_STAT_ACTIVITY_RESET (0x0UL << R_ACTIVITY_POS)
|
||||
#define I2C_INTR_STAT_ACTIVITY_SET (0x1UL << R_ACTIVITY_POS)
|
||||
|
||||
#define I2C_INTR_STAT_STOP_DET_RESET (0x0UL << R_STOP_DET_POS)
|
||||
#define I2C_INTR_STAT_STOP_DET_SET (0x1UL << R_STOP_DET_POS)
|
||||
|
||||
#define I2C_INTR_STAT_START_DET_RESET (0x1UL << R_START_DET_POS)
|
||||
#define I2C_INTR_STAT_START_DET_SET (0x1UL << R_START_DET_POS)
|
||||
|
||||
#define I2C_INTR_STAT_GEN_CALL_RESET (0x0UL << R_GEN_CALL_POS)
|
||||
#define I2C_INTR_STAT_GEN_CALL_SET (0x1UL << R_GEN_CALL_POS)
|
||||
|
||||
#define I2C_INTR_EN_RX_UNDER_DISABLE (0x0UL << EN_RX_UNDER_POS)
|
||||
#define I2C_INTR_EN_RX_UNDER_ENABLE (0x1UL << EN_RX_UNDER_POS)
|
||||
|
||||
#define I2C_INTR_EN_RX_OVER_DISABLE (0x0UL << EN_RX_OVER_POS)
|
||||
#define I2C_INTR_EN_RX_OVER_ENABLE (0x1UL << EN_RX_OVER_POS)
|
||||
|
||||
#define I2C_INTR_EN_RX_FULL_DISABLE (0x0UL << EN_RX_FULL_POS)
|
||||
#define I2C_INTR_EN_RX_FULL_ENABLE (0x1UL << EN_RX_FULL_POS)
|
||||
|
||||
#define I2C_INTR_EN_TX_OVER_DISABLE (0x0UL << EN_TX_OVER_POS)
|
||||
#define I2C_INTR_EN_TX_OVER_ENABLE (0x1UL << EN_TX_OVER_POS)
|
||||
|
||||
#define I2C_INTR_EN_TX_EMPTY_DISABLE (0x0UL << EN_TX_EMPTY_POS)
|
||||
#define I2C_INTR_EN_TX_EMPTY_ENABLE (0x1UL << EN_TX_EMPTY_POS)
|
||||
|
||||
#define I2C_INTR_EN_RD_REQ_DISABLE (0x0UL << EN_RD_REQ_POS)
|
||||
#define I2C_INTR_EN_RD_REQ_ENABLE (0x1UL << EN_RD_REQ_POS)
|
||||
|
||||
#define I2C_INTR_EN_TX_ABRT_DISABLE (0x0UL << EN_TX_ABRT_POS)
|
||||
#define I2C_INTR_EN_TX_ABRT_ENABLE (0x1UL << EN_TX_ABRT_POS)
|
||||
|
||||
#define I2C_INTR_EN_RX_DONE_DISABLE (0x0UL << EN_RX_DONE_POS)
|
||||
#define I2C_INTR_EN_RX_DONE_ENABLE (0x1UL << EN_RX_DONE_POS)
|
||||
|
||||
#define I2C_INTR_EN_ACTIVITY_DISABLE (0x0UL << EN_ACTIVITY_POS)
|
||||
#define I2C_INTR_EN_ACTIVITY_ENABLE (0x1UL << EN_ACTIVITY_POS)
|
||||
|
||||
#define I2C_INTR_EN_STOP_DET_DISABLE (0x0UL << EN_STOP_DET_POS)
|
||||
#define I2C_INTR_EN_STOP_DET_ENABLE (0x1UL << EN_STOP_DET_POS)
|
||||
|
||||
#define I2C_INTR_EN_START_DET_DISABLE (0x0UL << EN_START_DET_POS)
|
||||
#define I2C_INTR_EN_START_DET_ENABLE (0x1UL << EN_START_DET_POS)
|
||||
|
||||
#define I2C_INTR_EN_GEN_CALL_DISABLE (0x0UL << EN_GEN_CALL_POS)
|
||||
#define I2C_INTR_EN_GEN_CALL_ENABLE (0x1UL << EN_GEN_CALL_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_RX_UNDER_RESET (0x0UL << RX_UNDER_POS)
|
||||
#define I2C_RAW_INTR_STAT_RX_UNDERL_SET (0x1UL << RX_UNDER_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_RX_OVER_RESET (0x0UL << RX_OVER_POS)
|
||||
#define I2C_RAW_INTR_STAT_RX_OVER_SET (0x1UL << RX_OVER_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_RX_FULL_RESET (0x0UL << RX_FULL_POS)
|
||||
#define I2C_RAW_INTR_STAT_RX_FULL_SET (0x1UL << RX_FULL_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_TX_OVER_RESET (0x0UL << TX_OVER_POS)
|
||||
#define I2C_RAW_INTR_STAT_TX_OVER_SET (0x1UL << TX_OVER_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_TX_EMPTY_RESET (0x0UL << TX_EMPTY_POS)
|
||||
#define I2C_RAW_INTR_STAT_TX_EMPTY_SET (0x1UL << TX_EMPTY_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_RD_REQ_RESET (0x0UL << RD_REQ_POS)
|
||||
#define I2C_RAW_INTR_STAT_RD_REQ_SET (0x1UL << RD_REQ_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_TX_ABRT_RESET (0x0UL << TX_ABRT_POS)
|
||||
#define I2C_RAW_INTR_STAT_TX_ABRT_SET (0x1UL << TX_ABRT_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_RX_DONE_RESET (0x0UL << RX_DONE_POS)
|
||||
#define I2C_RAW_INTR_STAT_RX_DONE_SET (0x1UL << RX_DONE_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_ACTIVITY_RESET (0x0UL << ACTIVITY_POS)
|
||||
#define I2C_RAW_INTR_STAT_ACTIVITY_SET (0x1UL << ACTIVITY_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_STOP_DET_RESET (0x0UL << STOP_DET_POS)
|
||||
#define I2C_RAW_INTR_STAT_STOP_DET_SET (0x1UL << STOP_DET_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_START_DET_RESET (0x0UL << START_DET_POS)
|
||||
#define I2C_RAW_INTR_STAT_START_DET_SET (0x1UL << START_DET_POS)
|
||||
|
||||
#define I2C_RAW_INTR_STAT_GEN_CALL_RESET (0x0UL << GEN_CALL_POS)
|
||||
#define I2C_RAW_INTR_STAT_GEN_CALL_SET (0x1UL << GEN_CALL_POS)
|
||||
|
||||
#define I2C_RX_TL_FIFO_1 (0x0UL)
|
||||
#define I2C_RX_TL_FIFO_2 (0x1UL)
|
||||
#define I2C_RX_TL_FIFO_3 (0x2UL)
|
||||
#define I2C_RX_TL_FIFO_4 (0x3UL)
|
||||
#define I2C_RX_TL_FIFO_5 (0x4UL)
|
||||
#define I2C_RX_TL_FIFO_6 (0x5UL)
|
||||
#define I2C_RX_TL_FIFO_7 (0x6UL)
|
||||
#define I2C_RX_TL_FIFO_8 (0x7UL)
|
||||
#define I2C_RX_TL_FIFO_9 (0x8UL)
|
||||
#define I2C_RX_TL_FIFO_10 (0x9UL)
|
||||
#define I2C_RX_TL_FIFO_11 (0xAUL)
|
||||
#define I2C_RX_TL_FIFO_12 (0xBUL)
|
||||
#define I2C_RX_TL_FIFO_13 (0xCUL)
|
||||
#define I2C_RX_TL_FIFO_14 (0xDUL)
|
||||
#define I2C_RX_TL_FIFO_15 (0xEUL)
|
||||
#define I2C_RX_TL_FIFO_16 (0xFUL)
|
||||
|
||||
#define I2C_TX_TL_FIFO_0 (0x0UL)
|
||||
#define I2C_TX_TL_FIFO_1 (0x1UL)
|
||||
#define I2C_TX_TL_FIFO_2 (0x2UL)
|
||||
#define I2C_TX_TL_FIFO_3 (0x3UL)
|
||||
#define I2C_TX_TL_FIFO_4 (0x4UL)
|
||||
#define I2C_TX_TL_FIFO_5 (0x5UL)
|
||||
#define I2C_TX_TL_FIFO_6 (0x6UL)
|
||||
#define I2C_TX_TL_FIFO_7 (0x7UL)
|
||||
#define I2C_TX_TL_FIFO_8 (0x8UL)
|
||||
#define I2C_TX_TL_FIFO_9 (0x9UL)
|
||||
#define I2C_TX_TL_FIFO_10 (0xAUL)
|
||||
#define I2C_TX_TL_FIFO_11 (0xBUL)
|
||||
#define I2C_TX_TL_FIFO_12 (0xCUL)
|
||||
#define I2C_TX_TL_FIFO_13 (0xDUL)
|
||||
#define I2C_TX_TL_FIFO_14 (0xEUL)
|
||||
#define I2C_TX_TL_FIFO_15 (0xFUL)
|
||||
|
||||
#define I2C_ENABLE_EN_DISABLE (0x0UL)
|
||||
#define I2C_ENABLE_EN_ENABLE (0x1UL)
|
||||
|
||||
#define I2C_STATUS_ACTIVITY_RESET (0x0UL << I2C_ACTIVITY_POS)
|
||||
#define I2C_STATUS_ACTIVITY_SET (0x1UL << I2C_ACTIVITY_POS)
|
||||
|
||||
#define I2C_STATUS_TFNF_RESET (0x0UL << TFNF_POS)
|
||||
#define I2C_STATUS_TFNF_SET (0x1UL << TFNF_POS)
|
||||
|
||||
#define I2C_STATUS_TFE_RESET (0x0UL << TFE_POS)
|
||||
#define I2C_STATUS_TFE_SET (0x1UL << TFE_POS)
|
||||
|
||||
#define I2C_STATUS_RFNE_RESET (0x0UL << RFNE_POS)
|
||||
#define I2C_STATUS_RFNE_SET (0x1UL << RFNE_POS)
|
||||
|
||||
#define I2C_STATUS_RFF_RESET (0x0UL << RFF_POS)
|
||||
#define I2C_STATUS_RFF_SET (0x1UL << RFF_POS)
|
||||
|
||||
#define I2C_STATUS_MST_ACTIVITY_RESET (0x0UL << 5)
|
||||
#define I2C_STATUS_MST_ACTIVITY_SET (0x1UL << 5)
|
||||
|
||||
|
||||
|
||||
#define I2C_MODE_MASTER I2C_CON_MASTER_MODE_ENABLE
|
||||
#define I2C_MODE_SLAVE I2C_CON_SLAVE_DISABLE_ENABLE
|
||||
|
||||
#define I2C_CLOCK_SPEED_100K I2C_FREQUENCY_100K
|
||||
#define I2C_CLOCK_SPEED_400K I2C_FREQUENCY_400K
|
||||
#define I2C_CLOCK_SPEED_1M I2C_FREQUENCY_1M
|
||||
|
||||
void xc_i2c_init(I2C_InitCfg_t *i2c_cfg);
|
||||
void xc_i2c_enable_it(uint32_t val);
|
||||
void xc_i2c_fifo_rxtl_set(uint32_t val);
|
||||
void xc_i2c_fifo_txtl_set(uint32_t val);
|
||||
|
||||
FlagStatus i2c_flag_status_get(uint32_t i2c_flag);
|
||||
void xc_i2c_register_read_cb(i2c_read_callback i2c_cb);
|
||||
void xc_i2c_register_write_cb(i2c_write_callback i2c_cb);
|
||||
|
||||
uint32_t xc_i2c_write_block(uint8_t dev_addr, uint8_t *src, size_t len, uint16_t reset, uint16_t stop);
|
||||
uint32_t xc_i2c_read_block(uint8_t dev_addr, uint8_t *dst, size_t len, uint16_t reset, uint16_t stop);
|
||||
#endif
|
||||
@@ -0,0 +1,243 @@
|
||||
/*!
|
||||
* \file xc_drv_pga.c
|
||||
*
|
||||
* \brief Target pga implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_pga.h"
|
||||
#include "xc60xx.h"
|
||||
#include "xc_reg_cpr.h"
|
||||
#if (PGA_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief xc_pga_init
|
||||
* @details
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
|
||||
void xc_pga_init(PGA_InitCfg_t *pga_cfg)
|
||||
{
|
||||
/*opa level 1 gain +20DB*/
|
||||
cpr_opa_ctrl_reg__micgain_2__setf(pga_cfg->gain2);
|
||||
/*opa level 2 gain +22.6DB*/
|
||||
cpr_opa_ctrl_reg__volr_2__setf(pga_cfg->volr2);
|
||||
/*bias register controls current and difference MIC*/
|
||||
cpr_opa_ctrl_reg__resadj__setf(pga_cfg->resadj);
|
||||
/*Comparator hysteresis voltage control*/
|
||||
cpr_opa_ctrl_reg__cmp_ctrl__setf(pga_cfg->cmp_ctrl);
|
||||
/*Comparator current control*/
|
||||
cpr_opa_ctrl_reg__cmp_ibc__setf(pga_cfg->cmp_ibc);
|
||||
/*temperature sensor*/
|
||||
cpr_opa_ctrl_reg__en_temp_sensor__setf(pga_cfg->en_temp_sensor);
|
||||
/*open pdbias*/
|
||||
cpr_opa_ctrl_reg__pdbias__setf(pga_cfg->bias);
|
||||
cpr_opa_ctrl_reg__opa_ctrl__setf(pga_cfg->opa_ctrl);
|
||||
/*opa pd signal*/
|
||||
cpr_opa_ctrl_reg__pdopa__setf(pga_cfg->pdopa);
|
||||
cpr_opa_ctrl_reg__micgain__setf(pga_cfg->micgain);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_micgain_2_set
|
||||
* @details
|
||||
* @param micgain2 (BIT0) £ºinput First-order gain ( PGA_MIC_GAIN2_ENABLE - PGA_MIC_GAIN2_DISABLE)
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_micgain_2_set(uint8_t micgain2)
|
||||
{
|
||||
cpr_opa_ctrl_reg__micgain_2__setf(micgain2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_volr2_set
|
||||
* @details
|
||||
* @param volr2 (BIT0 - BIT3) £ºinput Two-stage gain ( PGA_VOLR2_GAIN_0_0DB - PGA_VOLR2_GAIN_0_0DB)
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_volr2_set(uint8_t volr2)
|
||||
{
|
||||
cpr_opa_ctrl_reg__volr_2__setf(volr2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_resadj_set
|
||||
* @details
|
||||
* @param resadj (BIT0 - BIT4) BIT2 -BIT4 :ELECTRICITY (PGA_ELECTRICITY_LEVEL0 - PGA_ELECTRICITY_LEVEL7)
|
||||
BIT1:pga input (SINGLE or PGA_DIFFERENCE)
|
||||
BIT0:unused
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_resadj_set(uint8_t resadj)
|
||||
{
|
||||
cpr_opa_ctrl_reg__resadj__setf(resadj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_cmp_ctrl_set
|
||||
* @details
|
||||
* @param cmp_ctrl : CMP_CTRL_VOLTAGE_LEVEL0 - CMP_CTRL_VOLTAGE_LEVEL3
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_cmp_ctrl_set(uint8_t cmp_ctrl)
|
||||
{
|
||||
cpr_opa_ctrl_reg__cmp_ctrl__setf(cmp_ctrl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_cmp_ibc_set
|
||||
* @details
|
||||
* @param cmp_ibc : CMP_IBC_ELECTRICITY_LEVEL0 - CMP_IBC_ELECTRICITY_LEVEL3
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_cmp_ibc_set(uint8_t cmp_ibc)
|
||||
{
|
||||
cpr_opa_ctrl_reg__cmp_ibc__setf(cmp_ibc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_temp_sensor_enable
|
||||
* @details
|
||||
* @param en_temp_sensor : TEMP_SENSOR_ENABLE / TEMP_SENSOR_DISABLE
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_temp_sensor_enable(uint8_t en_temp_sensor)
|
||||
{
|
||||
cpr_opa_ctrl_reg__en_temp_sensor__setf(en_temp_sensor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_volr_set
|
||||
* @details unused
|
||||
* @param volr
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_volr_set(uint8_t volr)
|
||||
{
|
||||
cpr_opa_ctrl_reg__volr__setf(volr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_pdbias_set
|
||||
* @details
|
||||
* @param pdbias :pdbias signal : 1:PD 0:EN
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_pdbias_set(uint8_t pdbias)
|
||||
{
|
||||
cpr_opa_ctrl_reg__pdbias__setf(pdbias);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
********************************************************************************************
|
||||
* @brief xc_pga_opa_ctrl_set
|
||||
* @details
|
||||
* @param opa_ctrl (BIT0 - BIT2) BIT2:(pdopa signal : 1:pd 0:en)
|
||||
BIT1:(pdopa signal input swap: 1:enable 0:disable)
|
||||
BIT0:(pdopa CTRL ELECTRICITY: 1:min 0:max)
|
||||
* @retval void
|
||||
*********************************************************************************************
|
||||
**/
|
||||
void xc_pga_opa_ctrl_set(uint8_t opa_ctrl)
|
||||
{
|
||||
cpr_opa_ctrl_reg__opa_ctrl__setf(opa_ctrl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
**********************************************************************************************
|
||||
* @brief xc_pga_pdopa_set
|
||||
* @details
|
||||
* @param pdopa signal : 1:pd 0:en
|
||||
* @retval void
|
||||
**********************************************************************************************
|
||||
*/
|
||||
void xc_pga_pdopa_set(uint8_t pdopa)
|
||||
{
|
||||
cpr_opa_ctrl_reg__pdopa__setf(pdopa);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**********************************************************************************************
|
||||
* @brief xc_pga_micgain_set
|
||||
* @details unused
|
||||
* @param micgain
|
||||
* @retval void
|
||||
**********************************************************************************************
|
||||
*/
|
||||
void xc_pga_micgain_set(uint8_t micgain)
|
||||
{
|
||||
cpr_opa_ctrl_reg__micgain__setf(micgain);
|
||||
}
|
||||
|
||||
#endif //(PGA_ON)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*!
|
||||
* \file pga_adc.h
|
||||
*
|
||||
* \brief The head file of pga_adc.h
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC_DRV_PGA_H_
|
||||
#define __XC_DRV_PGA_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#define PGA_PDBIAS_EN 0
|
||||
#define PGA_PDBIAS_PD 1
|
||||
|
||||
#define PGA_ELECTRICITY_LEVEL0 (0x07<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL1 (0x06<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL2 (0x05<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL3 (0x4<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL4 (0x3<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL5 (0x2<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL6 (0x1<<2)
|
||||
#define PGA_ELECTRICITY_LEVEL7 (0x0<<2) /* max electricity*/
|
||||
#define PGA_SINGLE (0x0<<1)
|
||||
#define PGA_DIFFERENCE (0x1<<1)
|
||||
|
||||
|
||||
#define CMP_CTRL_VOLTAGE_LEVEL0 (0x00) /* 0MV */
|
||||
#define CMP_CTRL_VOLTAGE_LEVEL1 (0x01) /* 12MV */
|
||||
#define CMP_CTRL_VOLTAGE_LEVEL2 (0x02) /* 23MV */
|
||||
#define CMP_CTRL_VOLTAGE_LEVEL3 (0x03) /* max electricity 36MV*/
|
||||
|
||||
#define CMP_IBC_ELECTRICITY_LEVEL0 (0x03) /* 1.43ua */
|
||||
#define CMP_IBC_ELECTRICITY_LEVEL1 (0x02) /* 2ua */
|
||||
#define CMP_IBC_ELECTRICITY_LEVEL2 (0x01) /* 3.33ua */
|
||||
#define CMP_IBC_ELECTRICITY_LEVEL3 (0x00) /* max electricity 10ua*/
|
||||
|
||||
#define TEMP_SENSOR_ENABLE 1
|
||||
#define TEMP_SENSOR_DISABLE 0
|
||||
|
||||
#define PGA_OPA_CTRL_SIGNAL_PD (0x1<<2)
|
||||
#define PGA_OPA_CTRL_SIGNAL_EN (0x0<<2)
|
||||
#define PGA_OPA_CTRL_INPUT_SWAP_ENABLE (0x1<<1)
|
||||
#define PGA_OPA_CTRL_INPUT_SWAP_DISABLE (0x0<<2)
|
||||
#define PGA_OPA_CTRL_ELECTRICITY_MAX (0x0<<0)
|
||||
#define PGA_OPA_CTRL_ELECTRICITY_MIN (0x1<<0)
|
||||
|
||||
#define PDOPA_SIGNAL_PD 1
|
||||
#define PDOPA_SIGNAL_EN 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PGA_MIC_GAIN2_DISABLE = 0,
|
||||
PGA_MIC_GAIN2_ENABLE = 1,
|
||||
} PGA_MIC_GAIN2TypeDef_t;
|
||||
|
||||
|
||||
/* 0 - 22.3db */
|
||||
typedef enum
|
||||
{
|
||||
PGA_VOLR2_GAIN_0_0DB = 0,
|
||||
PGA_VOLR2_GAIN_1_6DB = 1,
|
||||
PGA_VOLR2_GAIN_3_2DB = 2,
|
||||
PGA_VOLR2_GAIN_4_8DB = 3,
|
||||
PGA_VOLR2_GAIN_6_4DB = 4,
|
||||
PGA_VOLR2_GAIN_8_0DB = 5,
|
||||
PGA_VOLR2_GAIN_9_6DB = 6,
|
||||
PGA_VOLR2_GAIN_11_2DB = 7,
|
||||
PGA_VOLR2_GAIN_12_8DB = 8,
|
||||
PGA_VOLR2_GAIN_14_4DB = 9,
|
||||
PGA_VOLR2_GAIN_16_0DB = 10,
|
||||
PGA_VOLR2_GAIN_17_6DB = 11,
|
||||
PGA_VOLR2_GAIN_19_2DB = 12,
|
||||
PGA_VOLR2_GAIN_20_8DB = 13,
|
||||
PGA_VOLR2_GAIN_22_3DB = 14,
|
||||
} PGA_VOLR2TypeDef_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief CPR_OPA_CTRL_REG register definition
|
||||
* <pre>
|
||||
* Bits Field Name Reset Value
|
||||
* ----- ------------------ -----------
|
||||
* 28 micgain2 0
|
||||
* 27:24 volr2 0x0
|
||||
* 23:19 resadj 0x0
|
||||
* 18:17 cmp_ctrl 0x0
|
||||
* 16:15 cmp_ibc 0x0
|
||||
* 14 bg5v_ctrl 0
|
||||
* 13 en_temp_sensor 0
|
||||
* 12 pdbias 0
|
||||
* 11:08 volr 0x0
|
||||
* 07:05 opa_ctrl 0x0
|
||||
* 04 pdopa 0
|
||||
* 03:00 micgain 0x0
|
||||
* </pre>
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
PGA_MIC_GAIN2TypeDef_t gain2;
|
||||
PGA_VOLR2TypeDef_t volr2;
|
||||
uint8_t resadj;
|
||||
uint8_t cmp_ctrl;
|
||||
uint8_t cmp_ibc;
|
||||
uint8_t bg5v_ctrl;
|
||||
uint8_t en_temp_sensor;
|
||||
uint8_t bias;
|
||||
uint8_t volr;
|
||||
uint8_t opa_ctrl;
|
||||
uint8_t pdopa;
|
||||
uint8_t micgain;
|
||||
} PGA_InitCfg_t;
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_pga_init(PGA_InitCfg_t *pga_cfg);
|
||||
void xc_pga_micgain_2_set(uint8_t micgain2);
|
||||
void xc_pga_volr2_set(uint8_t volr2);
|
||||
void xc_pga_resadj_set(uint8_t resadj);
|
||||
void xc_pga_cmp_ctrl_set(uint8_t cmp_ctrl);
|
||||
void xc_pga_cmp_ibc_set(uint8_t cmp_ibc);
|
||||
void xc_pga_temp_sensor_enable(uint8_t en_temp_sensor);
|
||||
void xc_pga_volr_set(uint8_t volr);
|
||||
void xc_pga_pdbias_set(uint8_t pdbias);
|
||||
void xc_pga_opa_ctrl_set(uint8_t opa_ctrl);
|
||||
void xc_pga_pdopa_set(uint8_t pdopa);
|
||||
void xc_pga_micgain_set(uint8_t micgain);
|
||||
|
||||
#endif //__XC_DRV_PGA_H_
|
||||
@@ -0,0 +1,461 @@
|
||||
/*!
|
||||
* \file xc_drv_pwm.c
|
||||
*
|
||||
* \brief Target xc pwm driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
/*------------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_pwm.h"
|
||||
#include "xc_drv_gpio.h"
|
||||
#if (PWM_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
STATE_UNINITIALIZED,
|
||||
STATE_INITIALIZED,
|
||||
} xincx_drv_state_t;
|
||||
|
||||
pwm_handler_callback pwm_n_callback[3] = {
|
||||
pwm_capture_ch0_callback,
|
||||
pwm_capture_ch1_callback,
|
||||
pwm_capture_ch2_callback,
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static uint32_t pwm_clk_init_state = STATE_UNINITIALIZED;
|
||||
|
||||
static uint16_t pwm_freq_to_period(PWM_InitCfg_t *pwm_cfg, PWM_ClkDiv_TypeDef div_clk);
|
||||
|
||||
double period;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_pwm_init(uint8_t reg_idx, PWM_InitCfg_t *init_cfg)
|
||||
{
|
||||
if (pwm_clk_init_state == STATE_UNINITIALIZED) {
|
||||
|
||||
cpr_ctlapbclken_grctl__pwm_pclk_en__setf(ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__pwm_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__pwm_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_pwm_clk_ctl__pwm_clk_en__setf(ENABLE);
|
||||
cpr_pwm_clk_ctl__pwm_clksel__setf(init_cfg->SrcClk);
|
||||
cpr_pwm_clk_ctl__pwm_clk0_div__setf(init_cfg->DivClk);
|
||||
cpr_pwm_clk_ctl__pwm_clk1_div__setf(init_cfg->DivClk);
|
||||
|
||||
pwm_clk_init_state = STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
pwm_pin_set(reg_idx, init_cfg);
|
||||
|
||||
pwm_en__en__setf(reg_idx, DISABLE);
|
||||
|
||||
pwm_en__en_sel__setf(reg_idx, init_cfg->SrcEnable);
|
||||
|
||||
xc_pwm_dutycycle_set(reg_idx, init_cfg->Mode, init_cfg->DutyCycleAcc, init_cfg->DutyCycle);
|
||||
|
||||
pwm_period__period__setf(reg_idx, pwm_freq_to_period(init_cfg, PWM_CLK_DIV0));
|
||||
|
||||
pwm_compen__pwmcompen__setf(reg_idx, init_cfg->InvertEnable);
|
||||
|
||||
pwm_comptime__comptime__setf(reg_idx, init_cfg->InvertDelay);
|
||||
}
|
||||
|
||||
void xc_pwm_start(uint8_t reg_idx) { pwm_en__en__setf(reg_idx, PWM_EN_ENABLE); }
|
||||
|
||||
void xc_pwm_stop(uint8_t reg_idx) { pwm_en__en__setf(reg_idx, PWM_EN_DISABLE); }
|
||||
|
||||
void pwm_src_enable_set(uint8_t reg_idx, uint8_t src_enable) { pwm_en__en_sel__setf(reg_idx, src_enable); }
|
||||
|
||||
void xc_pwm_start_all(void) { pwm_en__pwm_en_all__setf(PWM0_IDX, PWM_EN_ALL_ENABLE); }
|
||||
|
||||
void xc_pwm_stop_all(void) { pwm_en__pwm_en_all__setf(PWM0_IDX, PWM_EN_ALL_DISABLE); }
|
||||
|
||||
void pwm_pin_set(uint8_t reg_idx, PWM_InitCfg_t *pwm_cfg)
|
||||
{
|
||||
GPIO_InitCfg_t gpio_cfg;
|
||||
if(pwm_cfg->OutputPin==GPIO_11||pwm_cfg->OutputPin==GPIO_12||pwm_cfg->OutputPin==GPIO_13){
|
||||
gpio_cfg.Mux = GPIO_Mux1;
|
||||
}else
|
||||
{
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
}
|
||||
gpio_cfg.Dir = GPIO_DIR_OUTPUT;
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
gpio_cfg.Int = NOT_INT;
|
||||
gpio_cfg.Pin = pwm_cfg->OutputPin;
|
||||
|
||||
if (reg_idx == PWM0_IDX || reg_idx == PWM1_IDX) {
|
||||
gpio_cfg.FunSel = (reg_idx == PWM0_IDX) ? PWM0 : PWM1;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
if (pwm_cfg->InvertEnable) {
|
||||
gpio_cfg.FunSel = (reg_idx == PWM0_IDX) ? PWM0_INV : PWM1_INV;
|
||||
|
||||
gpio_cfg.Pin = pwm_cfg->OutputInvertPin;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
} else if (reg_idx == PWM2_IDX) {
|
||||
gpio_cfg.Mux = GPIO_Mux3;
|
||||
if (pwm_cfg->OutputPin == GPIO_12) {
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
if (pwm_cfg->InvertEnable) {
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
gpio_cfg.FunSel = PWM2_INV;
|
||||
gpio_cfg.Pin = pwm_cfg->OutputInvertPin;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
|
||||
} else if (reg_idx == PWM3_IDX) {
|
||||
gpio_cfg.Mux = GPIO_Mux3;
|
||||
if (pwm_cfg->OutputPin == GPIO_13) {
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
if (pwm_cfg->InvertEnable) {
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
gpio_cfg.FunSel = PWM3_INV;
|
||||
gpio_cfg.Pin = pwm_cfg->OutputInvertPin;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
|
||||
} else if (reg_idx == PWM4_IDX) {
|
||||
gpio_cfg.Mux = GPIO_Mux2;
|
||||
if (pwm_cfg->OutputPin == GPIO_0) {
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
} else if (reg_idx == PWM5_IDX) {
|
||||
gpio_cfg.Mux = GPIO_Mux2;
|
||||
if (pwm_cfg->OutputPin == GPIO_1) {
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t pwm_freq_to_period(PWM_InitCfg_t *pwm_cfg, PWM_ClkDiv_TypeDef div_clk)
|
||||
{
|
||||
uint32_t pwm_clk;
|
||||
uint32_t freq_max;
|
||||
uint32_t freq;
|
||||
|
||||
switch (pwm_cfg->SrcClk) {
|
||||
case PWM_CLK_SRC_32M_DIV: {
|
||||
pwm_clk = xc_clock_hfclk_in_get() / PWM_CLK_DIV_CAL(div_clk);
|
||||
} break;
|
||||
|
||||
case PWM_CLK_SRC_32K_DIV: {
|
||||
pwm_clk = xc_clock_lfclk_in_get() / PWM_CLK_DIV_CAL(div_clk);
|
||||
} break;
|
||||
|
||||
case PWM_CLK_SRC_32K: {
|
||||
pwm_clk = CLOCK_LFCLK_IN_32K;
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(pwm_cfg->Mode == PWM_EN_MODE_EDGE_ALIGNED){
|
||||
freq_max = PWM_FREQ_MAX_CAL(pwm_clk, pwm_cfg->DutyCycleAcc);
|
||||
freq = PWM_FREQ_CAL(pwm_clk, pwm_cfg->DutyCycleAcc, pwm_cfg->Period);
|
||||
}else if(pwm_cfg->Mode == PWM_EN_MODE_CENTER_ALIGNED){
|
||||
freq_max = PWM_FREQ_MAX_CAL(pwm_clk, pwm_cfg->DutyCycleAcc)>>1;
|
||||
freq = PWM_FREQ_CAL(pwm_clk, pwm_cfg->DutyCycleAcc, pwm_cfg->Period)>>1;
|
||||
}
|
||||
|
||||
|
||||
if (freq > freq_max) {
|
||||
DEBUG("%s,line=%d,set freq=%d,The maximum configurable frequency %d hz \
|
||||
has been exceeded.\n",
|
||||
__func__, __LINE__, freq, freq_max);
|
||||
} else {
|
||||
DEBUG("%s,line=%d,set freq=%d,maximum configurable frequency %d hz\n", __func__, __LINE__, freq, freq_max);
|
||||
}
|
||||
|
||||
return pwm_cfg->Period;
|
||||
}
|
||||
|
||||
void xc_pwm_dutycycle_set(uint8_t reg_idx, uint8_t mode, uint32_t dutycycle_acc, uint32_t dutycycle)
|
||||
{
|
||||
if(mode == PWM_EN_MODE_EDGE_ALIGNED){
|
||||
pwm_en__mode__setf(reg_idx, PWM_EN_MODE_EDGE_ALIGNED);
|
||||
pwm_ocpy__ocpy_ratio_config__setf(reg_idx, dutycycle_acc-1);
|
||||
pwm_ocpy__ocpy_ratio__setf(reg_idx, dutycycle);
|
||||
}else if(mode == PWM_EN_MODE_CENTER_ALIGNED){
|
||||
pwm_en__mode__setf(reg_idx, PWM_EN_MODE_CENTER_ALIGNED);
|
||||
pwm_ocpy__ocpy_ratio_config__setf(reg_idx, (dutycycle_acc));
|
||||
pwm_ocpy__ocpy_ratio__setf(reg_idx, dutycycle_acc - dutycycle);
|
||||
}
|
||||
|
||||
pwm_up__update__setf(reg_idx, PWM_UP_UPDATE_ENABLE);
|
||||
}
|
||||
|
||||
void xc_pwm_lowpower_enable(uint8_t reg_idx) { pwm_en__sleep_en__setf(reg_idx, PWM_EN_SLEEP_EN_ENABLE); }
|
||||
|
||||
void xc_pwm_lowpower_disable(uint8_t reg_idx) { pwm_en__sleep_en__setf(reg_idx, PWM_EN_SLEEP_EN_DISABLE); }
|
||||
|
||||
void xc_pwm_lowpower_countdirection_set(uint8_t reg_idx, uint32_t direction)
|
||||
{
|
||||
pwm_en__sleep_incr__setf(reg_idx, direction);
|
||||
}
|
||||
|
||||
void xc_pwm_brake_enable(uint8_t reg_idx)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = pwm_break_ctl__pwm_brk_enable__getf(PWM0_IDX);
|
||||
|
||||
if (reg_idx == PWM0_IDX || reg_idx == PWM1_IDX) {
|
||||
val &= ~(PWM_BRK0_ENABLE_ENABLE);
|
||||
val |= (PWM_BRK0_ENABLE_ENABLE);
|
||||
} else if (reg_idx == PWM2_IDX || reg_idx == PWM3_IDX) {
|
||||
val &= ~(PWM_BRK1_ENABLE_ENABLE);
|
||||
val |= (PWM_BRK1_ENABLE_ENABLE);
|
||||
} else if (reg_idx == PWM4_IDX || reg_idx == PWM5_IDX) {
|
||||
val &= ~(PWM_BRK2_ENABLE_ENABLE);
|
||||
val |= (PWM_BRK2_ENABLE_ENABLE);
|
||||
}
|
||||
|
||||
pwm_break_ctl__pwm_brk_enable__setf(PWM0_IDX, val);
|
||||
}
|
||||
|
||||
void xc_pwm_brake_disable(uint8_t reg_idx)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = pwm_break_ctl__pwm_brk_enable__getf(PWM0_IDX);
|
||||
|
||||
if (reg_idx == PWM0_IDX || reg_idx == PWM1_IDX) {
|
||||
val &= ~(PWM_BRK0_ENABLE_ENABLE);
|
||||
} else if (reg_idx == PWM2_IDX || reg_idx == PWM3_IDX) {
|
||||
val &= ~(PWM_BRK1_ENABLE_ENABLE);
|
||||
} else if (reg_idx == PWM4_IDX || reg_idx == PWM5_IDX) {
|
||||
val &= ~(PWM_BRK2_ENABLE_ENABLE);
|
||||
}
|
||||
|
||||
pwm_break_ctl__pwm_brk_enable__setf(PWM0_IDX, val);
|
||||
}
|
||||
|
||||
uint8_t xc_pwm_brake_signal_valid_get(void) { return pwm_break_ctl__pwm_brk_sync__getf(PWM0_IDX); }
|
||||
|
||||
void xc_pwm_brake_signal_mask_set(uint32_t mask) { pwm_break_ctl__pwm_brk_mask__setf(PWM0_IDX, mask); }
|
||||
|
||||
void xc_pwm_brake_signal_trigger_level_set(uint32_t level) { pwm_break_ctl__pwm_brk_inv__setf(PWM0_IDX, level); }
|
||||
|
||||
void xc_pwm_brake_recovery_mode_set(uint32_t mode) { pwm_break_ctl__brk_mode__setf(PWM0_IDX, mode); }
|
||||
|
||||
uint8_t xc_pwm_brake_recovery_mode_get(void) { return (pwm_break_ctl__brk_mode__getf(PWM0_IDX)); }
|
||||
|
||||
void xc_pwm_brake_debounce_set(uint32_t debounce, uint32_t step)
|
||||
{
|
||||
pwm_break_ctl__brk_dbc_en__setf(PWM0_IDX, debounce);
|
||||
pwm_break_ctl__brk_dbc_step__setf(PWM0_IDX, step);
|
||||
}
|
||||
|
||||
void xc_pwm_brake_clear() { pwm_break_ctl__clear__setf(PWM0_IDX, PWM_BRK_BRK_CLEAR_EXIT); }
|
||||
|
||||
void xc_pwm_capture_enable(uint8_t ch) { cap_tim_ctl__capture_enable__setf(ch, PWM_CAPTURE_ENABLE); }
|
||||
|
||||
void xc_pwm_capture_disable(uint8_t ch) { cap_tim_ctl__capture_enable__setf(ch, PWM_CAPTURE_DISABLE); }
|
||||
|
||||
void xc_pwm_capture_enable_it(uint8_t ch)
|
||||
{
|
||||
if (ch == 0) {
|
||||
pwm_cap_tim_int_en__capture_upd_0_en__setf(ENABLE);
|
||||
} else if (ch == 1) {
|
||||
pwm_cap_tim_int_en__capture_upd_1_en__setf(ENABLE);
|
||||
} else if (ch == 2) {
|
||||
pwm_cap_tim_int_en__capture_upd_2_en__setf(ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void xc_pwm_capture_disable_it(uint8_t ch)
|
||||
{
|
||||
if (ch == PWM_IC_CH0) {
|
||||
pwm_cap_tim_int_en__capture_upd_0_en__setf(DISABLE);
|
||||
} else if (ch == PWM_IC_CH1) {
|
||||
pwm_cap_tim_int_en__capture_upd_1_en__setf(DISABLE);
|
||||
} else if (ch == PWM_IC_CH2) {
|
||||
pwm_cap_tim_int_en__capture_upd_2_en__setf(DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void xc_pwm_capture_signal_set(uint8_t ch, uint32_t signal) { cap_tim_ctl__capture_sig_sel__setf(ch, signal); }
|
||||
|
||||
void xc_pwm_capture_debounce_enable(uint8_t ch, uint32_t step)
|
||||
{
|
||||
cap_tim_ctl__dbc_en__setf(ch, PWM_CAPTURE_DBC_ENABLE);
|
||||
|
||||
cap_tim_ctl__dbc_step__setf(ch, step);
|
||||
}
|
||||
|
||||
void xc_pwm_capture_debounce_disable(uint8_t ch, uint32_t step)
|
||||
{
|
||||
cap_tim_ctl__dbc_en__setf(ch, PWM_CAPTURE_DBC_DISABLE);
|
||||
|
||||
cap_tim_ctl__dbc_step__setf(ch, step);
|
||||
}
|
||||
|
||||
void xc_pwm_capture_edge_set(uint8_t ch, uint32_t edge) { cap_tim_ctl__capture_mode__setf(ch, edge); }
|
||||
|
||||
void xc_pwm_capture_psc_set(uint8_t ch, uint32_t psc) { cap_tim_ctl__capture_psc__setf(ch, psc); }
|
||||
|
||||
void xc_pwm_capture_counter_enable(uint8_t ch)
|
||||
{
|
||||
cap_tim_ctl__common_cnt_enable__setf(ch, PWM_CAPTURE_COMMON_CNT_ENABLE);
|
||||
}
|
||||
|
||||
void xc_pwm_capture_counter_disable(uint8_t ch)
|
||||
{
|
||||
cap_tim_ctl__common_cnt_enable__setf(ch, PWM_CAPTURE_COMMON_CNT_DISABLE);
|
||||
}
|
||||
|
||||
uint16_t xc_pwm_capture_val_get(uint8_t ch) { return cap_tim_val__capture_value__getf(ch); }
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------------------------
|
||||
* PWM Timer
|
||||
*-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_pwm_timer_init(uint8_t reg_idx, PWM_Timer_InitCfg_t *init_cfg)
|
||||
{
|
||||
if (reg_idx > PWM_TIMER5_IDX)
|
||||
return;
|
||||
|
||||
if (pwm_clk_init_state == STATE_UNINITIALIZED) {
|
||||
cpr_ctlapbclken_grctl__pwm_pclk_en__setf(ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__pwm_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__pwm_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_pwm_clk_ctl__pwm_clk_en__setf(ENABLE);
|
||||
cpr_pwm_clk_ctl__pwm_clksel__setf(init_cfg->src_clk);
|
||||
cpr_pwm_clk_ctl__pwm_clk0_div__setf(init_cfg->clk_div);
|
||||
cpr_pwm_clk_ctl__pwm_clk1_div__setf(init_cfg->clk_div);
|
||||
|
||||
pwm_clk_init_state = STATE_INITIALIZED;
|
||||
}
|
||||
|
||||
uint32_t ctl_reg = (init_cfg->timer_mode << TIMER_MODE_POS) | (init_cfg->timer_int_mask_en << TIMER_INT_MASK_POS) |
|
||||
(init_cfg->timer_pwm_en << TIMER_PWM_POS) |
|
||||
(init_cfg->timer_0to100_pwm_en << TIMER_ON10OPWM_EN_POS);
|
||||
|
||||
pwm_timer_controlreg_set(reg_idx, ctl_reg);
|
||||
}
|
||||
|
||||
void xc_pwm_timer_deinit(uint8_t reg_idx)
|
||||
{
|
||||
pwm_clk_init_state = STATE_UNINITIALIZED;
|
||||
cpr_ctlapbclken_grctl__pwm_pclk_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_pwm_timer_set_freq(uint8_t reg_idx, uint32_t freq) { period = xc_clock_hfclk_in_get() / 2 / freq; }
|
||||
|
||||
void xc_pwm_timer_set_dutycycle(uint8_t reg_idx, double dutycycle)
|
||||
{
|
||||
uint16_t high_cnt = ((uint32_t)(period * dutycycle) / 100);
|
||||
uint16_t low_cnt = (uint32_t)(period - high_cnt);
|
||||
|
||||
pwm_timer_loadcount__timer_lc__setf(reg_idx, low_cnt);
|
||||
pwm_timer_loadcount2__timer_lc2__setf(reg_idx, high_cnt);
|
||||
}
|
||||
|
||||
void xc_pwm_timer_set_high_cnt(uint8_t reg_idx, uint16_t high_cnt)
|
||||
{
|
||||
pwm_timer_loadcount2__timer_lc2__setf(reg_idx, high_cnt);
|
||||
}
|
||||
|
||||
void xc_pwm_timer_set_low_cnt(uint8_t reg_idx, uint16_t low_cnt)
|
||||
{
|
||||
pwm_timer_loadcount__timer_lc__setf(reg_idx, low_cnt);
|
||||
}
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_pwm_timer_start(uint8_t reg_idx) { pwm_timer_controlreg__timer_en__setf(reg_idx, ENABLE); }
|
||||
|
||||
void xc_pwm_timer_stop(uint8_t reg_idx) { pwm_timer_controlreg__timer_en__setf(reg_idx, DISABLE); }
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------*/
|
||||
|
||||
void PWM_Handler(void)
|
||||
{
|
||||
uint32_t cap_tim_int;
|
||||
|
||||
cap_tim_int = pwm_cap_tim_int_get();
|
||||
|
||||
pwm_cap_tim_int_set(cap_tim_int); // clear inter
|
||||
|
||||
if ((cap_tim_int & PWM_CAPTURE_UPD0_EN_ENABLE) == PWM_CAPTURE_UPD0_EN_ENABLE) {
|
||||
pwm_capture_ch0_callback(NULL);
|
||||
}
|
||||
if ((cap_tim_int & PWM_CAPTURE_UPD1_EN_ENABLE) == PWM_CAPTURE_UPD1_EN_ENABLE) {
|
||||
pwm_capture_ch1_callback(NULL);
|
||||
}
|
||||
if ((cap_tim_int & PWM_CAPTURE_UPD2_EN_ENABLE) == PWM_CAPTURE_UPD2_EN_ENABLE) {
|
||||
pwm_capture_ch2_callback(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
__WEAK uint8_t pwm_capture_ch0_callback(void *context) { return 0; }
|
||||
|
||||
__WEAK uint8_t pwm_capture_ch1_callback(void *context) { return 0; }
|
||||
|
||||
__WEAK uint8_t pwm_capture_ch2_callback(void *context) { return 0; }
|
||||
|
||||
#endif //(PWM_ON)
|
||||
@@ -0,0 +1,319 @@
|
||||
/*!
|
||||
* \file xc_drv_pwm.h
|
||||
*
|
||||
* \brief The header of xc_drv_pwm.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_PWM_H_
|
||||
#define _XC_DRV_PWM_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define PWM_CLK_DIV_CAL(div) (2 * (div + 1))
|
||||
#define PWM_FREQ_MAX_CAL(pwm_clk, dutycycle_acc) \
|
||||
(pwm_clk / (dutycycle_acc * (0 + 1)))
|
||||
#define PWM_FREQ_CAL(pwm_clk, dutycycle_acc, period) \
|
||||
(pwm_clk / (dutycycle_acc * (period + 1)))
|
||||
|
||||
#define PWM_UP_UPDATE_ENABLE (1UL)
|
||||
#define PWM_UP_UPDATE_DISABLE (0UL)
|
||||
|
||||
#define PWM_EN_ENABLE (0x01UL)
|
||||
#define PWM_EN_DISABLE (0x00UL)
|
||||
#define PWM_EN_ALL_ENABLE (0x01UL)
|
||||
#define PWM_EN_ALL_DISABLE (0x00UL)
|
||||
#define PWM_EN_SLEEP_EN_ENABLE (0x01UL)
|
||||
#define PWM_EN_SLEEP_EN_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_EN_MODE_EDGE_ALIGNED (0x03UL)
|
||||
#define PWM_EN_MODE_CENTER_ALIGNED (0x02UL)
|
||||
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_Pos (0x00UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_Msk (0xFFUL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_1CLK (0x00UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_2CLK (0x01UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_3CLK (0x02UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_4CLK (0x03UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_5CLK (0x04UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_6CLK (0x05UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_7CLK (0x06UL)
|
||||
#define PWM_COMP_TIME_PWMCOMPTIME_VAL_8CLK (0x07UL)
|
||||
|
||||
#define PWM_BRK_BRK_CLEAR_EXIT (0x01UL)
|
||||
|
||||
#define PWM_BRK_DBC_EN_ENABLE (0x01UL)
|
||||
#define PWM_BRK_DBC_EN_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_BRK_DBC_STEP1 (0x01UL)
|
||||
#define PWM_BRK_DBC_STEP2 (0x02UL)
|
||||
#define PWM_BRK_DBC_STEP3 (0x03UL)
|
||||
#define PWM_BRK_DBC_STEP4 (0x04UL)
|
||||
#define PWM_BRK_DBC_STEP5 (0x05UL)
|
||||
#define PWM_BRK_DBC_STEP6 (0x06UL)
|
||||
#define PWM_BRK_DBC_STEP7 (0x07UL)
|
||||
#define PWM_BRK_DBC_STEP8 (0x08UL)
|
||||
#define PWM_BRK_DBC_STEP9 (0x09UL)
|
||||
#define PWM_BRK_DBC_STEP10 (0x0AUL)
|
||||
|
||||
#define PWM_BRK0_INV_ENABLE (0x01UL)
|
||||
#define PWM_BRK0_INV_DISABLE (0x00UL)
|
||||
#define PWM_BRK1_INV_ENABLE (0x02UL)
|
||||
#define PWM_BRK1_INV_DISABLE (0x00UL)
|
||||
#define PWM_BRK2_INV_ENABLE (0x04UL)
|
||||
#define PWM_BRK2_INV_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_BRK0_MASK_ENABLE (0x01UL)
|
||||
#define PWM_BRK0_MASK_DISABLE (0x00UL)
|
||||
#define PWM_BRK1_MASK_ENABLE (0x02UL)
|
||||
#define PWM_BRK1_MASK_DISABLE (0x00UL)
|
||||
#define PWM_BRK2_MASK_ENABLE (0x04UL)
|
||||
#define PWM_BRK2_MASK_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_BRK0_ENABLE_ENABLE (0x01UL)
|
||||
#define PWM_BRK0_ENABLE_DISABLE (0x00UL)
|
||||
#define PWM_BRK1_ENABLE_ENABLE (0x02UL)
|
||||
#define PWM_BRK1_ENABLE_DISABLE (0x00UL)
|
||||
#define PWM_BRK2_ENABLE_ENABLE (0x04UL)
|
||||
#define PWM_BRK2_ENABLE_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_CAPTURE_UPD0_EN_ENABLE (0x01UL)
|
||||
#define PWM_CAPTURE_UPD1_EN_ENABLE (0x02UL)
|
||||
#define PWM_CAPTURE_UPD2_EN_ENABLE (0x04UL)
|
||||
|
||||
#define PWM_CAPTURE_PSC_1 (0x00UL)
|
||||
#define PWM_CAPTURE_PSC_2 (0x01UL)
|
||||
#define PWM_CAPTURE_PSC_3 (0x02UL)
|
||||
|
||||
#define PWM_CAPTURE_MODE_RISE (0x00UL)
|
||||
#define PWM_CAPTURE_MODE_FALL (0x01UL)
|
||||
#define PWM_CAPTURE_MODE_BOTH (0x02UL)
|
||||
|
||||
#define PWM_CAPTURE_DBC_STEP0 (0x00UL)
|
||||
#define PWM_CAPTURE_DBC_STEP1 (0x01UL)
|
||||
#define PWM_CAPTURE_DBC_STEP2 (0x02UL)
|
||||
#define PWM_CAPTURE_DBC_STEP3 (0x03UL)
|
||||
#define PWM_CAPTURE_DBC_STEP4 (0x04UL)
|
||||
#define PWM_CAPTURE_DBC_STEP5 (0x05UL)
|
||||
#define PWM_CAPTURE_DBC_STEP6 (0x06UL)
|
||||
#define PWM_CAPTURE_DBC_STEP7 (0x07UL)
|
||||
#define PWM_CAPTURE_DBC_STEP8 (0x08UL)
|
||||
#define PWM_CAPTURE_DBC_STEP9 (0x09UL)
|
||||
#define PWM_CAPTURE_DBC_STEP10 (0x0AUL)
|
||||
#define PWM_CAPTURE_DBC_STEP11 (0x0BUL)
|
||||
#define PWM_CAPTURE_DBC_STEP12 (0x0CUL)
|
||||
|
||||
#define PWM_CAPTURE_SIG_SEL_PWM_CAPTURE0 (0x00UL)
|
||||
#define PWM_CAPTURE_SIG_SEL_PWM_CAPTURE1 (0x01UL)
|
||||
#define PWM_CAPTURE_SIG_SEL_PWM_CAPTURE2 (0x02UL)
|
||||
#define PWM_CAPTURE_SIG_SEL_PWM_BRK0 (0x03UL)
|
||||
#define PWM_CAPTURE_SIG_SEL_PWM_BRK1 (0x04UL)
|
||||
#define PWM_CAPTURE_SIG_SEL_PWM_BRK2 (0x05UL)
|
||||
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_0 (0x00UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_2 (0x01UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_3 (0x02UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_4 (0x03UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_5 (0x04UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_6 (0x05UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_7 (0x06UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_8 (0x07UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_9 (0x08UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_10 (0x09UL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_11 (0x0AUL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_12 (0x0BUL)
|
||||
#define PWM_CAPTURE_CLK_DIV_VAL_13 (0x0CUL)
|
||||
|
||||
#define PWM_CAPTURE_ENABLE (0x01UL)
|
||||
#define PWM_CAPTURE_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_CAPTURE_DBC_ENABLE (0x01UL)
|
||||
#define PWM_CAPTURE_DBC_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_CAPTURE_COMMON_CNT_ENABLE (0x01UL)
|
||||
#define PWM_CAPTURE_COMMON_CNT_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_CAPTURE_UPD_EN_ENABLE (0x01UL)
|
||||
#define PWM_CAPTURE_UPD_EN_DISABLE (0x00UL)
|
||||
|
||||
#define PWM_SIGNAL_CAPTURE0_GPIO3 GPIO_3
|
||||
#define PWM_SIGNAL_CAPTURE1_GPIO8 GPIO_8
|
||||
#define PWM_SIGNAL_CAPTURE2_GPIO9 GPIO_9
|
||||
#define PWM_SIGNAL_BRK0_GPIO4 GPIO_4
|
||||
#define PWM_SIGNAL_BRK1_GPIO5 GPIO_5
|
||||
#define PWM_SIGNAL_BRK2_GPIO6 GPIO_6
|
||||
|
||||
#define PWM_IC_CH0 0
|
||||
#define PWM_IC_CH1 1
|
||||
#define PWM_IC_CH2 2
|
||||
|
||||
#define PWM_BRK_SYNC_VALID 1
|
||||
#define PWM_BRK_SYNC_INVALID 0
|
||||
|
||||
#define PWM_BRK0_HIGH_LEVEL PWM_BRK0_INV_DISABLE
|
||||
#define PWM_BRK0_LOW_LEVEL PWM_BRK0_INV_ENABLE
|
||||
#define PWM_BRK1_HIGH_LEVEL PWM_BRK1_INV_DISABLE
|
||||
#define PWM_BRK1_LOW_LEVEL PWM_BRK1_INV_ENABLE
|
||||
#define PWM_BRK2_HIGH_LEVEL PWM_BRK2_INV_DISABLE
|
||||
#define PWM_BRK2_LOW_LEVEL PWM_BRK2_INV_ENABLE
|
||||
|
||||
#define PWM_ICSIG_CAPTURE0 PWM_CAPTURE_SIG_SEL_PWM_CAPTURE0
|
||||
#define PWM_ICSIG_CAPTURE1 PWM_CAPTURE_SIG_SEL_PWM_CAPTURE1
|
||||
#define PWM_ICSIG_CAPTURE2 PWM_CAPTURE_SIG_SEL_PWM_CAPTURE2
|
||||
|
||||
#define PWM_ALL_ENABLE PWM_EN_ALL_ENABLE
|
||||
#define PWM_ALL_DISABLE PWM_EN_ALL_DISABLE
|
||||
|
||||
#define PWM_SLEEP_COUNT_DIRECTION_UP (0x01UL)
|
||||
#define PWM_SLEEP_COUNT_DIRECTION_DOWN (0x00UL)
|
||||
|
||||
#define PWM_SLEEP_ENABLE PWM_SLEEP_EN_ENABLE
|
||||
#define PWM_SLEEP_DISABLE PWM_SLEEP_EN_DISABLE
|
||||
|
||||
#define PWM_EN_SEL_SELF (0x00UL)
|
||||
#define PWM_EN_SEL_ALL (0x01UL)
|
||||
|
||||
#define PWM_BRK_MODE_HARDWARE (0x00UL)
|
||||
#define PWM_BRK_MODE_SOFTWARE (0x01UL)
|
||||
|
||||
#define PWM_TIMER_MODE_USER_DEFINED (0x01UL)
|
||||
#define PWM_TIMER_MODE_FREE_RUNNING (0x00UL)
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
PWM_CLK_SRC_32M_DIV = 0, /*PWM CLK SRC 32MHz div.*/
|
||||
PWM_CLK_SRC_32K_DIV = 1, /*PWM CLK SRC 32kHz div.*/
|
||||
PWM_CLK_SRC_32K = 4, /*PWM CLK SRC 32kHz.*/
|
||||
} PWM_ClkSrc_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PWM_CLK_DIV0 = 0UL, /*PWM CLK 16 MHz or 16KHz*/
|
||||
PWM_CLK_DIV1 = 1UL, /*PWM CLK 8 MHz or 8KHz*/
|
||||
PWM_CLK_DIV3 = 3UL, /*PWM CLK 4 MHz or 4KHz.*/
|
||||
PWM_CLK_DIV7 = 7UL, /*PWM CLK 2 MHz or 2KHz.*/
|
||||
PWM_CLK_DIV15 = 15UL, /*PWM CLK 1 MHz or 1KHz.*/
|
||||
PWM_CLK_DIV31 = 31UL, /*PWM CLK 500 kHz or 500Hz.*/
|
||||
PWM_CLK_DIV63 = 63UL, /*PWM CLK 250 kHz or 250Hz.*/
|
||||
PWM_CLK_DIV127 = 127UL, /*PWM CLK 125 kHz or 125Hz.*/
|
||||
PWM_CLK_DIV255 = 255UL, /*PWM CLK 62500 Hz or 62.5Hz.*/
|
||||
} PWM_ClkDiv_TypeDef;
|
||||
|
||||
typedef enum pwm_timer_number
|
||||
{
|
||||
PWM_NO_TIMER = 0x00,
|
||||
PWM_TIMER_1 = 0x01,
|
||||
PWM_TIMER_2 = 0x02,
|
||||
PWM_TIMER_3 = 0x04,
|
||||
PWM_TIMER_4 = 0x08,
|
||||
PWM_TIMER_5 = 0x10,
|
||||
PWM_TIMER_6 = 0x20,
|
||||
PWM_ALL_TIMER = 0x3F,
|
||||
} ePWM_Timer_Num;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PWM_ClkSrc_TypeDef SrcClk;
|
||||
uint8_t Mode;
|
||||
uint32_t DutyCycleAcc;
|
||||
uint32_t DutyCycle;
|
||||
uint8_t SrcEnable;
|
||||
uint8_t Period;
|
||||
uint8_t DivClk;
|
||||
uint8_t OutputPin;
|
||||
uint8_t OutputInvertPin;
|
||||
uint8_t InvertDelay;
|
||||
bool InvertEnable;
|
||||
|
||||
} PWM_InitCfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PWM_ClkSrc_TypeDef src_clk;
|
||||
PWM_ClkDiv_TypeDef clk_div;
|
||||
uint8_t timer_0to100_pwm_en;
|
||||
uint8_t timer_pwm_en;
|
||||
uint8_t timer_int_mask_en;
|
||||
uint8_t timer_mode; /* 0x0 FREE_RUNNING; 0x1 USER_DEFINED */
|
||||
} PWM_Timer_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef uint8_t (*pwm_handler_callback)(void *context);
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_pwm_init(uint8_t reg_idx, PWM_InitCfg_t *pwm_cfg);
|
||||
void xc_pwm_start(uint8_t reg_idx);
|
||||
void xc_pwm_stop(uint8_t reg_idx);
|
||||
void xc_pwm_start_all(void);
|
||||
void xc_pwm_stop_all(void);
|
||||
void pwm_pin_set(uint8_t reg_idx, PWM_InitCfg_t *pwm_cfg);
|
||||
void xc_pwm_dutycycle_set(uint8_t reg_idx, uint8_t mode, uint32_t dutycycle_acc, uint32_t dutycycle);
|
||||
void xc_pwm_lowpower_enable(uint8_t reg_idx);
|
||||
void xc_pwm_lowpower_disable(uint8_t reg_idx);
|
||||
void xc_pwm_lowpower_countdirection_set(uint8_t reg_idx, uint32_t direction);
|
||||
void xc_pwm_brake_enable(uint8_t reg_idx);
|
||||
void xc_pwm_brake_disable(uint8_t reg_idx);
|
||||
uint8_t xc_pwm_brake_signal_valid_get(void);
|
||||
void xc_pwm_brake_signal_mask_set(uint32_t mask);
|
||||
void xc_pwm_brake_signal_trigger_level_set(uint32_t invert);
|
||||
void xc_pwm_brake_recovery_mode_set(uint32_t mode);
|
||||
uint8_t xc_pwm_brake_recovery_mode_get(void);
|
||||
void xc_pwm_brake_debounce_set(uint32_t debounce, uint32_t step);
|
||||
void xc_pwm_brake_clear(void);
|
||||
void xc_pwm_capture_enable(uint8_t ch);
|
||||
void xc_pwm_capture_disable(uint8_t ch);
|
||||
void xc_pwm_capture_enable_it(uint8_t ch);
|
||||
void xc_pwm_capture_disable_it(uint8_t ch);
|
||||
void xc_pwm_capture_signal_set(uint8_t ch, uint32_t signal);
|
||||
void xc_pwm_capture_debounce_enable(uint8_t ch, uint32_t step);
|
||||
void xc_pwm_capture_debounce_disable(uint8_t ch, uint32_t step);
|
||||
void xc_pwm_capture_edge_set(uint8_t ch, uint32_t edge);
|
||||
void xc_pwm_capture_psc_set(uint8_t ch, uint32_t psc);
|
||||
void xc_pwm_capture_counter_enable(uint8_t ch);
|
||||
void xc_pwm_capture_counter_disable(uint8_t ch);
|
||||
uint16_t xc_pwm_capture_val_get(uint8_t ch);
|
||||
|
||||
void xc_pwm_timer_init(uint8_t reg_idx, PWM_Timer_InitCfg_t *init_cfg);
|
||||
void xc_pwm_timer_deinit(uint8_t reg_idx);
|
||||
void xc_pwm_timer_set_freq(uint8_t reg_idx, uint32_t freq);
|
||||
void xc_pwm_timer_set_dutycycle(uint8_t reg_idx, double dutycycle);
|
||||
void xc_pwm_timer_start(uint8_t reg_idx);
|
||||
void xc_pwm_timer_stop(uint8_t reg_idx);
|
||||
void xc_pwm_timer_set_high_cnt(uint8_t reg_idx, uint16_t high_cnt);
|
||||
void xc_pwm_timer_set_low_cnt(uint8_t reg_idx, uint16_t high_cnt);
|
||||
|
||||
uint8_t pwm_capture_ch0_callback(void *context);
|
||||
uint8_t pwm_capture_ch1_callback(void *context);
|
||||
uint8_t pwm_capture_ch2_callback(void *context);
|
||||
#endif // _XC_DRV_PWM_H_
|
||||
@@ -0,0 +1,937 @@
|
||||
/*!
|
||||
* \file xc_drv_pwr.c
|
||||
*
|
||||
* \brief Target xc6xxx hal power implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_pwr.h"
|
||||
#if (USE_ROM_FLASH)
|
||||
#include "xc6xxx_fmc_spi.h"
|
||||
#endif // (USE_ROM_FLASH)
|
||||
#if (PWR_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_pwr_vol_set(void)
|
||||
{
|
||||
uint32_t hf_clk = xc_clock_hfclk_in_get();
|
||||
|
||||
switch (hf_clk) {
|
||||
case CLOCK_HFCLK_IN_16M: {
|
||||
cprao_aon_bbldo_adj_set(0x2c);
|
||||
cprao_aon_lpoldo_adj_set(4);
|
||||
// XC_CPR_AO->BBLDO_ADJ = 0x3C; // 0x4a;
|
||||
// XC_CPR_AO->LPOLDO_ADJ = 4; // 1;
|
||||
} break;
|
||||
|
||||
case CLOCK_HFCLK_IN_32M: {
|
||||
// if use usb driver, bbldo is at least 0x4E.
|
||||
// cprao_aon_bbldo_adj_set(0x4E);
|
||||
cprao_aon_bbldo_adj_set(0x2a);
|
||||
cprao_aon_lpoldo_adj_set(7);
|
||||
// XC_CPR_AO->BBLDO_ADJ = 0x9E; // 0x2C;
|
||||
// XC_CPR_AO->LPOLDO_ADJ = 7;
|
||||
} break;
|
||||
|
||||
case CLOCK_HFCLK_IN_48M: {
|
||||
cprao_aon_bbldo_adj_set(0x2b);
|
||||
cprao_aon_lpoldo_adj_set(7);
|
||||
// XC_CPR_AO->BBLDO_ADJ = 0x9C;
|
||||
// XC_CPR_AO->LPOLDO_ADJ = 4;
|
||||
} break;
|
||||
|
||||
case CLOCK_HFCLK_IN_64M: {
|
||||
cprao_aon_bbldo_adj_set(0x2b);
|
||||
cprao_aon_lpoldo_adj_set(7);
|
||||
// XC_CPR_AO->BBLDO_ADJ = 0x9C;
|
||||
// XC_CPR_AO->LPOLDO_ADJ = 4;
|
||||
} break;
|
||||
|
||||
case CLOCK_HFCLK_IN_96M: {
|
||||
cprao_aon_bbldo_adj_set(0x2f);
|
||||
cprao_aon_lpoldo_adj_set(7);
|
||||
// XC_CPR_AO->BBLDO_ADJ = 0x9e;
|
||||
// XC_CPR_AO->LPOLDO_ADJ = 7;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
cprao_aon_bbldo_adj_set(0x2c);
|
||||
cprao_aon_lpoldo_adj_set(4);
|
||||
// XC_CPR_AO->BBLDO_ADJ = 0x9C;
|
||||
// XC_CPR_AO->LPOLDO_ADJ = 4;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_powerdown
|
||||
* @details adc power down
|
||||
* @param void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_powerdown(void)
|
||||
{
|
||||
adc_rf_ctl__pd_adc__setf(ADC_RF_CTL_PD_GADC_POWERDOWN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
**************************************************************************************
|
||||
* @brief xc_adc_wakeup
|
||||
* @details adc wakeup
|
||||
* @param void
|
||||
* @retval void
|
||||
***************************************************************************************
|
||||
*/
|
||||
void xc_adc_wakeup(void)
|
||||
{
|
||||
adc_rf_ctl__pd_adc__setf(ADC_RF_CTL_PD_GADC_WAKWUP);
|
||||
}
|
||||
|
||||
__RAM_CODE void xc_pwr_ao_timer_pclk32k_set(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
cprao_aon_reg1__timer_ao_sleep_clksw__setf(1);
|
||||
|
||||
val = cprao_aon_reg1__timer_ao_sleep_clksw__getf();
|
||||
|
||||
while ((val & 0x01) != 1) {
|
||||
__NOP();
|
||||
__NOP();
|
||||
val = cprao_aon_reg1__timer_ao_sleep_clksw__getf();
|
||||
}
|
||||
}
|
||||
|
||||
void xc_pwr_ao_timer_pclk32m_Set()
|
||||
{
|
||||
cprao_aon_reg1__timer_ao_sleep_clksw__setf(0);
|
||||
}
|
||||
|
||||
void xc_pwr_sleep_init(PWR_InitCfg_t *pwr_cfg)
|
||||
{
|
||||
|
||||
cprao_aon_sys_time_set((RST_READY_TIME << 12) | (OSC32_STABLE_TIME));
|
||||
|
||||
if (pwr_cfg->pwr_sleep_mode == LIGHT_SLEEP_MODE) {
|
||||
xc_pwr_pd_lightsleep_set();
|
||||
xc_pwr_sleepsrc_mask_set(0x1e001e);
|
||||
} else if (pwr_cfg->pwr_sleep_mode == DEEP_SLEEP_MODE) {
|
||||
xc_pwr_pd_deepsleep_set();
|
||||
delay_us(100);
|
||||
xc_pwr_sleepsrc_mask_set(0x1e001e);
|
||||
}
|
||||
|
||||
xc_pwr_osc_off();
|
||||
|
||||
xc_pwr_wake_it_set(pwr_cfg->pwr_wake_it_src);
|
||||
}
|
||||
|
||||
// __RAM_CODE void xc_sleep_init()
|
||||
// {
|
||||
// xc_adc_powerdown();
|
||||
// xc_pwr_usb_off();
|
||||
// xc_pwr_rc16m_off();
|
||||
|
||||
// xc_pwr_rc32k_calib_off();
|
||||
|
||||
// // xc_pwr_rom_off();
|
||||
// xc_pwr_opa_tempsensor_off();
|
||||
// xc_pwr_opa_volr_off();
|
||||
// xc_pwr_revddldo_off();
|
||||
|
||||
// xc_pwr_dcdc_close();
|
||||
// xc_pwr_rfdigital_off();
|
||||
|
||||
// xc_pwr_modem_off();
|
||||
// xc_pwr_pd_lightsleep_set();
|
||||
// }
|
||||
|
||||
__RAM_CODE void xc_pwr_ble_sleep_enter(void)
|
||||
{
|
||||
#if (USE_XIP == 1)
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_PowerDown();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_power_down();
|
||||
#endif // USE_ROM_FLASH
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
cpr_fmc_ctl_set(0x3000 | (1 << 9)); // close fmc
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
#endif // USE_XIP
|
||||
|
||||
__disable_irq();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
__WFI();
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
cpr_fmc_ctl_set(0x3503); // open FMC
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
xc_pwr_rom_on();
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_WakeUp();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_wake_up();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#endif
|
||||
|
||||
xc_pwr_ao_timer_pclk32m_Set();
|
||||
|
||||
// xc_pwr_rom_on();
|
||||
|
||||
__enable_irq();
|
||||
|
||||
#ifdef USED_DCDC
|
||||
xc_pwr_dcdc_open();
|
||||
#endif
|
||||
|
||||
xc_pwr_modem_on();
|
||||
|
||||
xc_pwr_rfdigital_on();
|
||||
|
||||
xc_adc_wakeup();
|
||||
}
|
||||
|
||||
__RAM_CODE void xc_sleep(void)
|
||||
{
|
||||
xc_adc_powerdown();
|
||||
xc_pwr_usb_off();
|
||||
xc_pwr_rc16m_off();
|
||||
|
||||
// xc_pwr_rom_off();
|
||||
xc_pwr_modem_off();
|
||||
xc_pwr_opa_tempsensor_off();
|
||||
xc_pwr_opa_volr_off();
|
||||
xc_pwr_revddldo_off();
|
||||
cprao_aon_reg4__bb_coreldo_normal_sw_mux__setf(1);
|
||||
// xc_pwr_bor_off();
|
||||
|
||||
xc_pwr_dcdc_close();
|
||||
xc_pwr_rfdigital_off();
|
||||
xc_pwr_rc32k_calib_off();
|
||||
rtc_rccal_en_set(0x00);
|
||||
|
||||
xc_pwr_pd_lightsleep_set();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_PowerDown();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_power_down();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
xc_pwr_rom_off();
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
cpr_fmc_ctl_set(0x3000 | (1 << 9)); // close fmc
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
#endif
|
||||
|
||||
__disable_irq();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
__WFI();
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
|
||||
cpr_fmc_ctl_set(0x3503); // open FMC
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
xc_pwr_rom_on();
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_WakeUp();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_wake_up();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#endif
|
||||
|
||||
xc_pwr_ao_timer_pclk32m_Set();
|
||||
|
||||
// xc_pwr_rom_on();
|
||||
|
||||
__enable_irq();
|
||||
|
||||
#ifdef USED_DCDC
|
||||
xc_pwr_dcdc_open();
|
||||
#endif
|
||||
|
||||
xc_pwr_modem_on();
|
||||
|
||||
xc_pwr_rfdigital_on();
|
||||
|
||||
xc_adc_wakeup();
|
||||
}
|
||||
|
||||
__RAM_CODE void xc_deep_sleep()
|
||||
{
|
||||
|
||||
xc_pwr_ao_timer_pclk32k_set();
|
||||
adc_rf_ctl__pd_adc__setf(ADC_RF_CTL_PD_GADC_POWERDOWN);
|
||||
xc_pwr_usb_off();
|
||||
xc_pwr_rc16m_off();
|
||||
xc_pwr_rfdigital_off();
|
||||
xc_pwr_modem_off();
|
||||
xc_pwr_pd_deepsleep_set();
|
||||
xc_pwr_rom_on();
|
||||
xc_pwr_dcdc_close();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_PowerDown();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_power_down();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
cpr_fmc_ctl_set(0x3000 | (1 << 9)); // close FMC
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
}
|
||||
#endif
|
||||
|
||||
__disable_irq();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
__WFI();
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
cpr_fmc_ctl_set(0x3503);
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
xc_pwr_rom_on();
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_WakeUp();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_wake_up();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#endif
|
||||
|
||||
xc_pwr_ao_timer_pclk32m_Set();
|
||||
|
||||
// xc_pwr_rom_on();
|
||||
|
||||
__enable_irq();
|
||||
|
||||
#ifdef USED_DCDC
|
||||
xc_pwr_dcdc_open();
|
||||
#endif
|
||||
|
||||
xc_pwr_modem_on();
|
||||
|
||||
xc_pwr_rfdigital_on();
|
||||
|
||||
xc_adc_wakeup();
|
||||
}
|
||||
|
||||
__RAM_CODE void xc_pwr_cpu_sleep_enter(void)
|
||||
{
|
||||
xc_pwr_ao_timer_pclk32k_set();
|
||||
|
||||
xc_adc_powerdown();
|
||||
|
||||
xc_pwr_usb_off();
|
||||
|
||||
xc_pwr_rc16m_off();
|
||||
|
||||
xc_pwr_rfdigital_off();
|
||||
|
||||
xc_pwr_modem_off();
|
||||
|
||||
xc_pwr_pd_lightsleep_set(); // auto switch core ldo voltage 1.17v to 0.89v
|
||||
xc_pwr_opa_tempsensor_off();
|
||||
xc_pwr_opa_volr_off();
|
||||
|
||||
xc_pwr_dcdc_close();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_PowerDown();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_power_down();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
cpr_fmc_ctl_set(0x3000 | (1 << 11) | (1 << 9)); // close FMC
|
||||
#endif // USE_XIP
|
||||
xc_pwr_rom_off();
|
||||
|
||||
__disable_irq();
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
__WFI(); // waiting to wake up
|
||||
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
#if (USE_XIP == 1)
|
||||
cpr_fmc_ctl_set(0x3503); // open FMC
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
xc_pwr_rom_on();
|
||||
|
||||
#if (USE_ROM_FLASH)
|
||||
FMC_SPI_Flash_WakeUp();
|
||||
#else // (USE_ROM_FLASH)
|
||||
xc_fmc_spi_flash_wake_up();
|
||||
#endif // (USE_ROM_FLASH)
|
||||
#endif // USE_XIP
|
||||
|
||||
xc_pwr_ao_timer_pclk32m_Set();
|
||||
|
||||
// xc_pwr_rom_on();
|
||||
|
||||
__enable_irq();
|
||||
|
||||
#ifdef USED_DCDC
|
||||
xc_pwr_dcdc_open();
|
||||
#endif
|
||||
|
||||
xc_pwr_modem_on();
|
||||
|
||||
xc_pwr_rfdigital_on();
|
||||
|
||||
xc_adc_wakeup();
|
||||
}
|
||||
|
||||
void xc_pwr_gpio_sleep_config(void)
|
||||
{
|
||||
#if (USE_XIP == 1)
|
||||
/* puctrl1= 0xf ,clk,cs,d0,d1 must pulldown */
|
||||
// cprao_aon_puctrl1_set(0xf);
|
||||
cprao_aon_puctrl1_set(0x5555F);
|
||||
#else
|
||||
|
||||
// if (sleep_mode == LIGHT_SLEEP_MODE) {
|
||||
// XC_CPR_AO->PU_CTRLx[0] = 0x4;
|
||||
// } else if (sleep_mode == DEEP_SLEEP_MODE) {
|
||||
// XC_CPR_AO->PU_CTRLx[0] = 0xf;
|
||||
// }
|
||||
|
||||
#endif
|
||||
|
||||
NVIC_DisableIRQ(GPIO_IRQn);
|
||||
|
||||
GPIO_InitCfg_t gpio_cfg = {0};
|
||||
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
gpio_cfg.Dir = GPIO_DIR_INPUT;
|
||||
gpio_cfg.FunSel = GPIO_Dx;
|
||||
gpio_cfg.Int = NOT_INT;
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
|
||||
// The gpio scripts used cannot be configured. gpio36-39 cannot be
|
||||
// configured.
|
||||
for (int i = 0; i < GPIO_36; i++) {
|
||||
gpio_cfg.Pin = i;
|
||||
|
||||
if (i == 18 || i == 19 ) // Default for uart0
|
||||
{
|
||||
|
||||
} else if (i == 33 || i == 34) {
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
}
|
||||
else if (i == 35) {
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
} else if (i == 20 || i == 21) {
|
||||
// Pins required when using an external 32k crystal
|
||||
if (xc_clock_lfclk_src_get() != CLOCK_LFCLK_SRC_XTAL) {
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
} else {
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// void xc_gpio_sleep_config(void)
|
||||
// {
|
||||
// #if (USE_XIP == 1)
|
||||
// cprao_aon_puctrl1_set(0xf);
|
||||
// // XC_CPR_AO->PU_CTRLx[0] = 0xf; /* puctrl1= 0xf ,clk,cs,d0,d1 must pulldown */
|
||||
// #endif
|
||||
|
||||
// NVIC_DisableIRQ(GPIO_IRQn);
|
||||
|
||||
// GPIO_InitCfg_t gpio_cfg = {0};
|
||||
|
||||
// gpio_cfg.Mux = GPIO_Mux0;
|
||||
// gpio_cfg.Dir = GPIO_DIR_INPUT;
|
||||
// gpio_cfg.FunSel = GPIO_Dx;
|
||||
// gpio_cfg.Int = NOT_INT;
|
||||
// gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
|
||||
// for (int i = 0; i < GPIO_MAX; i++) {
|
||||
// gpio_cfg.Pin = i;
|
||||
|
||||
// if (i == 18 || i == 19) // Default for uart0
|
||||
// {
|
||||
|
||||
// } else if (i == 33 || i == 34) {
|
||||
// xc_gpio_pull_config(i, GPIO_PULLDOWN);
|
||||
// } else if (i == 35) {
|
||||
// gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
// xc_gpio_init(&gpio_cfg);
|
||||
// } else if (i == 20 || i == 21) {
|
||||
// // Pins required when using an external 32k crystal
|
||||
// if (xc_clock_lfclk_src_get() != CLOCK_LFCLK_SRC_XTAL) {
|
||||
// xc_gpio_init(&gpio_cfg);
|
||||
// }
|
||||
// } else {
|
||||
// xc_gpio_init(&gpio_cfg);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void xc_pwr_gpio_lightsleep_wake_config(uint8_t pin, uint8_t edge_it)
|
||||
{
|
||||
GPIO_InitCfg_t gpio_cfg = {0};
|
||||
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
gpio_cfg.Dir = GPIO_DIR_INPUT;
|
||||
gpio_cfg.FunSel = GPIO_Dx;
|
||||
|
||||
if (edge_it == RIS_EDGE_INT) {
|
||||
gpio_cfg.Int = RIS_EDGE_INT;
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
} else if (edge_it == FAIL_EDGE_INT) {
|
||||
gpio_cfg.Int = FAIL_EDGE_INT;
|
||||
gpio_cfg.Pull = GPIO_PULLUP;
|
||||
}
|
||||
|
||||
gpio_cfg.Pin = pin;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
NVIC_EnableIRQ(GPIO_IRQn);
|
||||
}
|
||||
|
||||
void xc_pwr_pwrkey_init(void)
|
||||
{
|
||||
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(ENABLE);
|
||||
cprao_aon_clken_grctl__rtc_clk_en__setf(ENABLE);
|
||||
|
||||
rtc_pwrkey_ctrl0_set(0);
|
||||
rtc_pwrkey_ctrl1_set(0);
|
||||
rtc_pwrkey_ctrl2_set(0);
|
||||
rtc_pwrkey_ctrl3_set(0);
|
||||
}
|
||||
|
||||
void xc_pwr_pwrkey_deepsleep_wake_config(uint8_t pin, uint8_t level)
|
||||
{
|
||||
GPIO_InitCfg_t gpio_cfg = {0};
|
||||
uint32_t val;
|
||||
uint32_t val_ctl;
|
||||
|
||||
gpio_cfg.Mux = GPIO_Mux0;
|
||||
gpio_cfg.Dir = GPIO_DIR_INPUT;
|
||||
gpio_cfg.FunSel = GPIO_Dx;
|
||||
gpio_cfg.Int = NOT_INT;
|
||||
|
||||
if(pin <= GPIO_31) {
|
||||
if (level == DEEP_SLEEP_GPIO_WAKE_HIGH_LEVEL) {
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
|
||||
val = rtc_pwrkey_ctrl0__powkey_edge__getf();
|
||||
val &= ~(1 << pin);
|
||||
rtc_pwrkey_ctrl0__powkey_edge__setf(val);
|
||||
|
||||
} else if (level == DEEP_SLEEP_GPIO_WAKE_LOW_LEVEL) {
|
||||
gpio_cfg.Pull = GPIO_PULLUP;
|
||||
|
||||
val = rtc_pwrkey_ctrl0__powkey_edge__getf();
|
||||
val |= (1 << pin);
|
||||
rtc_pwrkey_ctrl0__powkey_edge__setf(val);
|
||||
}
|
||||
|
||||
gpio_cfg.Pin = pin;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
val_ctl =rtc_pwrkey_ctrl1_get();
|
||||
rtc_pwrkey_ctrl1__powkey_en__setf((1 << pin)|val_ctl);
|
||||
|
||||
rtc_pwrkey_ctrl2__powkey_inten__setf(ENABLE);
|
||||
|
||||
NVIC_EnableIRQ(RTC_IRQn);
|
||||
} else {
|
||||
gpio_cfg.Pin = pin;
|
||||
pin = pin-32;
|
||||
|
||||
if (level == DEEP_SLEEP_GPIO_WAKE_HIGH_LEVEL) {
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
val = rtc_pwrkey_ctrl3__powkey_edge_h__getf();
|
||||
val &= ~(1 << pin);
|
||||
rtc_pwrkey_ctrl3__powkey_edge_h__setf(val);
|
||||
|
||||
} else if (level == DEEP_SLEEP_GPIO_WAKE_LOW_LEVEL) {
|
||||
gpio_cfg.Pull = GPIO_PULLUP;
|
||||
val = rtc_pwrkey_ctrl3__powkey_edge_h__getf();
|
||||
val |= (1 << pin);
|
||||
rtc_pwrkey_ctrl3__powkey_edge_h__setf(val);
|
||||
}
|
||||
|
||||
val_ctl =rtc_pwrkey_ctrl3__powkey_en_h__getf();
|
||||
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
rtc_pwrkey_ctrl2__powkey_inten__setf(ENABLE);
|
||||
|
||||
rtc_pwrkey_ctrl3__powkey_en_h__setf((1 << pin)|val_ctl);
|
||||
|
||||
NVIC_EnableIRQ(RTC_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
void xc_pwr_pwrkey_write_pin(uint8_t pin, uint8_t level)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if(cpr_ctlapbclken_grctl__rtc_pclk_en__getf()==DISABLE){
|
||||
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(ENABLE);
|
||||
}
|
||||
if(cprao_aon_clken_grctl__rtc_clk_en__getf()==DISABLE){
|
||||
cprao_aon_clken_grctl__rtc_clk_en__setf(ENABLE);
|
||||
}
|
||||
if(pin < 32){
|
||||
val = rtc_pwrkey_soft_ctrl0_get();
|
||||
val = val | (1 << pin);
|
||||
rtc_pwrkey_soft_ctrl0_set(val);
|
||||
|
||||
val = rtc_pwrkey_soft_ctrl1_get();
|
||||
if(level == 0){
|
||||
val &= ~(1<<pin);
|
||||
}else{
|
||||
val |= (1<<pin);
|
||||
}
|
||||
rtc_pwrkey_soft_ctrl1_set(val);
|
||||
}else{
|
||||
|
||||
val = rtc_pwrkey_ctrl3__aogpio_soft_out_en_h__getf();
|
||||
val = val | (1 << (pin-32));
|
||||
rtc_pwrkey_ctrl3__aogpio_soft_out_en_h__setf(val);
|
||||
|
||||
val = rtc_pwrkey_ctrl3__aogpio_soft_out_value_h__getf();
|
||||
if(level == 0){
|
||||
val &= ~(1<<(pin-32));
|
||||
}else{
|
||||
val |= (1<<(pin-32));
|
||||
}
|
||||
rtc_pwrkey_ctrl3__aogpio_soft_out_value_h__setf(val);
|
||||
}
|
||||
}
|
||||
|
||||
void xc_pwr_pwrkey_toggle_pin(uint8_t pin)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if(cpr_ctlapbclken_grctl__rtc_pclk_en__getf()==DISABLE){
|
||||
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(ENABLE);
|
||||
}
|
||||
if(cprao_aon_clken_grctl__rtc_clk_en__getf()==DISABLE){
|
||||
cprao_aon_clken_grctl__rtc_clk_en__setf(ENABLE);
|
||||
}
|
||||
|
||||
if(pin < 32){
|
||||
val = rtc_pwrkey_soft_ctrl0_get();
|
||||
val = val | (1 << pin);
|
||||
rtc_pwrkey_soft_ctrl0_set(val);
|
||||
|
||||
val = rtc_pwrkey_soft_ctrl1_get();
|
||||
if(val == 0){
|
||||
val |= (1<<pin);
|
||||
}else{
|
||||
val &= ~(1<<pin);
|
||||
}
|
||||
rtc_pwrkey_soft_ctrl1_set(val);
|
||||
}else{
|
||||
|
||||
val = rtc_pwrkey_ctrl3__aogpio_soft_out_en_h__getf();
|
||||
val = val | (1 << (pin-32));
|
||||
rtc_pwrkey_ctrl3__aogpio_soft_out_en_h__setf(val);
|
||||
|
||||
val = rtc_pwrkey_ctrl3__aogpio_soft_out_value_h__getf();
|
||||
|
||||
if(( val & 1<<(pin-32)) == 0){
|
||||
val |= (1<<(pin-32));
|
||||
}else{
|
||||
val &= ~(1<<(pin-32));
|
||||
}
|
||||
rtc_pwrkey_ctrl3__aogpio_soft_out_value_h__setf(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xc_pwr_dcdc_init(uint8_t vol_level)
|
||||
{
|
||||
if (vol_level > 7) {
|
||||
vol_level = 7;
|
||||
}
|
||||
|
||||
cprao_aon_dcdc_ctr_reg1__dcdc_ctrl__setf(vol_level);
|
||||
|
||||
}
|
||||
|
||||
void xc_pwr_dcdc_close()
|
||||
{
|
||||
// 0b100, 3.3v supply power
|
||||
cprao_aon_reg1__bb_coreldo_dcdc_sw_soft__setf(0);
|
||||
cprao_aon_reg1__bb_coreldo_dcdc_sw_softsel__setf(0);
|
||||
cprao_aon_reg1__bb_coreldo_dcdc_sw_mux__setf(1);
|
||||
cprao_aon_dcdc_ctr_reg0_set(1<<6);
|
||||
|
||||
}
|
||||
|
||||
void xc_pwr_dcdc_open()
|
||||
{
|
||||
cprao_aon_dcdc_ctr_reg0__dcdc_en_soft__setf(1);
|
||||
cprao_aon_dcdc_ctr_reg0__dcdc_bg_en_soft__setf(1);
|
||||
|
||||
// 0b011, dcdc supply power
|
||||
cprao_aon_reg1__bb_coreldo_dcdc_sw_softsel__setf(1);
|
||||
cprao_aon_reg1__bb_coreldo_dcdc_sw_soft__setf(1);
|
||||
for (volatile uint16_t dly = 0; dly < 600; dly++) ;
|
||||
cprao_aon_reg1__bb_coreldo_dcdc_sw_mux__setf(0);
|
||||
}
|
||||
|
||||
#endif //(PWR_ON)
|
||||
@@ -0,0 +1,227 @@
|
||||
/*!
|
||||
* \file xc_drv_pwr.h
|
||||
*
|
||||
* \brief The header of xc_drv_pwr.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC_DRV_PWR_H_
|
||||
#define __XC_DRV_PWR_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define RST_READY_TIME 0x7 // 0x03
|
||||
#define OSC32_STABLE_TIME 80 // 80 =2.5ms 64=2ms, 32=1ms, 16=0.5ms
|
||||
#define WAIT_BLE_EXIT_LOWpwr_TIME 20 // 15
|
||||
#define PRE_WAKEUP_TIME \
|
||||
(RST_READY_TIME + OSC32_STABLE_TIME + WAIT_BLE_EXIT_LOWpwr_TIME)
|
||||
#define DEEP_SLEEP_MODE 0
|
||||
#define LIGHT_SLEEP_MODE 1
|
||||
|
||||
#define DEEP_SLEEP_GPIO_WAKE_HIGH_LEVEL 0
|
||||
#define DEEP_SLEEP_GPIO_WAKE_LOW_LEVEL 1
|
||||
|
||||
#define BLE_IRQn_WAKE (1 << BLE_IRQn)
|
||||
#define GPIO_IRQn_WAKE (1 << GPIO_IRQn)
|
||||
#define RTC_IRQn_WAKE (1 << RTC_IRQn)
|
||||
#define TIMER0_IRQn_WAKE (1 << TIMER0_IRQn)
|
||||
#define TIMER1_IRQn_WAKE (1 << TIMER1_IRQn)
|
||||
#define TIMER2_IRQn_WAKE (1 << TIMER2_IRQn)
|
||||
#define TIMER3_IRQn_WAKE (1 << TIMER3_IRQn)
|
||||
#define TIMER_AO0_IRQn_WAKE (1 << TIMER_AO0_IRQn)
|
||||
#define TIMER_AO1_IRQn_WAKE (1 << TIMER_AO1_IRQn)
|
||||
#define MPU_IRQn_WAKE (1 << MPU_IRQn )
|
||||
|
||||
#define pwr_GPIO_LightSleepConfig pwr_GPIO_SleepConfig
|
||||
#define pwr_GPIO_DeepSleepConfig pwr_GPIO_SleepConfig
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/* pwr Init structure definition */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t pwr_wake_it_src;
|
||||
|
||||
uint32_t pwr_sleep_mode;
|
||||
|
||||
} PWR_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
__INLINE void xc_pwr_wake_it_set(uint32_t Val)
|
||||
{
|
||||
cprao_slpctl_int_mask_set(0xFFFFFFFF & (~Val));
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_usb_off(void) { cpr_rf_reg5_set(0x1C); }
|
||||
|
||||
__INLINE void xc_pwr_rc16m_off(void)
|
||||
{
|
||||
cpr_rf_reg0__rc_16m_disalbe__setf(ENABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_aotimer_src_set32k(void)
|
||||
{
|
||||
cprao_aon_reg1__timer_ao_sleep_clksw__setf(ENABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_aotimer_src_set32m(void)
|
||||
{
|
||||
cprao_aon_reg1__timer_ao_sleep_clksw__setf(DISABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_pd_lightsleep_set(void)
|
||||
{
|
||||
cprao_aon_slp_pd_mask_set(0x101);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_pd_deepsleep_set(void)
|
||||
{
|
||||
cprao_aon_slp_pd_mask_set(0x0);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_osc_off(void)
|
||||
{
|
||||
cprao_aon_slp_ctl_set(0x0);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_modem_off(void)
|
||||
{
|
||||
cprao_aon_vdd_iso_en__vddmdm_en__setf(ENABLE);
|
||||
cprao_aon_vdd_switch_en__vddmdm_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_modem_on(void)
|
||||
{
|
||||
cprao_aon_vdd_iso_en__vddmdm_en__setf(DISABLE);
|
||||
cprao_aon_vdd_switch_en__vddmdm_en__setf(ENABLE);
|
||||
}
|
||||
|
||||
__RAM_CODE __INLINE void xc_pwr_rom_off(void)
|
||||
{
|
||||
cprao_aon_vdd_iso_en__vddrom_en__setf(ENABLE);
|
||||
cprao_aon_vdd_switch_en__vddrom_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
__RAM_CODE __INLINE void xc_pwr_rom_on(void)
|
||||
{
|
||||
cprao_aon_vdd_iso_en__vddrom_en__setf(DISABLE);
|
||||
cprao_aon_vdd_switch_en__vddrom_en__setf(ENABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_rfdigital_off(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = cprao_aon_coreldo_en_get();
|
||||
|
||||
val &= 0xFFFFFFFE;
|
||||
|
||||
cprao_aon_coreldo_en_set(val);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_rfdigital_on(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = cprao_aon_coreldo_en_get();
|
||||
|
||||
val |= 1 << 0;
|
||||
|
||||
cprao_aon_coreldo_en_set(val);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_sleepsrc_mask_set(uint32_t val)
|
||||
{
|
||||
cpr_slp_src_mask_set(val);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_opa_volr_off(void)
|
||||
{
|
||||
// OPA volr off
|
||||
uint32_t val;
|
||||
val = cpr_opa_ctrl_reg__volr__getf();
|
||||
val |= 1 << 2;
|
||||
cpr_opa_ctrl_reg__opa_ctrl__setf(val);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_revddldo_off()
|
||||
{
|
||||
cprao_aon_reg4__bb_lpoldo_ibc__setf(4);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_opa_tempsensor_off(void)
|
||||
{
|
||||
cpr_opa_ctrl_reg__en_temp_sensor__setf(DISABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_bor_on(void)
|
||||
{
|
||||
cprao_aon_bor_ctr_reg0__en_bor__setf(DISABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_bor_off(void)
|
||||
{
|
||||
cprao_aon_bor_ctr_reg0__en_bor__setf(DISABLE);
|
||||
}
|
||||
|
||||
__INLINE void xc_pwr_rc32k_calib_off() {}
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_pwr_sleep_init(PWR_InitCfg_t *pwr_cfg);
|
||||
void xc_pwr_ao_timer_pclk32m_Set(void);
|
||||
void xc_pwr_ao_timer_pclk32k_set(void);
|
||||
void xc_pwr_gpio_sleep_config(void);
|
||||
|
||||
void pwr_cpu_sleep_init(void);
|
||||
__RAM_CODE void xc_pwr_cpu_sleep_enter(void);
|
||||
__RAM_CODE void xc_pwr_ble_sleep_enter(void);
|
||||
// void xc_sleep_init(void);
|
||||
// void xc_gpio_sleep_config(void);
|
||||
__RAM_CODE void xc_deep_sleep(void);
|
||||
__RAM_CODE void xc_sleep(void);
|
||||
|
||||
void xc_pwr_gpio_lightsleep_wake_config(uint8_t pin, uint8_t edge_it);
|
||||
void xc_pwr_pwrkey_init(void);
|
||||
void xc_pwr_pwrkey_deepsleep_wake_config(uint8_t pin, uint8_t level);
|
||||
void pwr_gpio_sleep_wake_config(uint8_t sleep_mode, uint8_t pin, uint8_t it);
|
||||
|
||||
void xc_pwr_dcdc_init(uint8_t vol_level);
|
||||
void xc_pwr_dcdc_close(void);
|
||||
void xc_pwr_dcdc_open(void);
|
||||
|
||||
void xc_pwr_vol_set(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __XC6xxx_HAL_pwr_H_ */
|
||||
@@ -0,0 +1,173 @@
|
||||
/*!
|
||||
* \file xc_drv_qdec.c
|
||||
*
|
||||
* \brief Target xc qdec driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_qdec.h"
|
||||
#if (QDEC_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_qdec_init(Qdec_InitCfg_t *init_cfg)
|
||||
{
|
||||
xc_gpio_mux_ctl(GPIO_21, GPIO_Mux2);
|
||||
xc_gpio_mux_ctl(GPIO_20, GPIO_Mux2);
|
||||
|
||||
// DEBUG("0_CTLAPBCLKEN_GRCTL: %08x\n", cpr_ctlapbclken_grctl_get());
|
||||
cpr_ctlapbclken_grctl__qdec_pclk_en__setf(ENABLE);
|
||||
// DEBUG("1_CTLAPBCLKEN_GRCTL: %08x\n", cpr_ctlapbclken_grctl_get());
|
||||
cpr_rstctl_ctlapb_sw__qdec_rstn__setf(~ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__qdec_rstn__setf(~DISABLE);
|
||||
DEBUG("0_QDEC_CLK_CTL: %08x\n", cpr_qdec_clk_ctl_get());
|
||||
cpr_qdec_clk_ctl__qdec_clk_div__setf(0x07);
|
||||
cpr_qdec_clk_ctl__qdec_clk_en__setf(ENABLE);
|
||||
DEBUG("1_QDEC_CLK_CTL: %08x\n", cpr_qdec_clk_ctl_get());
|
||||
if(ENABLE == init_cfg->auto_clr_en) {
|
||||
qdec_ctl__auto_clr_en__setf(ENABLE);
|
||||
} else {
|
||||
qdec_ctl__auto_clr_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
if(ENABLE == init_cfg->single_sample_rst_en) {
|
||||
qdec_ctl__single_sample_rst_en__setf(ENABLE);
|
||||
} else {
|
||||
qdec_ctl__single_sample_rst_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
if(ENABLE == init_cfg->db_filter_en) {
|
||||
qdec_ctl__db_filter_en__setf(ENABLE);
|
||||
} else {
|
||||
qdec_ctl__db_filter_en__setf(DISABLE);
|
||||
}
|
||||
QDEC_CTL_REG = 0x40;
|
||||
qdec_samp_ctl_pack(init_cfg->db_sample_div,
|
||||
init_cfg->num_pts_sampled,
|
||||
init_cfg->acc_sample_div);
|
||||
|
||||
qdec_int_msk_pack(ENABLE, ENABLE, ENABLE, DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_qdec_enable(void)
|
||||
{
|
||||
qdec_ctl__qdec_en__setf(ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_qdec_disable(void)
|
||||
{
|
||||
qdec_ctl__qdec_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_qdec_start(void)
|
||||
{
|
||||
qdec_ctl__qdec_start__setf(ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_qdec_stop(void)
|
||||
{
|
||||
qdec_ctl__qdec_start__setf(DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void QDEC_Handler(void)
|
||||
{
|
||||
uint8_t qdec_int_mask = qdec_int_msk_get( );
|
||||
uint8_t qdec_int = qdec_int_get( );
|
||||
uint8_t qdec_int_sta = (qdec_int & qdec_int_mask);
|
||||
qdec_int_set(qdec_int);
|
||||
|
||||
if(SINGLE_SAMPLE_MSK_BIT == (qdec_int_sta & SINGLE_SAMPLE_MSK_BIT)) {
|
||||
DEBUG("__SINGLE_SAMPLE_INT__\n");
|
||||
}
|
||||
|
||||
if(SAMPLE_END_MSK_BIT == (qdec_int_sta & SAMPLE_END_MSK_BIT)) {
|
||||
DEBUG("__SAMPLE_END_INT__\n");
|
||||
DEBUG("Sample: %04x\n", (uint16_t)qdec_acc_get( ));
|
||||
DEBUG("DB: %02x\n", (uint8_t)qdec_db_get( ));
|
||||
}
|
||||
|
||||
if(ACC_OF_MSK_BIT == (qdec_int_sta & ACC_OF_MSK_BIT)) {
|
||||
DEBUG("__ACC_INT__\n");
|
||||
}
|
||||
|
||||
if(DB_OF_MSK_BIT == (qdec_int_sta & DB_OF_MSK_BIT)) {
|
||||
DEBUG("__DB_INT__\n");
|
||||
}
|
||||
}
|
||||
#endif //(QDEC_ON)
|
||||
@@ -0,0 +1,120 @@
|
||||
/*!
|
||||
* \file xc_drv_qdec.h
|
||||
*
|
||||
* \brief The header of xc_drv_qdec.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_QDEC_H_
|
||||
#define _XC_DRV_QDEC_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum {
|
||||
QDEC_DIVIDE_DIV_1 = 0,
|
||||
QDEC_DIVIDE_DIV_2 = 1,
|
||||
QDEC_DIVIDE_DIV_4 = 2,
|
||||
QDEC_DIVIDE_DIV_8 = 3,
|
||||
QDEC_DIVIDE_DIV_16 = 4,
|
||||
QDEC_DIVIDE_DIV_32 = 5,
|
||||
QDEC_DIVIDE_DIV_64 = 6,
|
||||
QDEC_DIVIDE_DIV_128 = 7,
|
||||
QDEC_DIVIDE_DIV_256 = 8,
|
||||
QDEC_DIVIDE_DIV_512 = 9,
|
||||
QDEC_DIVIDE_DIV_1024 = 10,
|
||||
QDEC_DIVIDE_DIV_2048 = 11,
|
||||
QDEC_DIVIDE_DIV_4096 = 12,
|
||||
QDEC_DIVIDE_DIV_8192 = 13,
|
||||
QDEC_DIVIDE_DIV_16384 = 14,
|
||||
QDEC_DIVIDE_DIV_32768 = 15,
|
||||
QDEC_DIVIDE_DIV_65536 = 16,
|
||||
QDEC_DIVIDE_DIV_131072 = 17,
|
||||
QDEC_DIVIDE_DIV_262144 = 18,
|
||||
QDEC_DIVIDE_DIV_524288 = 19,
|
||||
QDEC_DIVIDE_DIV_1048576 = 20
|
||||
|
||||
} eSampleDivide;
|
||||
|
||||
typedef enum {
|
||||
QDEC_PTS_NUM_5 = 0,
|
||||
QDEC_PTS_NUM_10 = 1,
|
||||
QDEC_PTS_NUM_40 = 2,
|
||||
QDEC_PTS_NUM_80 = 3,
|
||||
QDEC_PTS_NUM_120 = 4,
|
||||
QDEC_PTS_NUM_160 = 5,
|
||||
QDEC_PTS_NUM_200 = 6,
|
||||
QDEC_PTS_NUM_240 = 7,
|
||||
QDEC_PTS_NUM_280 = 8,
|
||||
QDEC_PTS_NUM_320 = 9,
|
||||
QDEC_PTS_NUM_360 = 10,
|
||||
QDEC_PTS_NUM_400 = 11
|
||||
|
||||
} ePtsNum;
|
||||
|
||||
typedef enum {
|
||||
QDEC_DB_SAMP_DIV_1 = 0,
|
||||
QDEC_DB_SAMP_DIV_2 = 1,
|
||||
QDEC_DB_SAMP_DIV_4 = 2,
|
||||
QDEC_DB_SAMP_DIV_8 = 3,
|
||||
QDEC_DB_SAMP_DIV_16 = 4,
|
||||
QDEC_DB_SAMP_DIV_32 = 5,
|
||||
QDEC_DB_SAMP_DIV_64 = 6
|
||||
|
||||
} eDBSampDiv;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t auto_clr_en;
|
||||
uint8_t single_sample_rst_en;
|
||||
uint8_t db_filter_en;
|
||||
eSampleDivide acc_sample_div;
|
||||
ePtsNum num_pts_sampled;
|
||||
eDBSampDiv db_sample_div;
|
||||
|
||||
} Qdec_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_qdec_init(Qdec_InitCfg_t *init_cfg);
|
||||
void xc_qdec_enable(void);
|
||||
void xc_qdec_disable(void);
|
||||
void xc_qdec_start(void);
|
||||
void xc_qdec_stop(void);
|
||||
|
||||
#endif // _XC_DRV_AOTIMER_H_
|
||||
@@ -0,0 +1,163 @@
|
||||
/*!
|
||||
* \file xc_drv_rtc.c
|
||||
*
|
||||
* \brief Target xc aotimer driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
#if (RTC_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
RTC_Intr_Cb_t RTC_Intr_cb = {
|
||||
NULL,
|
||||
T1_CMR_Callback,
|
||||
T2_CMR_Callback,
|
||||
T3_CMR_Callback,
|
||||
Sec_Callback,
|
||||
Min_Callback,
|
||||
Hour_Callback,
|
||||
Day_Callback};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_rtc_start(void) { rtc_icr__rtc__cnt_e__setf(RTC_ICR_CNTE_ENABLE); }
|
||||
|
||||
void xc_rtc_stop(void) { rtc_icr__rtc__cnt_e__setf(RTC_ICR_CNTE_DISABLE); }
|
||||
|
||||
static void xc_rtc_matchtime_set(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
if (rtc_cfg->MatchTime.ch == RTC_MATCH_T1) {
|
||||
rtc_cmr_one_pack(rtc_cfg->MatchTime.Week, rtc_cfg->MatchTime.Hour,
|
||||
rtc_cfg->MatchTime.Min, rtc_cfg->MatchTime.Sec);
|
||||
} else if (rtc_cfg->MatchTime.ch == RTC_MATCH_T2) {
|
||||
rtc_cmr_two_pack(rtc_cfg->MatchTime.Week, rtc_cfg->MatchTime.Hour,
|
||||
rtc_cfg->MatchTime.Min, rtc_cfg->MatchTime.Sec);
|
||||
} else if (rtc_cfg->MatchTime.ch == RTC_MATCH_T3) {
|
||||
rtc_cmr_three_pack(rtc_cfg->MatchTime.Week, rtc_cfg->MatchTime.Hour,
|
||||
rtc_cfg->MatchTime.Min, rtc_cfg->MatchTime.Sec);
|
||||
}
|
||||
}
|
||||
|
||||
void xc_rtc_date_get(Rtc_DateTypeDef_t *Date) { __rtc_dateget(Date); }
|
||||
|
||||
void xc_rtc_init(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
cpr_ctlapbclken_grctl__rtc_pclk_en__setf(ENABLE);
|
||||
|
||||
cprao_aon_clken_grctl__rtc_clk_en__setf(ENABLE);
|
||||
|
||||
rtc_icr_set(DISABLE);
|
||||
|
||||
rtc_raw_limit__setf(xc_clock_lfclk_in_get());
|
||||
|
||||
rtc_datelimitSet(rtc_cfg);
|
||||
rtc_dateSet(rtc_cfg);
|
||||
|
||||
if (rtc_cfg->MatchTimeEnable) {
|
||||
xc_rtc_matchtime_set(rtc_cfg);
|
||||
rtc_config_matchtimeit(rtc_cfg);
|
||||
}
|
||||
|
||||
if (rtc_cfg->SecIT_Enable) {
|
||||
rtc_config_secit(rtc_cfg);
|
||||
}
|
||||
if (rtc_cfg->MinIT_Enable) {
|
||||
rtc_config_minit(rtc_cfg);
|
||||
}
|
||||
if (rtc_cfg->HourIT_Enable) {
|
||||
rtc_config_hourit(rtc_cfg);
|
||||
}
|
||||
if (rtc_cfg->DayIT_Enable) {
|
||||
rtc_config_dayit(rtc_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
void RTC_Handler(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = rtc_all_intr_ao_get();
|
||||
|
||||
if (val & RTC_AO_ALL_INTR_AO_TIMER_INTR_Msk) {
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_clr__setf(RTC_AO_TIMER_CTL_AO_TIMER_CLR_SET);
|
||||
rtc_ao_timer_ctl__rtc_ao_timer_en__setf(RTC_AO_TIMER_CTL_AO_TIMER_EN_DISABLE);
|
||||
xc_rc32k_soft_calib_set();
|
||||
}
|
||||
|
||||
val = rtc_isr_eoi_get();
|
||||
|
||||
if (val) {
|
||||
rtc_isr_eoi_set(val);
|
||||
|
||||
if ((val & RTC_ICR_T1E_Msk) == RTC_ICR_T1E_Msk){
|
||||
RTC_Intr_cb.T1_CMR_Callback();
|
||||
}
|
||||
if ((val & RTC_ICR_T2E_Msk) == RTC_ICR_T2E_Msk){
|
||||
RTC_Intr_cb.T2_CMR_Callback();
|
||||
}
|
||||
if ((val & RTC_ICR_T3E_Msk) == RTC_ICR_T3E_Msk){
|
||||
RTC_Intr_cb.T3_CMR_Callback();
|
||||
}
|
||||
|
||||
if ((val & RTC_ICR_DaE_Msk) == RTC_ICR_DaE_Msk){
|
||||
RTC_Intr_cb.Day_Callback();
|
||||
}
|
||||
if ((val & RTC_ICR_HoE_Msk) == RTC_ICR_HoE_Msk){
|
||||
RTC_Intr_cb.Hour_Callback();
|
||||
}
|
||||
if ((val & RTC_ICR_MiE_Msk) == RTC_ICR_MiE_Msk){
|
||||
RTC_Intr_cb.Min_Callback();
|
||||
}
|
||||
if ((val & RTC_ICR_SeE_Msk) == RTC_ICR_SeE_Msk){
|
||||
RTC_Intr_cb.Sec_Callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__WEAK uint8_t T1_CMR_Callback(void) { return 0; }
|
||||
|
||||
__WEAK uint8_t T2_CMR_Callback(void) { return 0; }
|
||||
|
||||
__WEAK uint8_t T3_CMR_Callback(void) { return 0; }
|
||||
|
||||
__WEAK uint8_t Sec_Callback(void) { return 0; }
|
||||
|
||||
__WEAK uint8_t Min_Callback(void) { return 0; }
|
||||
|
||||
__WEAK uint8_t Hour_Callback(void) { return 0; }
|
||||
|
||||
__WEAK uint8_t Day_Callback(void) { return 0; }
|
||||
|
||||
#endif //(RTC_ON)
|
||||
@@ -0,0 +1,260 @@
|
||||
/*!
|
||||
* \file xc_drv_rtc.h
|
||||
*
|
||||
* \brief The header of xc_drv_rtc.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_RTC_H_
|
||||
#define _XC_DRV_RTC_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "xc6xxx.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define RTC_ICR_DAE_ENABLE (1UL)
|
||||
#define RTC_ICR_DAE_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_HOE_ENABLE (1UL)
|
||||
#define RTC_ICR_HOE_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_MIE_ENABLE (1UL)
|
||||
#define RTC_ICR_MIE_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_SEE_ENABLE (1UL)
|
||||
#define RTC_ICR_SEE_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_T2E_ENABLE (1UL)
|
||||
#define RTC_ICR_T2E_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_T1E_ENABLE (1UL)
|
||||
#define RTC_ICR_T1E_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_T3E_ENABLE (1UL)
|
||||
#define RTC_ICR_T3E_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_MASK_ALL_ENABLE (1UL)
|
||||
#define RTC_ICR_MASK_ALL_DISABLE (0UL)
|
||||
|
||||
#define RTC_ICR_CNTE_ENABLE (1UL)
|
||||
#define RTC_ICR_CNTE_DISABLE (0UL)
|
||||
|
||||
#define RTC_AO_TIMER_CTL_AO_TIMER_CLR_SET (1UL)
|
||||
#define RTC_AO_TIMER_CTL_AO_TIMER_CLR_RESET (0UL)
|
||||
|
||||
#define RTC_AO_TIMER_CTL_AO_TIMER_EN_ENABLE (1UL)
|
||||
#define RTC_AO_TIMER_CTL_AO_TIMER_EN_DISABLE (0UL)
|
||||
|
||||
|
||||
#define RTC_ICR_T1E_Msk (0x1UL << 5UL) /*!< Bit mask of T1E field. */
|
||||
#define RTC_ICR_T2E_Msk (0x1UL << 4UL) /*!< Bit mask of T2E field. */
|
||||
#define RTC_ICR_T3E_Msk (0x1UL << 6UL) /*!< Bit mask of T3E field. */
|
||||
#define RTC_ICR_DaE_Msk (0x1UL << 0UL) /*!< Bit mask of DaE field. */
|
||||
#define RTC_ICR_HoE_Msk (0x1UL << 1UL) /*!< Bit mask of HoE field. */
|
||||
#define RTC_ICR_MiE_Msk (0x1UL << 2UL) /*!< Bit mask of MiE field. */
|
||||
#define RTC_ICR_SeE_Msk (0x1UL << 3UL) /*!< Bit mask of SeE field. */
|
||||
|
||||
#define RTC_AO_ALL_INTR_AO_TIMER_INTR_Msk (0x1UL << 5UL) /*!< Bit mask of AO_TIMER_INTR field. */
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
RTC_MATCH_SUNDAY = (0x01 << 0), /*Interrupt from TIME1 event. */
|
||||
RTC_MATCH_MONDAY = (0x01 << 1), /*Interrupt from TIME2 event. */
|
||||
RTC_MATCH_TUESDAY = (0x01 << 2), /*Interrupt from TIME3 event. */
|
||||
RTC_MATCH_WEDNESDAY = (0x01 << 3), /*Interrupt from SEC event. */
|
||||
RTC_MATCH_THURSDAY = (0x01 << 4), /*Interrupt from MIN event. */
|
||||
RTC_MATCH_FRIDAY = (0x01 << 5), /*Interrupt from HOUR event. */
|
||||
RTC_MATCH_SATURDAY = (0x01 << 6) /*Interrupt from DAY event. */
|
||||
} RTC_MatchWeek_TypeDef_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTC_MATCH_T1 = (0x01 << 5), /**< MATCH_TIME_1 ch. */
|
||||
RTC_MATCH_T2 = (0x01 << 4), /**< MATCH_TIME_2 ch */
|
||||
RTC_MATCH_T3 = (0x01 << 6), /**< MATCH_TIME_3 ch */
|
||||
} RTC_MatchTimeCh_TypeDef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Sec;
|
||||
uint8_t Min;
|
||||
uint8_t Hour;
|
||||
uint8_t Week;
|
||||
uint16_t Day;
|
||||
} Rtc_DateTypeDef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t HourLimit;
|
||||
uint8_t MinLimit;
|
||||
uint8_t SecLimit;
|
||||
} Rtc_DateLimitTypeDef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ch;
|
||||
uint8_t Sec;
|
||||
uint8_t Min;
|
||||
uint8_t Hour;
|
||||
uint8_t Week;
|
||||
} Rtc_MatchTimeTypeDef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rtc_DateTypeDef_t Date;
|
||||
Rtc_DateLimitTypeDef_t DateLimit;
|
||||
Rtc_MatchTimeTypeDef_t MatchTime;
|
||||
bool MatchTimeEnable;
|
||||
bool SecIT_Enable;
|
||||
bool MinIT_Enable;
|
||||
bool HourIT_Enable;
|
||||
bool DayIT_Enable;
|
||||
} RTC_InitCfg_t;
|
||||
|
||||
typedef struct RTC_Intr_Cb_s
|
||||
{
|
||||
uint8_t (*AO_Timer_Callback)(uint8_t calib_flag);
|
||||
uint8_t (*T1_CMR_Callback)(void);
|
||||
uint8_t (*T2_CMR_Callback)(void);
|
||||
uint8_t (*T3_CMR_Callback)(void);
|
||||
uint8_t (*Sec_Callback)(void);
|
||||
uint8_t (*Min_Callback)(void);
|
||||
uint8_t (*Hour_Callback)(void);
|
||||
uint8_t (*Day_Callback)(void);
|
||||
} RTC_Intr_Cb_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static __inline void __rtc_dateget(Rtc_DateTypeDef_t *Date)
|
||||
{
|
||||
Date->Sec = rtc_ccvr__rtc_ccvr_sec__getf();
|
||||
Date->Min = rtc_ccvr__rtc_ccvr_min__getf();
|
||||
Date->Hour = rtc_ccvr__rtc_ccvr_hour__getf();
|
||||
Date->Day = rtc_ccvr__rtc_ccvr_day__getf();
|
||||
Date->Week = rtc_wvr__getf();
|
||||
}
|
||||
|
||||
static __inline void rtc_datelimitSet(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
rtc_hour_limit__setf(rtc_cfg->DateLimit.HourLimit);
|
||||
rtc_minute_limit__setf(rtc_cfg->DateLimit.MinLimit);
|
||||
rtc_second_limit__setf(rtc_cfg->DateLimit.SecLimit);
|
||||
}
|
||||
|
||||
static __inline void rtc_dateSet(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
rtc_clr__rtc_clr_day__setf(rtc_cfg->Date.Day);
|
||||
rtc_clr__rtc_clr_hour__setf(rtc_cfg->Date.Hour);
|
||||
rtc_clr__rtc_clr_min__setf(rtc_cfg->Date.Min);
|
||||
rtc_clr__rtc_clr_sec__setf(rtc_cfg->Date.Sec);
|
||||
rtc_wlr__setf(rtc_cfg->Date.Week);
|
||||
}
|
||||
|
||||
static __inline void rtc_config_matchtimeit(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
if (rtc_cfg->MatchTime.ch == RTC_MATCH_T1) {
|
||||
if (rtc_cfg->MatchTimeEnable) {
|
||||
rtc_icr__rtc_t1e__setf(1);
|
||||
|
||||
} else {
|
||||
rtc_icr__rtc_t1e__setf(0);
|
||||
}
|
||||
} else if (rtc_cfg->MatchTime.ch == RTC_MATCH_T2) {
|
||||
if (rtc_cfg->MatchTimeEnable) {
|
||||
rtc_icr__rtc_t2e__setf(1);
|
||||
} else {
|
||||
rtc_icr__rtc_t2e__setf(0);
|
||||
}
|
||||
} else if (rtc_cfg->MatchTime.ch == RTC_MATCH_T3) {
|
||||
if (rtc_cfg->MatchTimeEnable) {
|
||||
rtc_icr__rtc_t3e__setf(1);
|
||||
} else {
|
||||
rtc_icr__rtc_t3e__setf(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void rtc_config_secit(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
if (rtc_cfg->SecIT_Enable) {
|
||||
rtc_icr__rtc__se_e__setf(1);
|
||||
} else {
|
||||
rtc_icr__rtc__se_e__setf(0);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void rtc_config_minit(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
if (rtc_cfg->SecIT_Enable) {
|
||||
rtc_icr__rtc__mi_e__setf(1);
|
||||
} else {
|
||||
rtc_icr__rtc__mi_e__setf(0);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void rtc_config_hourit(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
if (rtc_cfg->SecIT_Enable) {
|
||||
rtc_icr__rtc__ho_e__setf(1);
|
||||
} else {
|
||||
rtc_icr__rtc__ho_e__setf(0);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void rtc_config_dayit(RTC_InitCfg_t *rtc_cfg)
|
||||
{
|
||||
if (rtc_cfg->SecIT_Enable) {
|
||||
rtc_icr__rtc__da_e__setf(1);
|
||||
} else {
|
||||
rtc_icr__rtc__da_e__setf(0);
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_rtc_init(RTC_InitCfg_t *rtc_cfg);
|
||||
void xc_rtc_start(void);
|
||||
void xc_rtc_stop(void);
|
||||
void xc_rtc_date_get(Rtc_DateTypeDef_t *Date);
|
||||
uint8_t AO_Timer_Callback(uint8_t calib_flag);
|
||||
uint8_t T1_CMR_Callback(void);
|
||||
uint8_t T2_CMR_Callback(void);
|
||||
uint8_t T3_CMR_Callback(void);
|
||||
uint8_t Sec_Callback(void);
|
||||
uint8_t Min_Callback(void);
|
||||
uint8_t Hour_Callback(void);
|
||||
uint8_t Day_Callback(void);
|
||||
|
||||
void rtc_intr_callback(uint64_t intr_sta);
|
||||
#endif // _XC_DRV_RTC_H_
|
||||
@@ -0,0 +1,598 @@
|
||||
/*!
|
||||
* \file xc6xxx_hal_spi.c
|
||||
*
|
||||
* \brief Target xc6xxx hal spi implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
|
||||
#if (SPI_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool SPI_DMA_IT_Enable_Flag[3];
|
||||
uint8_t SPI_Mode[3];
|
||||
} SPI_CtrlBlock_Typedef;
|
||||
|
||||
SPI_CtrlBlock_Typedef m_spi_cb;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
eXC_RESULT xc_spi_write_bytes(uint8_t reg_idx, uint8_t *txdata, uint16_t len);
|
||||
eXC_RESULT xc_spi_read_bytes(uint8_t reg_idx, uint8_t *rxdata, uint16_t len);
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_spi_init(uint8_t reg_idx, SPI_InitCfg_t *init_cfg)
|
||||
{
|
||||
#if (USE_XIP == 0)
|
||||
if (SPI0_IDX == reg_idx) {
|
||||
cpr_rstctl_subrst_sw__ssi0_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__ssi0_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_ctlapbclken_grctl__ssi0_pclk_en__setf(ENABLE);
|
||||
|
||||
cpr_ssi0_mclk_ctl__ssi_mclk_div__setf(0);
|
||||
cpr_ssi0_mclk_ctl__ssi_mclk_en__setf(1);
|
||||
|
||||
cpr_ssi_ctrl__ssi0_protocol__setf(SSI_CTRL0_FRF_MOTOROLA);
|
||||
|
||||
}
|
||||
#endif
|
||||
if (SPI1_IDX == reg_idx) {
|
||||
|
||||
cpr_rstctl_subrst_sw__ssi1_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__ssi1_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_ssi1_mclk_ctl__ssi_mclk_div__setf(0);
|
||||
cpr_ssi1_mclk_ctl__ssi_mclk_en__setf(1);
|
||||
|
||||
cpr_ctlapbclken_grctl__ssi1_pclk_en__setf(ENABLE);
|
||||
|
||||
if (init_cfg->Mode == SPI_MODE_MASTER) {
|
||||
|
||||
cpr_ssi_ctrl__ssi1_master_en__setf(ENABLE);
|
||||
} else if (init_cfg->Mode == SPI_MODE_SLAVE) {
|
||||
|
||||
cpr_ssi_ctrl__ssi1_master_en__setf(DISABLE);
|
||||
}
|
||||
cpr_ssi_ctrl__ssi1_protocol__setf(SSI_CTRL0_FRF_MOTOROLA);
|
||||
} else if (SPI2_IDX == reg_idx) {
|
||||
|
||||
cpr_rstctl_subrst_sw__ssi2_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__ssi2_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_ssi1_mclk_ctl__ssi2_mclk_div__setf(0);
|
||||
cpr_ssi1_mclk_ctl__ssi2_mclk_en__setf(1);
|
||||
|
||||
cpr_ctlapbclken_grctl__ssi2_pclk_en__setf(ENABLE);
|
||||
|
||||
cpr_ssi_ctrl__ssi2_protocol__setf(SSI_CTRL0_FRF_MOTOROLA);
|
||||
}
|
||||
|
||||
spi_en_set(reg_idx, DISABLE);
|
||||
// sste is automatically set to 1 when spi slave is initialized.
|
||||
// therefor, manually clear this bit to 0 here.
|
||||
spi_ctrl0__ssi_sste__setf(reg_idx, DISABLE);
|
||||
spi_ctrl0__ssi_tmod__setf(reg_idx, init_cfg->Direction);
|
||||
spi_ctrl0__ssi_scpol__setf(reg_idx, init_cfg->CLKPolarity);
|
||||
spi_ctrl0__ssi_scpha__setf(reg_idx, init_cfg->CLKPhase);
|
||||
spi_ctrl0__ssi_dfs__setf(reg_idx, init_cfg->DataSize);
|
||||
|
||||
spi_ie_set(reg_idx, DISABLE);
|
||||
spi_se_set(reg_idx, ENABLE);
|
||||
spi_baud__ssi_sckdv__setf(reg_idx, init_cfg->BaudRatePrescaler);
|
||||
spi_txftl__ssi_tft__setf(reg_idx, SSI_TXFTL_FIFO_1);
|
||||
spi_rxftl__ssi_rft__setf(reg_idx, SSI_RXFTL_FIFO_1);
|
||||
}
|
||||
|
||||
static void xc_spi_enable(uint8_t reg_idx, uint8_t dfs)
|
||||
{
|
||||
spi_en__ssi_sen__setf(reg_idx, DISABLE);
|
||||
spi_dmas_set(reg_idx, DISABLE);
|
||||
spi_ctrl0__ssi_dfs__setf(reg_idx, dfs);
|
||||
spi_en__ssi_sen__setf(reg_idx, ENABLE);
|
||||
}
|
||||
|
||||
static void xc_spi_disable(uint8_t reg_idx) { spi_en__ssi_sen__setf(reg_idx, DISABLE); }
|
||||
|
||||
void xc_spi_rxftl_fifo_set(uint8_t reg_idx, uint8_t val)
|
||||
{
|
||||
spi_rxftl__ssi_rft__setf(reg_idx, val);
|
||||
}
|
||||
|
||||
void xc_spi_txftl_fifo_set(uint8_t reg_idx, uint8_t val)
|
||||
{
|
||||
spi_txftl__ssi_tft__setf(reg_idx, val);
|
||||
}
|
||||
|
||||
void xc_spi_enable_it(uint8_t reg_idx, uint8_t val) { spi_ie_set(reg_idx, val); }
|
||||
|
||||
void xc_spi_disable_it(uint8_t reg_idx, uint8_t val) { spi_ie_set(reg_idx, val); }
|
||||
|
||||
void xc_spi_flash_power_down(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t txbuff[2] = {0};
|
||||
|
||||
txbuff[1] = CMD_PWRDWN;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_8BIT);
|
||||
xc_spi_write_bytes(reg_idx, txbuff, sizeof(txbuff));
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
void xc_spi_flash_wake_up(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t txbuff[2] = {0};
|
||||
|
||||
txbuff[1] = CMD_RELEASE_PWRDWN;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_8BIT);
|
||||
xc_spi_write_bytes(reg_idx, txbuff, sizeof(txbuff));
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
static uint8_t xc_spi_flash_wait_busy(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t cmd[2] = {0};
|
||||
uint8_t sta[2] = {0xff, 0xff};
|
||||
|
||||
cmd[0] = CMD_READ_STATUS;
|
||||
cmd[1] = 0xff;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
xc_spi_read_bytes(reg_idx, sta, sizeof(sta));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
return (sta[1] & 0x01);
|
||||
}
|
||||
|
||||
static void xc_spi_flash_write_enable(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t txbuff[2] = {0};
|
||||
|
||||
txbuff[1] = CMD_WRITE_ENABLE;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_8BIT);
|
||||
xc_spi_write_bytes(reg_idx, txbuff, sizeof(txbuff));
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
eXC_RESULT xc_spi_flash_erase_sector(uint8_t reg_idx, uint32_t Dst_Addr)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_flash_write_enable(reg_idx);
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
cmd[0] = CMD_SECTOR_ERASE;
|
||||
cmd[1] = Dst_Addr >> 16;
|
||||
cmd[2] = Dst_Addr >> 8;
|
||||
cmd[3] = Dst_Addr;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
#if (USE_INTEGRATED_FlASH == USE_PUYA_FlASH)
|
||||
void xc_spi_flash_erase_page(uint8_t reg_idx, uint32_t Dst_Addr)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_flash_write_enable(reg_idx);
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
cmd[0] = CMD_PAGE_ERASE;
|
||||
cmd[1] = Dst_Addr >> 16;
|
||||
cmd[2] = Dst_Addr >> 8;
|
||||
cmd[3] = Dst_Addr;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
void xc_spi_flash_write_page(uint8_t reg_idx, uint32_t WriteAddr, uint8_t *pBuffer)
|
||||
{
|
||||
uint32_t addr = WriteAddr;
|
||||
uint8_t cmd[16 + 4] = {0};
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_flash_write_enable(reg_idx);
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
cmd[0] = CMD_PAGE_PROGRAM;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
memcpy(&cmd[4], pBuffer + i * 16, 16);
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
addr += 16;
|
||||
}
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
void xc_spi_flash_read_page(uint8_t reg_idx, uint32_t ReadAddr, uint8_t *pBuffer)
|
||||
{
|
||||
uint8_t cmd[16 + 4] = {0};
|
||||
uint8_t mid[16 + 4] = {0};
|
||||
uint16_t rx_idx = 0;
|
||||
uint32_t addr = ReadAddr;
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
cmd[0] = CMD_READ_DATA;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
xc_spi_read_bytes(reg_idx, mid, sizeof(cmd));
|
||||
|
||||
memcpy(&pBuffer[rx_idx], mid + 4, 16);
|
||||
addr += 16;
|
||||
rx_idx += 16;
|
||||
}
|
||||
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_flash_write(uint8_t reg_idx, uint32_t addr, uint8_t *buff,
|
||||
uint16_t size)
|
||||
{
|
||||
eXC_RESULT ret = XR_OK;
|
||||
uint32_t cur_addr = addr;
|
||||
uint32_t end_addr = addr + size;
|
||||
uint16_t wt_len = 0;
|
||||
// The current page number occupied by this data storage
|
||||
// The position occupied by this address on the current page
|
||||
uint32_t cur_start_psr = 0;
|
||||
uint16_t cur_size;
|
||||
|
||||
#ifndef GD_FlASH_INTEGRATION
|
||||
uint16_t cur_page_num = 0;
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE];
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
cur_page_num = CUR_PAGE_NUM(cur_addr);
|
||||
cur_start_psr = CUR_START_PSR(cur_addr);
|
||||
|
||||
xc_spi_flash_read_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE, temp_buff);
|
||||
xc_spi_flash_erase_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE);
|
||||
|
||||
if (cur_start_psr) {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE - cur_start_psr, size - wt_len);
|
||||
} else {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE, size - wt_len);
|
||||
}
|
||||
memcpy(&temp_buff[cur_start_psr], buff + wt_len, cur_size);
|
||||
wt_len += cur_size;
|
||||
cur_addr += cur_size;
|
||||
|
||||
xc_spi_flash_write_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE, temp_buff);
|
||||
}
|
||||
#else
|
||||
uint16_t cur_sector_num = 0;
|
||||
uint8_t temp_buff[FLASH_SECTOR_SIZE] = {0};
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
cur_sector_num = CUR_SECTOR_NUM(cur_addr);
|
||||
cur_start_psr = CUR_START_PSR(cur_addr);
|
||||
|
||||
for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
|
||||
xc_spi_flash_read_page(reg_idx, CUR_SECTOR_PAGE_ADDR(cur_sector_num, i), temp_buff+i*FLASH_PAGE_SIZE);
|
||||
}
|
||||
|
||||
xc_spi_flash_erase_sector(reg_idx, cur_sector_num * FLASH_SECTOR_SIZE);
|
||||
|
||||
if (cur_start_psr) {
|
||||
cur_size = MIN(FLASH_SECTOR_SIZE - cur_start_psr, size - wt_len);
|
||||
} else {
|
||||
cur_size = MIN(FLASH_SECTOR_SIZE, size - wt_len);
|
||||
}
|
||||
|
||||
memcpy(&temp_buff[cur_start_psr], buff + wt_len, cur_size);
|
||||
wt_len += cur_size;
|
||||
cur_addr += cur_size;
|
||||
|
||||
for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
|
||||
xc_spi_flash_write_page(reg_idx, CUR_SECTOR_PAGE_ADDR(cur_sector_num, i), temp_buff+i*FLASH_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_flash_read(uint8_t reg_idx, uint32_t addr, uint8_t *buff,
|
||||
uint16_t size)
|
||||
{
|
||||
eXC_RESULT ret = XR_OK;
|
||||
uint32_t cur_addr = addr;
|
||||
uint32_t end_addr = addr + size;
|
||||
uint16_t rd_len = 0;
|
||||
uint16_t cur_page_num = 0;
|
||||
uint32_t cur_start_psr = 0;
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = {0};
|
||||
uint16_t cur_size;
|
||||
|
||||
while (cur_addr != end_addr) {
|
||||
cur_page_num = CUR_PAGE_NUM(cur_addr);
|
||||
cur_start_psr = CUR_START_PSR(cur_addr);
|
||||
xc_spi_flash_read_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE, temp_buff);
|
||||
if (cur_start_psr) {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE - cur_start_psr, size - rd_len);
|
||||
} else {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE, size - rd_len);
|
||||
}
|
||||
|
||||
memcpy(buff + rd_len, &temp_buff[cur_start_psr], cur_size);
|
||||
cur_addr += cur_size;
|
||||
rd_len += cur_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void xc_spi_flash_read_128bit_uid(uint8_t reg_idx, uint8_t *buff)
|
||||
{
|
||||
while (xc_spi_flash_wait_busy(reg_idx)) {
|
||||
DEBUG("line=%d,status=%d\n", __LINE__, xc_spi_flash_wait_busy(reg_idx));
|
||||
};
|
||||
|
||||
uint8_t cmd[21] = {0};
|
||||
uint8_t id[21] = {0};
|
||||
|
||||
cmd[0] = CMD_RUID;
|
||||
cmd[1] = 0x00;
|
||||
cmd[2] = 0x00;
|
||||
cmd[3] = 0x00;
|
||||
cmd[4] = 0x00;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
xc_spi_read_bytes(reg_idx, id, sizeof(id));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
memcpy(buff, &id[5], 16);
|
||||
}
|
||||
|
||||
eXC_RESULT xc_spi_flash_rdid(uint8_t reg_idx, uint8_t *buff)
|
||||
{
|
||||
while (xc_spi_flash_wait_busy(reg_idx)) {
|
||||
DEBUG("line=%d,status=%d\n", __LINE__, xc_spi_flash_wait_busy(reg_idx));
|
||||
};
|
||||
|
||||
uint8_t cmd[4] = {0};
|
||||
uint8_t id[4] = {0};
|
||||
|
||||
cmd[0] = CMD_RDID;
|
||||
cmd[1] = 0xff;
|
||||
cmd[2] = 0xff;
|
||||
cmd[3] = 0xff;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
xc_spi_read_bytes(reg_idx, id, sizeof(id));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
memcpy(buff, &id[1], 3);
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------- SPI1 Master & Slave API
|
||||
* ---------------------------------------*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only Master & Slave
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
static void xc_spi_datasize_set(uint8_t reg_idx, uint8_t dfs)
|
||||
{
|
||||
|
||||
spi_en_set(reg_idx, DISABLE);
|
||||
spi_ctrl0__ssi_dfs__setf(reg_idx, dfs);
|
||||
spi_en_set(reg_idx, ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only applicable Master & Slave communication
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_write_bytes(uint8_t reg_idx, uint8_t *txdata, uint16_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return XR_ERROR;
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 2;
|
||||
uint16_t cnt = len / 2;
|
||||
uint16_t mid_data[128 + 1] = {0};
|
||||
uint16_t i = 0;
|
||||
|
||||
while (spi_sts__ssi_tfe__getf(reg_idx) == RESET) {
|
||||
i++;
|
||||
if (i >= SPI_WAIT_TIMEOUT) {
|
||||
DEBUG("func=%s,line=%d,timeout\n", __func__, __LINE__);
|
||||
return XR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt != 0) {
|
||||
for (n = 0; n < cnt; n++) {
|
||||
mid_data[n] = ((txdata[n * 2] << 8) | txdata[n * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (remain != 0) {
|
||||
for (n = 0; n < remain; n++) {
|
||||
mid_data[cnt] |= (txdata[cnt * 2 + n] << (16 - 8 * n));
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt != 0) {
|
||||
if (remain != 0)
|
||||
cnt = cnt + 1;
|
||||
for (n = 0; n < cnt; n++)
|
||||
spi_data_set(reg_idx, mid_data[n]);
|
||||
} else {
|
||||
spi_data_set(reg_idx, mid_data[0]);
|
||||
}
|
||||
|
||||
while ((spi_sts__ssi_rfne__getf(reg_idx) == RESET) ||
|
||||
(spi_sts__ssi_tfe__getf(reg_idx) == RESET)) {
|
||||
i++;
|
||||
if (i >= SPI_WAIT_TIMEOUT) {
|
||||
// DEBUG("func=%s,line=%d,timeout\n", __func__, __LINE__);
|
||||
return XR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only applicable Master & Slave communication
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_read_bytes(uint8_t reg_idx, uint8_t *rxdata, uint16_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return XR_ERROR;
|
||||
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 2;
|
||||
uint16_t cnt = len / 2;
|
||||
uint16_t mid_data = 0;
|
||||
|
||||
if (cnt != 0) {
|
||||
for (n = 0; n < cnt; n++) {
|
||||
|
||||
mid_data = spi_data_get(reg_idx);
|
||||
rxdata[n * 2] = mid_data >> 8;
|
||||
rxdata[n * 2 + 1] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
if (remain != 0) {
|
||||
|
||||
mid_data = spi_data_get(reg_idx);
|
||||
for (n = 0; n < remain; n++) {
|
||||
rxdata[cnt * 2 + n] = mid_data >> 8;
|
||||
rxdata[cnt * 2 + 1 + n] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only applicable Master & Slave communication
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_spi_write_and_read_data(uint8_t reg_idx, uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size)
|
||||
{
|
||||
if (w_size != (spi_rxftl_get(reg_idx) + 1) * 2)
|
||||
return;
|
||||
xc_spi_datasize_set(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, w_data, w_size);
|
||||
|
||||
while (!(spi_is_get(reg_idx) == SSI_IS_RXFIS_SET))
|
||||
;
|
||||
xc_spi_read_bytes(reg_idx, r_data, r_size);
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
#endif //(SPI_ON)
|
||||
@@ -0,0 +1,174 @@
|
||||
/*!
|
||||
* \file xc_drv_aotimer.h
|
||||
*
|
||||
* \brief The header of xc_drv_aotimer.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_SPI_H_
|
||||
#define _XC_DRV_SPI_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
#include "xc_drv_flash.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define SPI_WAIT_TIMEOUT 65535
|
||||
|
||||
// temporary macros -- alex revised
|
||||
|
||||
#define SSI_CTRL0_FRF_MOTOROLA (0x1UL)
|
||||
#define SSI_CTRL0_FRF_TI (0x0UL)
|
||||
|
||||
/* SPI_Mode SPI Mode */
|
||||
#define SPI_MODE_SLAVE (0x00000000U)
|
||||
#define SPI_MODE_MASTER (0x00000001U)
|
||||
|
||||
/* SPI_data_size */
|
||||
#define SSI_CTRL0_DFS_LEN_16BIT ((uint16_t)0x0fUL)
|
||||
#define SSI_CTRL0_DFS_LEN_8BIT ((uint16_t)0x07UL)
|
||||
|
||||
/* SPI_data_direction */
|
||||
#define SSI_CTRL0_TMOD_WR (0x0UL)
|
||||
#define SSI_CTRL0_TMOD_W (0x1UL)
|
||||
#define SSI_CTRL0_TMOD_R (0x2UL)
|
||||
|
||||
/* SPI_BaudRate_Prescaler */
|
||||
#define SSI_BAUD_DIV_2 (0x02UL)
|
||||
#define SSI_BAUD_DIV_4 (0x04UL)
|
||||
#define SSI_BAUD_DIV_6 (0x06UL)
|
||||
#define SSI_BAUD_DIV_8 (0x08UL)
|
||||
#define SSI_BAUD_DIV_10 (0x0aUL)
|
||||
#define SSI_BAUD_DIV_12 (0x0cUL)
|
||||
|
||||
/* SPI_Clock_Polarity */
|
||||
#define SSI_CTRL0_SCPOL_HIGH (0x1UL)
|
||||
#define SSI_CTRL0_SCPOL_LOW (0x0UL)
|
||||
|
||||
/* SPI_Clock_Phase */
|
||||
#define SSI_CTRL0_SCPHA_LEAD (0x0UL)
|
||||
#define SSI_CTRL0_SCPHA_TRAIL (0x1UL)
|
||||
|
||||
/* SPI_MSB_transmission */
|
||||
#define SPI_FirstBit_MSB ((uint16_t)0x0000)
|
||||
|
||||
#define SSI_TXFTL_FIFO_0 (0x00UL)
|
||||
#define SSI_TXFTL_FIFO_1 (0x01UL)
|
||||
#define SSI_TXFTL_FIFO_2 (0x02UL)
|
||||
#define SSI_TXFTL_FIFO_3 (0x03UL)
|
||||
#define SSI_TXFTL_FIFO_4 (0x04UL)
|
||||
#define SSI_TXFTL_FIFO_5 (0x05UL)
|
||||
#define SSI_TXFTL_FIFO_6 (0x06UL)
|
||||
#define SSI_TXFTL_FIFO_7 (0x07UL)
|
||||
|
||||
#define SSI_RXFTL_FIFO_0 (0x00UL)
|
||||
#define SSI_RXFTL_FIFO_1 (0x01UL)
|
||||
#define SSI_RXFTL_FIFO_2 (0x02UL)
|
||||
#define SSI_RXFTL_FIFO_3 (0x03UL)
|
||||
#define SSI_RXFTL_FIFO_4 (0x04UL)
|
||||
#define SSI_RXFTL_FIFO_5 (0x05UL)
|
||||
#define SSI_RXFTL_FIFO_6 (0x06UL)
|
||||
#define SSI_RXFTL_FIFO_7 (0x07UL)
|
||||
|
||||
#define SSI_IE_TXEIE_ENABLE (0x1UL << SSI_TXEIE_POS)
|
||||
#define SSI_IE_TXEIE_DISABLE (0x0UL << SSI_TXEIE_POS)
|
||||
|
||||
#define SSI_IE_TXOIE_ENABLE (0x1UL << SSI_TXOIE_POS)
|
||||
#define SSI_IE_TXOIE_DISABLE (0x0UL << SSI_TXOIE_POS)
|
||||
|
||||
#define SSI_IE_RXUIE_ENABLE (0x1UL << SSI_RXUIE_POS)
|
||||
#define SSI_IE_RXUIE_DISABLE (0x0UL << SSI_RXUIE_POS)
|
||||
|
||||
#define SSI_IE_RXOIE_ENABLE (0x1UL << SSI_RXOIE_POS)
|
||||
#define SSI_IE_RXOIE_DISABLE (0x0UL << SSI_RXOIE_POS)
|
||||
|
||||
#define SSI_IE_RXFIE_ENABLE (0x1UL << SSI_RXFIE_POS)
|
||||
#define SSI_IE_RXFIE_DISABLE (0x0UL << SSI_RXFIE_POS)
|
||||
|
||||
#define SSI_IS_TXEIS_SET (0x1UL << SSI_TXEIS_POS)
|
||||
#define SSI_IS_TXEIS_RESET (0x0UL << SSI_TXEIS_POS)
|
||||
|
||||
#define SSI_IS_TXOIS_SET (0x1UL << SSI_TXOIS_POS)
|
||||
#define SSI_IS_TXOIS_RESET (0x0UL << SSI_TXOIS_POS)
|
||||
|
||||
#define SSI_IS_RXUIS_SET (0x1UL << SSI_RXUIS_POS)
|
||||
#define SSI_IS_RXUIS_RESET (0x0UL << SSI_RXUIS_POS)
|
||||
|
||||
#define SSI_IS_RXOIS_SET (0x1UL << SSI_RXOIS_POS)
|
||||
#define SSI_IS_RXOIS_RESET (0x0UL << SSI_RXOIS_POS)
|
||||
|
||||
#define SSI_IS_RXFIS_SET (0x1UL << SSI_RXFIS_POS)
|
||||
#define SSI_IS_RXFIS_RESET (0x0UL << SSI_RXFIS_POS)
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Mode;
|
||||
uint32_t Direction;
|
||||
uint32_t DataSize;
|
||||
uint32_t CLKPolarity;
|
||||
uint32_t CLKPhase;
|
||||
uint32_t NSS;
|
||||
uint32_t BaudRatePrescaler;
|
||||
uint32_t FirstBit;
|
||||
} SPI_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef void (*timer_handler_callback)(void *context);
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_spi_init(uint8_t reg_idx, SPI_InitCfg_t *init_cfg);
|
||||
void xc_spi_rxftl_fifo_set(uint8_t reg_idx, uint8_t val);
|
||||
void xc_spi_txftl_fifo_set(uint8_t reg_idx, uint8_t val);
|
||||
|
||||
void xc_spi_enable_it(uint8_t reg_idx, uint8_t val);
|
||||
void xc_spi_disable_it(uint8_t reg_idx, uint8_t val);
|
||||
|
||||
void xc_spi_flash_power_down(uint8_t reg_idx);
|
||||
void xc_spi_flash_wake_up(uint8_t reg_idx);
|
||||
uint8_t xc_spi_flash_wait_busy(uint8_t reg_idx);
|
||||
eXC_RESULT xc_spi_flash_erase_sector(uint8_t reg_idx, uint32_t Dst_Addr);
|
||||
void xc_spi_flash_erase_page(uint8_t reg_idx, uint32_t Dst_Addr);
|
||||
void xc_spi_flash_write_page(uint8_t reg_idx, uint32_t WriteAddr,
|
||||
uint8_t *pBuffer);
|
||||
void xc_spi_flash_read_page(uint8_t reg_idx, uint32_t ReadAddr, uint8_t *pBuffer);
|
||||
eXC_RESULT xc_spi_flash_write(uint8_t reg_idx, uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
eXC_RESULT xc_spi_flash_read(uint8_t reg_idx, uint32_t addr, uint8_t *buff,
|
||||
uint16_t size);
|
||||
void xc_spi_flash_read_128bit_uid(uint8_t reg_idx, uint8_t *buff);
|
||||
eXC_RESULT xc_spi_flash_rdid(uint8_t reg_idx, uint8_t *buff);
|
||||
void xc_spi_write_and_read_data(uint8_t reg_idx, uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size);
|
||||
|
||||
#endif // _XC_DRV_AOTIMER_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
/*!
|
||||
* \file xc_drv_spi_dma.h
|
||||
*
|
||||
* \brief The header of xc_drv_spi_dma.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef __XC_DRV_SPI_DMA_H_
|
||||
#define __XC_DRV_SPI_DMA_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "xc6xxx.h"
|
||||
#include "xc_drv_flash.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define SPI1_BASE_OFFSET 0x1000
|
||||
#define SPI2_BASE_OFFSET 0x1800
|
||||
|
||||
#define SSIx_DATA_OFFSET 0x60
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_spi_dma_deinit(uint8_t spi_idx);
|
||||
|
||||
void xc_spi_dma_read_data(uint8_t spi_idx, uint8_t *data, uint16_t size);
|
||||
void xc_spi_dma_write_data(uint8_t spi_idx, uint8_t *data, uint16_t size);
|
||||
void xc_spi_dma_write_and_read_data(uint8_t spi_idx,
|
||||
uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size);
|
||||
void xc_spi_dma_read_and_write_data(uint8_t spi_idx,
|
||||
uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size);
|
||||
|
||||
void xc_spi_dma_flash_power_down(uint8_t spi_idx);
|
||||
void xc_spi_dma_flash_wakeup(uint8_t spi_idx);
|
||||
void xc_spi_dma_flash_wait_busy(uint8_t spi_idx);
|
||||
void xc_spi_dma_flash_erase_sector(uint8_t spi_idx, uint32_t Dst_Addr);
|
||||
void xc_spi_dma_flash_erase_page(uint8_t spi_idx, uint32_t Dst_Addr);
|
||||
void xc_spi_dma_flash_write_page(uint8_t spi_idx, uint32_t WriteAddr, uint8_t *data, uint16_t size);
|
||||
void xc_spi_dma_flash_read_page(uint8_t spi_idx, uint32_t ReadAddr, uint8_t *data, uint16_t size);
|
||||
void xc_spi_dma_flash_rdid(uint8_t spi_idx, uint8_t *rdid);
|
||||
void xc_spi_dma_flash_ruid(uint8_t spi_idx, uint8_t *ruid);
|
||||
|
||||
eXC_RESULT xc_spi_dma_flash_write(uint8_t spi_idx, uint32_t addr, uint8_t *buff, uint16_t size);
|
||||
eXC_RESULT xc_spi_dma_flash_read(uint8_t spi_idx, uint32_t addr, uint8_t *buff, uint16_t size);
|
||||
|
||||
#endif /* __XC_DRV_SPI_DMA_H_ */
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/*!
|
||||
* \file xc6xxx_sw_i2c.c
|
||||
*
|
||||
* \brief Target xc software i2c implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_sw_i2c.h"
|
||||
#if (SW_I2C_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define AT24C01 128
|
||||
#define AT24C02 256
|
||||
#define AT24C04 512
|
||||
#define AT24C08 1024
|
||||
#define AT24C16 2048
|
||||
#define AT24C32 4096
|
||||
#define AT24C64 8192
|
||||
#define AT24C128 16384
|
||||
#define AT24C256 32768
|
||||
|
||||
#define EE_PAGE_ADDR_UNIT 256
|
||||
#define EE_PAGE_BYTE 8
|
||||
#define EE_SIZE AT24C08
|
||||
#define I2C_SLAVE_ADDR (0x50)
|
||||
|
||||
#define AT24XX_SR1_ADDR (0x50)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void i2c_software_init(void)
|
||||
{
|
||||
GPIO_InitCfg_t gpio_cfg = {0};
|
||||
|
||||
gpio_cfg.FunSel = GPIO_Dx;
|
||||
gpio_cfg.Dir = GPIO_DIR_OUTPUT;
|
||||
gpio_cfg.Pull = GPIO_PULLDOWN;
|
||||
gpio_cfg.Int = NOT_INT;
|
||||
|
||||
gpio_cfg.Pin = SCL_PIN;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
|
||||
gpio_cfg.Pin = SDA_PIN;
|
||||
xc_gpio_init(&gpio_cfg);
|
||||
}
|
||||
|
||||
void i2c_start(void)
|
||||
{
|
||||
SDA_OUT_HIGH(SDA_PIN);
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
delay_us(2);
|
||||
SDA_OUT_LOW(SDA_PIN); // START:when CLK is high,DATA change form high to low
|
||||
delay_us(2);
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
}
|
||||
|
||||
void i2c_stop(void)
|
||||
{
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
SDA_OUT_LOW(SDA_PIN); // STOP:when CLK is high DATA change form low to high
|
||||
delay_us(2);
|
||||
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
delay_us(2);
|
||||
SDA_OUT_HIGH(SDA_PIN);
|
||||
delay_us(2);
|
||||
}
|
||||
|
||||
uint8_t i2c_wait_ack(void)
|
||||
{
|
||||
uint8_t ucErrTime = 0;
|
||||
|
||||
SDA_INPUT(SDA_PIN, GPIO_PULLUP);
|
||||
delay_us(7);
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
delay_us(7);
|
||||
|
||||
while (SDA_INPUT_VAL(SDA_PIN)) {
|
||||
ucErrTime++;
|
||||
if (ucErrTime > 250) {
|
||||
i2c_stop();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
delay_us(2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_ack(void)
|
||||
{
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
SDA_OUT_LOW(SDA_PIN);
|
||||
delay_us(2);
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
delay_us(2);
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
}
|
||||
|
||||
void i2c_nack(void)
|
||||
{
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
SDA_OUT_HIGH(SDA_PIN);
|
||||
delay_us(2);
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
delay_us(2);
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
}
|
||||
|
||||
void i2c_send_byte(uint8_t txd)
|
||||
{
|
||||
uint8_t t;
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
for (t = 0; t < 8; t++) {
|
||||
if ((txd & 0x80) >> 7) {
|
||||
SDA_OUT_HIGH(SDA_PIN);
|
||||
} else {
|
||||
SDA_OUT_LOW(SDA_PIN);
|
||||
}
|
||||
txd <<= 1;
|
||||
delay_us(2);
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
delay_us(2);
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
delay_us(2);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t i2c_read_byte(unsigned char ack)
|
||||
{
|
||||
unsigned char i, receive = 0;
|
||||
SDA_INPUT(SDA_PIN, GPIO_PULLUP);
|
||||
for (i = 0; i < 8; i++) {
|
||||
SCL_OUT_LOW(SCL_PIN);
|
||||
delay_us(5);
|
||||
SCL_OUT_HIGH(SCL_PIN);
|
||||
receive <<= 1;
|
||||
if (SDA_INPUT_VAL(SDA_PIN)) {
|
||||
receive++;
|
||||
}
|
||||
delay_us(5);
|
||||
}
|
||||
if (!ack)
|
||||
i2c_nack();
|
||||
else
|
||||
i2c_ack();
|
||||
return receive;
|
||||
}
|
||||
|
||||
uint8_t at24cxx_read_byte(uint16_t addr)
|
||||
{
|
||||
uint8_t temp = 0;
|
||||
i2c_start();
|
||||
|
||||
if (EE_SIZE > AT24C16) {
|
||||
i2c_send_byte(0XA0);
|
||||
i2c_wait_ack();
|
||||
i2c_send_byte(addr >> 8);
|
||||
i2c_wait_ack();
|
||||
} else
|
||||
i2c_send_byte(0XA0 + ((addr / 256) << 1));
|
||||
|
||||
i2c_wait_ack();
|
||||
i2c_send_byte(addr % 256);
|
||||
i2c_wait_ack();
|
||||
i2c_start();
|
||||
i2c_send_byte(0XA0 + ((addr / 256) << 1) + 1);
|
||||
i2c_wait_ack();
|
||||
temp = i2c_read_byte(0);
|
||||
i2c_stop();
|
||||
return temp;
|
||||
}
|
||||
|
||||
void at24cxx_write_byte(uint16_t addr, uint8_t data)
|
||||
{
|
||||
i2c_start();
|
||||
if (EE_SIZE > AT24C16) {
|
||||
i2c_send_byte(0XA0);
|
||||
i2c_wait_ack();
|
||||
i2c_send_byte(addr >> 8);
|
||||
} else {
|
||||
i2c_send_byte(0XA0 + ((addr / 256) << 1));
|
||||
}
|
||||
i2c_wait_ack();
|
||||
i2c_send_byte(addr % 256);
|
||||
i2c_wait_ack();
|
||||
i2c_send_byte(data);
|
||||
i2c_wait_ack();
|
||||
i2c_stop();
|
||||
delay_ms(10);
|
||||
}
|
||||
|
||||
void at24cxx_write_nbytes(uint16_t addr, uint8_t *buff, uint32_t num)
|
||||
{
|
||||
while (num--) {
|
||||
at24cxx_write_byte(addr, *buff);
|
||||
addr++;
|
||||
buff++;
|
||||
}
|
||||
}
|
||||
|
||||
void at24cxx_read_nbytes(uint16_t addr, uint8_t *buff, uint32_t num)
|
||||
{
|
||||
while (num) {
|
||||
*buff++ = at24cxx_read_byte(addr++);
|
||||
num--;
|
||||
}
|
||||
}
|
||||
#endif //(SW_I2C_ON)
|
||||
@@ -0,0 +1,101 @@
|
||||
/*!
|
||||
* \file xc6xxx_sw_i2c.h
|
||||
*
|
||||
* \brief The header of xc6xxx_sw_i2c.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC_DRV_SW_I2C_H_
|
||||
#define __XC_DRV_SW_I2C_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define SDA_OUT_HIGH(pin) \
|
||||
{ \
|
||||
xc_gpio_direction_config(pin, GPIO_DIR_OUTPUT); \
|
||||
xc_gpio_write_pin(pin, GPIO_PIN_SET); \
|
||||
}
|
||||
#define SDA_OUT_LOW(pin) \
|
||||
{ \
|
||||
xc_gpio_direction_config(pin, GPIO_DIR_OUTPUT); \
|
||||
xc_gpio_write_pin(pin, GPIO_PIN_RESET); \
|
||||
}
|
||||
|
||||
#define SCL_OUT_HIGH(pin) \
|
||||
{ \
|
||||
xc_gpio_direction_config(pin, GPIO_DIR_OUTPUT); \
|
||||
xc_gpio_write_pin(pin, GPIO_PIN_SET); \
|
||||
}
|
||||
|
||||
#define SCL_OUT_LOW(pin) \
|
||||
{ \
|
||||
xc_gpio_direction_config(pin, GPIO_DIR_OUTPUT); \
|
||||
xc_gpio_write_pin(pin, GPIO_PIN_RESET); \
|
||||
}
|
||||
|
||||
#define SDA_INPUT(pin, pull) \
|
||||
{ \
|
||||
xc_gpio_direction_config(pin, GPIO_DIR_INPUT); \
|
||||
xc_gpio_pull_config(pin, pull); \
|
||||
}
|
||||
#define SDA_INPUT_VAL(pin) xc_gpio_read_pin(pin)
|
||||
|
||||
#define SCL_PIN 2
|
||||
#define SDA_PIN 3
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void i2c_start(void);
|
||||
void i2c_stop(void);
|
||||
void i2c_send_byte(uint8_t txd);
|
||||
void i2c_ack(void);
|
||||
uint8_t i2c_read_byte(unsigned char ack);
|
||||
void i2c_nack(void);
|
||||
uint8_t i2c_wait_ack(void);
|
||||
|
||||
void i2c_software_init(void);
|
||||
uint8_t at24cxx_read_byte(uint16_t addr);
|
||||
void at24cxx_write_byte(uint16_t addr, uint8_t data);
|
||||
|
||||
void at24cxx_write_nbytes(uint16_t addr, uint8_t *buff, uint32_t num);
|
||||
void at24cxx_read_nbytes(uint16_t addr, uint8_t *buff, uint32_t num);
|
||||
|
||||
#endif /* __XC60xx_SW_I2C_H_ */
|
||||
@@ -0,0 +1,68 @@
|
||||
/*!
|
||||
* \file xc_drv_systick.c
|
||||
*
|
||||
* \brief Target xinchip systick driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_systick.h"
|
||||
#include "xc_drv_clock.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void SysTick_Handler(void) { systick_callback(); }
|
||||
|
||||
void delay_us(uint32_t nus)
|
||||
{
|
||||
if (nus == 0)
|
||||
return;
|
||||
|
||||
uint32_t unit = xc_systick_unit_get();
|
||||
|
||||
uint32_t temp;
|
||||
|
||||
SysTick->CTRL = 0x00; // 关闭计数器
|
||||
SysTick->LOAD = unit * nus - unit + 1;
|
||||
|
||||
SysTick->VAL = 0;
|
||||
SysTick->CTRL = 0x05;
|
||||
|
||||
do {
|
||||
temp = SysTick->CTRL; // 读取当前倒计数值
|
||||
} while ((temp & 0x01) && (!(temp & (1 << 16))));
|
||||
}
|
||||
|
||||
void delay_ms(uint32_t nms)
|
||||
{
|
||||
if (nms == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
delay_us(1000);
|
||||
} while (--nms);
|
||||
}
|
||||
|
||||
__WEAK void systick_callback(void) {}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* @Descripttion:
|
||||
* @version:
|
||||
* @Author: sueRimn
|
||||
* @Date: 2024-05-10 09:47:53
|
||||
* @LastEditors: sueRimn
|
||||
* @LastEditTime: 2024-05-10 09:50:47
|
||||
*/
|
||||
/*!
|
||||
* \file xc_drv_systick.h
|
||||
*
|
||||
* \brief The header of xc_drv_systick.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_SYSTICK_H_
|
||||
#define _XC_DRV_SYSTICK_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void delay_us(uint32_t nus);
|
||||
void delay_ms(uint32_t nms);
|
||||
|
||||
void systick_callback(void);
|
||||
|
||||
#endif /* _XC_DRV_SYSTICK_H_ */
|
||||
@@ -0,0 +1,200 @@
|
||||
/*!
|
||||
* \file xc_drv_timer.c
|
||||
*
|
||||
* \brief Target xc timer driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_timer.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
timer_handler_callback timer_n_callback[4] = {timer0_callback, timer1_callback,
|
||||
timer2_callback, timer3_callback};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_timer_init(uint8_t reg_idx, Timer_InitCfg_t *init_cfg)
|
||||
{
|
||||
if (TIMER0_IDX == reg_idx) {
|
||||
cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);
|
||||
cpr_timer0_clk_ctl__timer_clksel__setf(
|
||||
(uint8_t)init_cfg->timer_src_clk);
|
||||
cpr_timer0_clk_ctl__timer_clk0_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
cpr_timer0_clk_ctl__timer_clk1_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
} else if (TIMER1_IDX == reg_idx) {
|
||||
cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);
|
||||
cpr_timer1_clk_ctl__timer_clksel__setf(
|
||||
(uint8_t)init_cfg->timer_src_clk);
|
||||
cpr_timer1_clk_ctl__timer_clk0_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
cpr_timer1_clk_ctl__timer_clk1_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
} else if (TIMER2_IDX == reg_idx) {
|
||||
cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);
|
||||
cpr_timer2_clk_ctl__timer_clksel__setf(
|
||||
(uint8_t)init_cfg->timer_src_clk);
|
||||
cpr_timer2_clk_ctl__timer_clk0_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
cpr_timer2_clk_ctl__timer_clk1_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
} else if (TIMER3_IDX == reg_idx) {
|
||||
cpr_ctlapbclken_grctl__timer_pclk_en__setf(ENABLE);
|
||||
cpr_timer3_clk_ctl__timer_clksel__setf(
|
||||
(uint8_t)init_cfg->timer_src_clk);
|
||||
cpr_timer3_clk_ctl__timer_clk0_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
cpr_timer3_clk_ctl__timer_clk1_div__setf(
|
||||
(uint8_t)init_cfg->timer_div_clk);
|
||||
}
|
||||
cpr_lp_ctl__timer_sysclk_sel__setf(ENABLE);
|
||||
|
||||
timer_tcr__tes__setf(reg_idx, TIMER_TCR_TES_DISABLE);
|
||||
timer_tcr__tms__setf(reg_idx, (uint8_t)init_cfg->timer_mode);
|
||||
}
|
||||
|
||||
static uint32_t xc_timer_us_to_ticks(uint8_t reg_idx, uint32_t us)
|
||||
{
|
||||
uint32_t ticks;
|
||||
uint8_t src_clk;
|
||||
|
||||
if (TIMER0_IDX == reg_idx) {
|
||||
src_clk = cpr_timer0_clk_ctl__timer_clksel__getf();
|
||||
|
||||
if (src_clk == TIMER_CLK_SRC_32M_DIV) {
|
||||
ticks = TIMER_CLKSRC_32M_DIV_CAL(
|
||||
us, cpr_timer0_clk_ctl__timer_clk0_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K_DIV) {
|
||||
ticks = TIMER_CLKSRC_32K_DIV_CAL(
|
||||
us, cpr_timer0_clk_ctl__timer_clk1_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K) {
|
||||
ticks = TIMER_CLKSRC_32K_CAL(us);
|
||||
}
|
||||
} else if (TIMER1_IDX == reg_idx) {
|
||||
src_clk = cpr_timer1_clk_ctl__timer_clksel__getf();
|
||||
|
||||
if (src_clk == TIMER_CLK_SRC_32M_DIV) {
|
||||
ticks = TIMER_CLKSRC_32M_DIV_CAL(
|
||||
us, cpr_timer1_clk_ctl__timer_clk0_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K_DIV) {
|
||||
ticks = TIMER_CLKSRC_32K_DIV_CAL(
|
||||
us, cpr_timer1_clk_ctl__timer_clk1_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K) {
|
||||
ticks = TIMER_CLKSRC_32K_CAL(us);
|
||||
}
|
||||
} else if (TIMER2_IDX == reg_idx) {
|
||||
src_clk = cpr_timer2_clk_ctl__timer_clksel__getf();
|
||||
|
||||
if (src_clk == TIMER_CLK_SRC_32M_DIV) {
|
||||
ticks = TIMER_CLKSRC_32M_DIV_CAL(
|
||||
us, cpr_timer2_clk_ctl__timer_clk0_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K_DIV) {
|
||||
ticks = TIMER_CLKSRC_32K_DIV_CAL(
|
||||
us, cpr_timer2_clk_ctl__timer_clk1_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K) {
|
||||
ticks = TIMER_CLKSRC_32K_CAL(us);
|
||||
}
|
||||
} else if (TIMER3_IDX == reg_idx) {
|
||||
src_clk = cpr_timer3_clk_ctl__timer_clksel__getf();
|
||||
|
||||
if (src_clk == TIMER_CLK_SRC_32M_DIV) {
|
||||
ticks = TIMER_CLKSRC_32M_DIV_CAL(
|
||||
us, cpr_timer3_clk_ctl__timer_clk0_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K_DIV) {
|
||||
ticks = TIMER_CLKSRC_32K_DIV_CAL(
|
||||
us, cpr_timer3_clk_ctl__timer_clk1_div__getf());
|
||||
} else if (src_clk == TIMER_CLK_SRC_32K) {
|
||||
ticks = TIMER_CLKSRC_32K_CAL(us);
|
||||
}
|
||||
}
|
||||
|
||||
if (ticks < TIMER_MIN_TLC_VAL)
|
||||
ticks = TIMER_MIN_TLC_VAL;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
void xc_timer_set_value(uint8_t reg_idx, uint32_t us)
|
||||
{
|
||||
uint32_t ticks = xc_timer_us_to_ticks(reg_idx, us);
|
||||
|
||||
timer_tcr__tes__setf(reg_idx, TIMER_TCR_TES_DISABLE);
|
||||
|
||||
timer_tlc_set(reg_idx, ticks);
|
||||
}
|
||||
|
||||
void xc_timer_start(uint8_t reg_idx)
|
||||
{
|
||||
NVIC_EnableIRQ((IRQn_Type)(TIMER0_IRQn + reg_idx));
|
||||
timer_tcr__tim__setf(reg_idx, TIMER_TCR_TIM_DISABLE);
|
||||
timer_tcr__tes__setf(reg_idx, TIMER_TCR_TES_ENABLE);
|
||||
}
|
||||
|
||||
void xc_timer_stop(uint8_t reg_idx)
|
||||
{
|
||||
timer_tcr__tes__setf(reg_idx, TIMER_TCR_TES_DISABLE);
|
||||
}
|
||||
|
||||
void TIMER0_Handler(void)
|
||||
{
|
||||
(void)timer_tic_get(TIMER0_IDX);
|
||||
if (timer_n_callback[0] != NULL)
|
||||
timer_n_callback[0](NULL);
|
||||
}
|
||||
|
||||
void TIMER1_Handler(void)
|
||||
{
|
||||
(void)timer_tic_get(TIMER1_IDX);
|
||||
if (timer_n_callback[1] != NULL)
|
||||
timer_n_callback[1](NULL);
|
||||
}
|
||||
|
||||
void TIMER2_Handler(void)
|
||||
{
|
||||
(void)timer_tic_get(TIMER2_IDX);
|
||||
if (timer_n_callback[2] != NULL)
|
||||
timer_n_callback[2](NULL);
|
||||
}
|
||||
|
||||
void TIMER3_Handler(void)
|
||||
{
|
||||
(void)timer_tic_get(TIMER3_IDX);
|
||||
if (timer_n_callback[3] != NULL)
|
||||
timer_n_callback[3](NULL);
|
||||
}
|
||||
|
||||
__WEAK void timer0_callback(void *context) {}
|
||||
|
||||
__WEAK void timer1_callback(void *context) {}
|
||||
|
||||
__WEAK void timer2_callback(void *context) {}
|
||||
|
||||
__WEAK void timer3_callback(void *context) {}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*!
|
||||
* \file xc_drv_timer.h
|
||||
*
|
||||
* \brief The header of xc_drv_aotimer.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef _XC_DRV_TIMER_H_
|
||||
#define _XC_DRV_TIMER_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xc6xxx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define TIMER_MIN_TLC_VAL 0x04
|
||||
#define TIMER_CLKSRC_32K_CAL(us) ( (CLOCK_RC_LFCLK_IN_32K / 1000)*us / 1000)
|
||||
#define TIMER_CLKSRC_32K_DIV_CAL(us, div) (32000 /(2 * (div + 1)) /100 * us / 10000)
|
||||
#define TIMER_CLKSRC_32M_DIV_CAL(us, div) (32000000 / (2 * (div + 1)) /100000 * us / 10)
|
||||
|
||||
|
||||
|
||||
#define TIMER_TCR_TIM_DISABLE (0x00UL)
|
||||
#define TIMER_TCR_TIM_ENABLE (0x01UL)
|
||||
|
||||
#define TIMER_TCR_TES_ENABLE (0x01UL)
|
||||
#define TIMER_TCR_TES_DISABLE (0x00UL)
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
TIMER_CLK_SRC_32M_DIV = 0, /* Timer CLK SRC 32MHz div. */
|
||||
TIMER_CLK_SRC_32K_DIV = 1, /* Timer CLK SRC 32kHz div. */
|
||||
TIMER_CLK_SRC_32K = 3, /* Timer CLK SRC 32kHz. */
|
||||
} TIMER_SrcClkTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER_DIV_CLK_16MHzOr16K = 0, /* Timer ref clk 16 MHz or 16KHz */
|
||||
TIMER_DIV_CLK_8MHzOr8K = 1, /* Timer ref clk 8 MHz or 8KHz */
|
||||
TIMER_DIV_CLK_4MHzOr4K = 2, /* Timer ref clk 4 MHz or 4KHz.*/
|
||||
TIMER_DIV_CLK_2MHzOr2K = 3, /* Timer ref clk 2 MHz or 2KHz.*/
|
||||
TIMER_DIV_CLK_1MHzOr1K = 4, /* Timer ref clk 1 MHz or 1KHz.*/
|
||||
TIMER_DIV_CLK_500KHzOr500 = 5, /* Timer ref clk 500 kHz or 500Hz.*/
|
||||
TIMER_DIV_CLK_250KHzOr250 = 6, /* Timer ref clk 250 kHz or 250Hz.*/
|
||||
TIMER_DIV_CLK_125KHzOr125 = 7, /* Timer ref clk 125 kHz or 125Hz.*/
|
||||
TIMER_DIV_CLK_62500HzOr62_5 = 8, /* Timer ref clk 62500 Hz or 62.5Hz.*/
|
||||
TIMER_DIV_CLK_32000Hz = 9 /* Timer ref clk 32000 Hz.*/
|
||||
} Timer_DivClkTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TIMER_MODE_SINGLE = 0,
|
||||
TIMER_MODE_CYCLE = 1,
|
||||
} Timer_ModeTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TIMER_SrcClkTypeDef timer_src_clk; /* Timer src clk. */
|
||||
Timer_DivClkTypeDef timer_div_clk; /* Timer div clk. */
|
||||
Timer_ModeTypeDef timer_mode; /* Timer mode. */
|
||||
uint32_t ticks; /* Timer ticks. */
|
||||
} Timer_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef void (*timer_handler_callback)(void *context);
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_timer_init(uint8_t reg_idx, Timer_InitCfg_t *init_cfg);
|
||||
void xc_timer_set_value(uint8_t reg_idx, uint32_t us);
|
||||
void xc_timer_start(uint8_t reg_idx);
|
||||
void xc_timer_stop(uint8_t reg_idx);
|
||||
|
||||
void timer0_callback(void *context);
|
||||
void timer1_callback(void *context);
|
||||
void timer2_callback(void *context);
|
||||
void timer3_callback(void *context);
|
||||
|
||||
#endif // _XC_DRV_AOTIMER_H_
|
||||
@@ -0,0 +1,244 @@
|
||||
/*!
|
||||
* \file xc6xxx_hal_uart.c
|
||||
*
|
||||
* \brief Target xc6xxx hal uart implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_uart.h"
|
||||
//#include "usr_server.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t __attribute__((aligned(4))) uart_txdmabuff[UART_BUFF_LEN];
|
||||
uint8_t __attribute__((aligned(4))) uart_rxdmabuff[UART_BUFF_LEN];
|
||||
|
||||
UART_Block_t uart_ctl_block;
|
||||
ring_buffer_t uart_rxbuffer[UART_NUM];
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_uart_init(uint8_t reg_idx, UART_InitCfg_t *uart_cfg)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t uart_clk = 0x00;
|
||||
|
||||
uint32_t div, mul, clk_ctl, adj_div, m0_fclk_div;
|
||||
|
||||
m0_fclk_div = cpr_m0_fclk_ctl__m0_fclk_div__getf();
|
||||
uart_clk = xc_clock_hfclk_in_get() * (m0_fclk_div + 1);
|
||||
|
||||
mul = (uart_cfg->BaudRate >> 20) & 0xFFFF;
|
||||
div = (uart_cfg->BaudRate >> 4) & 0xFFFF;
|
||||
|
||||
adj_div = uart_clk / 1000000;
|
||||
clk_ctl = (mul << 16) | (div * adj_div / 32);
|
||||
|
||||
if (reg_idx == UART0_IDX) {
|
||||
cpr_rstctl_subrst_sw__uart0_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__uart0_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
val = cpr_lp_ctl_get();
|
||||
val &= ~(UART0_CLK_OFF_PROTECT_EN_BIT);
|
||||
cpr_lp_ctl_set(val);
|
||||
|
||||
cpr_ctlapbclken_grctl__uart0_pclk_en__setf(ENABLE);
|
||||
cpr_uart0_clk_grctl__uart0_clk_gr__setf(8);
|
||||
cpr_uart0_clk_grctl__uart0_clk_gr_upd__setf(ENABLE);
|
||||
cpr_uart0_clk_ctl_set(clk_ctl);
|
||||
}
|
||||
if (reg_idx == UART1_IDX) {
|
||||
cpr_rstctl_subrst_sw__uart1_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__uart1_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
val = cpr_lp_ctl_get();
|
||||
val &= ~(UART1_CLK_OFF_PROTECT_EN_BIT);
|
||||
cpr_lp_ctl_set(val);
|
||||
|
||||
cpr_ctlapbclken_grctl__uart1_pclk_en__setf(ENABLE);
|
||||
cpr_uart1_clk_grctl__uart1_clk_gr__setf(8);
|
||||
cpr_uart1_clk_grctl__uart1_clk_gr_upd__setf(ENABLE);
|
||||
cpr_uart1_clk_ctl_set(clk_ctl);
|
||||
}
|
||||
if (reg_idx == UART2_IDX) {
|
||||
cpr_rstctl_subrst_sw__uart2_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__uart2_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_uart2_clk_grctl__uart2_pclk_en__setf(ENABLE);
|
||||
cpr_uart2_clk_grctl__uart2_clk_gr__setf(8);
|
||||
cpr_uart2_clk_grctl__uart2_clk_gr_upd__setf(ENABLE);
|
||||
|
||||
cpr_uart2_clk_ctl_set(clk_ctl);
|
||||
}
|
||||
|
||||
uart_tcr__dlab__setf(reg_idx, UART_TCR_DLAB_DLLH_ENABLE);
|
||||
uart_dll__dll__setf(reg_idx, (uart_cfg->BaudRate & 0xF));
|
||||
uart_ier_set(reg_idx, 0);
|
||||
uart_tcr__dlab__setf(reg_idx, UART_TCR_DLAB_DLLH_DISABLE);
|
||||
|
||||
while (uart_usr_get(reg_idx) == 1) {
|
||||
};
|
||||
|
||||
uart_tcr__eps__setf(reg_idx, uart_cfg->Parity);
|
||||
|
||||
uart_tcr__stop__setf(reg_idx, uart_cfg->StopBits);
|
||||
|
||||
uart_tcr__cls__setf(reg_idx, uart_cfg->WordLength);
|
||||
|
||||
uart_mcr__afce__setf(reg_idx, uart_cfg->HardwareFlowControl);
|
||||
|
||||
uart_fcr_pack(reg_idx, UART_FCR_RCVR_TRIGGER_FIFO_1_BYTE, UART_FCR_TX_EMPTY_TRIGGER_FIFO_2_1,
|
||||
UART_FCR_XMIT_FIFO_RESET_CLEAR, UART_FCR_RCVR_FIFO_RESET_CLEAR, UART_FCR_FIFO_ENABLE_ENABLE);
|
||||
}
|
||||
|
||||
void xc_uart_enable_rx_it(uint8_t reg_idx) { uart_ier__erdai__setf(reg_idx, UART_IER_ERDAI_ENABLE); }
|
||||
|
||||
void xc_uart_disable_rx_it(uint8_t reg_idx) { uart_ier__erdai__setf(reg_idx, UART_IER_ERDAI_DISABLE); }
|
||||
|
||||
void xc_uart_send_byte(uint8_t reg_idx, uint8_t byte)
|
||||
{
|
||||
while (1) {
|
||||
if (uart_tsr__thre__getf(reg_idx) & UART_TSR_THRE_VALID) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uart_thr__thr__setf(reg_idx, byte);
|
||||
}
|
||||
|
||||
void xc_uart_send_data(uint8_t reg_idx, uint8_t *data, uint16_t len)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
xc_uart_send_byte(reg_idx, data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint16_t xc_uart_receive_data(uint8_t reg_idx, uint8_t *data)
|
||||
{
|
||||
uint8_t ch = (reg_idx == UART0_IDX) ? 0 : ((reg_idx == UART1_IDX) ? 1 : 2);
|
||||
|
||||
if ((uart_tsr__dr__getf(reg_idx) & UART_TSR_DR_VALID) !=
|
||||
UART_TSR_DR_VALID) {
|
||||
|
||||
uint16_t recv_len = ring_buffer_num_items(&uart_rxbuffer[ch]);//获取环形缓冲区数据长度
|
||||
if (recv_len==5){
|
||||
ring_buffer_dequeue_arr(&uart_rxbuffer[ch], data, recv_len);
|
||||
return recv_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
void xc_uart_ctl_block_reset(void)
|
||||
{
|
||||
memset(&uart_ctl_block, 0, sizeof(uart_ctl_block));
|
||||
uart_ctl_block.uart_receive_cb = NULL;
|
||||
}
|
||||
|
||||
void xc_uart_register_receive_cb(uart_handler_callback uart_cb) { uart_ctl_block.uart_receive_cb = uart_cb; }
|
||||
|
||||
|
||||
|
||||
uint8_t Myrx_buff[uarx_size];
|
||||
uint8_t rx_complete=0;
|
||||
bool buffer_complet_flag = 0;
|
||||
|
||||
|
||||
__WEAK void uart_user_handler(uint8_t reg_idx)
|
||||
{
|
||||
static volatile uint8_t count = 0;
|
||||
uint8_t rx_val;
|
||||
uint32_t IIR, TSR;
|
||||
uint8_t ch = (reg_idx == UART0_IDX) ? 0 : ((reg_idx == UART1_IDX) ? 1 : 2);
|
||||
static uint8_t buffer_cnt = 0;
|
||||
|
||||
rx_val = uart_rbr__rbr__getf(reg_idx);
|
||||
IIR = uart_iir__iid__getf(reg_idx);
|
||||
TSR = uart_tsr_get(reg_idx);
|
||||
if(rx_complete==0){
|
||||
Myrx_buff[count]=rx_val;
|
||||
|
||||
if(Myrx_buff[0] == 0XCC){ //
|
||||
count++;
|
||||
}else{
|
||||
count = 0;
|
||||
}
|
||||
if (count>=2&&count >=Myrx_buff[1]){
|
||||
count = 0;
|
||||
rx_complete = 1; // 接收完成标志
|
||||
}
|
||||
}
|
||||
|
||||
// if (((IIR & IID_MASK) == UART_IIR_IID_BUSY)) {
|
||||
// uart_usr_get(reg_idx);
|
||||
// }
|
||||
|
||||
// if (((IIR & IID_MASK) == UART_IIR_IID_ETSI)) {
|
||||
// DEBUG("line=%d, error handle \n", __LINE__);
|
||||
// }
|
||||
//
|
||||
// if (((IIR & IID_MASK) == UART_IIR_IID_ERDAI)) {
|
||||
// TSR = uart_tsr_get(reg_idx);
|
||||
// while ((TSR & UART_TSR_DR_VALID) == UART_TSR_DR_VALID) {
|
||||
// rx_val = uart_rbr__rbr__getf(reg_idx);
|
||||
// TSR = uart_tsr_get(reg_idx);
|
||||
//
|
||||
// if (uart_ctl_block.uart_receive_cb != NULL) {
|
||||
//
|
||||
// uart_ctl_block.uart_receive_cb(&rx_val, 1); //串口接收
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if ((IIR & IID_MASK) == UART_IIR_IID_TO) {
|
||||
// TSR = uart_tsr_get(reg_idx);
|
||||
// while ((TSR & UART_TSR_DR_VALID) == UART_TSR_DR_VALID) {
|
||||
|
||||
// rx_val = uart_rbr__rbr__getf(reg_idx);
|
||||
// TSR = uart_tsr_get(reg_idx);
|
||||
// if (uart_ctl_block.uart_receive_cb != NULL) {
|
||||
// uart_ctl_block.uart_receive_cb(&rx_val, 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void UART0_Handler(void) { uart_user_handler(UART0_IDX); }
|
||||
|
||||
void UART1_Handler(void) { uart_user_handler(UART1_IDX); }
|
||||
|
||||
void UART2_Handler(void) { uart_user_handler(UART2_IDX); }
|
||||
@@ -0,0 +1,261 @@
|
||||
/*!
|
||||
* \file xc_drv_uart.h
|
||||
*
|
||||
* \brief The header of xc_drv_uart.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/** Define to Prevent Recursive Inclusion */
|
||||
#ifndef __XC_UART_H__
|
||||
#define __XC_UART_H__
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ringbuffer.h"
|
||||
#include "xc6xxx.h"
|
||||
//bool buffer_complet_flag = 0;
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
typedef void (*uart_handler_callback)(uint8_t *buff, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief UART interrupt ID enumeration
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
UART_IT_Modem_Status = 0x00, /*!< modem status Interrupt */
|
||||
UART_NO_Pending_INT = 0x01, /*!< no interrupt pending */
|
||||
UART_IT_THR_Empty = 0x02, /*!< THR emptyInterrupt */
|
||||
UART_IT_Received_Data_Available = 0x04, /*!< received data available Interrupt */
|
||||
UART_IT_Receive_Line_Status = 0x06, /*!< receiver line status Interrupt */
|
||||
UART_IT_Character_Timeout = 0x0C, /*!< character timeout Interrupt */
|
||||
} UART_IT_TypeDef;
|
||||
|
||||
/**
|
||||
* @brief UART Init Structure Definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t BaudRate;
|
||||
|
||||
uint16_t WordLength;
|
||||
|
||||
uint16_t StopBits;
|
||||
|
||||
uint16_t Parity;
|
||||
|
||||
uint16_t HardwareFlowControl;
|
||||
|
||||
} UART_InitCfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uart_handler_callback uart_receive_cb;
|
||||
} UART_Block_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define UART_IER_ERDA_ENABLE (0x1UL)
|
||||
#define UART_IER_ERDA_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_ETHEI_ENABLE (0x1UL)
|
||||
#define UART_IER_ETHEI_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_ETSI_ENABLE (0x1UL)
|
||||
#define UART_IER_ETSI_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_EMSI_ENABLE (0x1UL)
|
||||
#define UART_IER_EMSI_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_ETSI_ENABLE (0x1UL)
|
||||
#define UART_IER_ETSI_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_ETHSI_ENABLE (0x1UL)
|
||||
#define UART_IER_ETHSI_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_ERDAI_ENABLE (0x1UL)
|
||||
#define UART_IER_ERDAI_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IER_PTIME_ENABLE (0x1UL)
|
||||
#define UART_IER_PTIME_DISABLE (0x0UL)
|
||||
|
||||
#define UART_IIR_IID_EMSI (0x0UL)
|
||||
#define UART_IIR_IID_NO_IT (0x1UL)
|
||||
#define UART_IIR_IID_ETHEI (0x02UL)
|
||||
#define UART_IIR_IID_ERDAI (0x04UL)
|
||||
#define UART_IIR_IID_ETSI (0x06UL)
|
||||
#define UART_IIR_IID_BUSY (0x07UL)
|
||||
#define UART_IIR_IID_TO (0xCUL)
|
||||
|
||||
#define UART_IIR_FS_ENABLE (0x3UL)
|
||||
#define UART_IIR_FS_DISABLE (0x0UL)
|
||||
|
||||
#define UART_FCR_FIFO_ENABLE_ENABLE (0x1UL)
|
||||
#define UART_FCR_FIFO_ENABLE_DISABLE (0x0UL)
|
||||
|
||||
#define UART_FCR_RCVR_FIFO_RESET_CLEAR (0x1UL)
|
||||
#define UART_FCR_RCVR_FIFO_RESET_NOT_CLEAR (0x0UL)
|
||||
|
||||
#define UART_FCR_XMIT_FIFO_RESET_CLEAR (0x1UL)
|
||||
#define UART_FCR_XMIT_FIFO_RESET_NOT_CLEAR (0x0UL)
|
||||
|
||||
#define UART_FCR_TX_EMPTY_TRIGGER_FIFO_EMPTY (0x0UL)
|
||||
#define UART_FCR_TX_EMPTY_TRIGGER_FIFO_2_BYTE (0x1UL)
|
||||
#define UART_FCR_TX_EMPTY_TRIGGER_FIFO_4_3 (0x2UL)
|
||||
#define UART_FCR_TX_EMPTY_TRIGGER_FIFO_2_1 (0x3UL)
|
||||
|
||||
#define UART_FCR_RCVR_TRIGGER_FIFO_1_BYTE (0x0UL)
|
||||
#define UART_FCR_RCVR_TRIGGER_FIFO_4_1 (0x1UL)
|
||||
#define UART_FCR_RCVR_TRIGGER_FIFO_2_1 (0x2UL)
|
||||
#define UART_FCR_RCVR_TRIGGER_FIFO_LESS_2_BYTE (0x3UL)
|
||||
|
||||
#define UART_TCR_CLS_Pos (0UL)
|
||||
#define UART_TCR_CLS_Msk (0x3UL)
|
||||
#define UART_TCR_CLS_5BITS (0x0UL)
|
||||
#define UART_TCR_CLS_6BITS (0x1UL)
|
||||
#define UART_TCR_CLS_7BITS (0x2UL)
|
||||
#define UART_TCR_CLS_8BITS (0x3UL)
|
||||
|
||||
#define UART_TCR_STOP_Pos (2UL)
|
||||
#define UART_TCR_STOP_Msk (0x1UL)
|
||||
#define UART_TCR_STOP_1BITS (0x0UL)
|
||||
#define UART_TCR_STOP_1_5BITS (0x1UL)
|
||||
|
||||
#define UART_TCR_STOP_2BITS (0x1UL)
|
||||
|
||||
#define UART_TCR_PEN_DISABLE (0x0UL)
|
||||
#define UART_TCR_PENS_ENABLE (0x1UL)
|
||||
|
||||
#define UART_TCR_EPS_ODD (0x0UL)
|
||||
#define UART_TCR_EPS_EVEN (0x1UL)
|
||||
|
||||
#define UART_TCR_BREAK_STOP (0x1UL)
|
||||
#define UART_TCR_BREAK_RECOVER (0x0UL)
|
||||
|
||||
#define UART_TCR_DLAB_DLLH_ENABLE (0x1UL)
|
||||
#define UART_TCR_DLAB_DLLH_DISABLE (0x0UL)
|
||||
|
||||
#define UART_MCR_RTS_Msk (0x1UL)
|
||||
#define UART_MCR_RTS_OUT_HIGH (0x1UL)
|
||||
#define UART_MCR_RTS_OUT_LOW (0x0UL)
|
||||
|
||||
#define UART_MCR_AFCE_ENABLE (0x1UL)
|
||||
#define UART_MCR_AFCE_DISABLE (0x0UL)
|
||||
|
||||
#define UART_TSR_DR_VALID (0x1UL)
|
||||
#define UART_TSR_DR_INVALID (0x0UL)
|
||||
|
||||
#define UART_TSR_OE_VALID (0x1UL)
|
||||
#define UART_TSR_OE_INVALID (0x0UL)
|
||||
|
||||
#define UART_TSR_PE_Pos (2UL)
|
||||
#define UART_TSR_PE_Msk (0x1UL)
|
||||
#define UART_TSR_PE_VALID (0x1UL)
|
||||
#define UART_TSR_PE_INVALID (0x0UL)
|
||||
|
||||
#define UART_TSR_FE_VALID (0x1UL)
|
||||
#define UART_TSR_FE_INVALID (0x0UL)
|
||||
|
||||
#define UART_TSR_BI_VALID (0x1UL)
|
||||
#define UART_TSR_BI_INVALID (0x0UL)
|
||||
|
||||
#define UART_TSR_THRE_VALID (0x1UL)
|
||||
#define UART_TSR_THRE_INVALID (0x0UL)
|
||||
|
||||
#define UART_TSR_RX_FIFO_ERROR_VALID (0x1UL)
|
||||
#define UART_TSR_RX_FIFO_ERROR_INVALID (0x0UL)
|
||||
|
||||
#define UART_MSR_DCTS_CHANGE (0x1UL)
|
||||
#define UART_MSR_DCTS_NO_CHANGE (0x0UL)
|
||||
|
||||
#define UART_MSR_CTS_OUT_LOW (0x1UL)
|
||||
#define UART_MSR_CTS_OUT_HIGH (0x0UL)
|
||||
|
||||
#define UART_USR_BUSY_BUSY (0x1UL)
|
||||
#define UART_USR_BUSY_IDLE (0x0UL)
|
||||
|
||||
#define UART_NUM 3
|
||||
#define UART_BUFF_LEN 64U
|
||||
|
||||
#define UART_DATA_5_BITS UART_TCR_CLS_5BITS
|
||||
#define UART_DATA_6_BITS UART_TCR_CLS_6BITS
|
||||
#define UART_DATA_7_BITS UART_TCR_CLS_7BITS
|
||||
#define UART_DATA_8_BITS UART_TCR_CLS_8BITS
|
||||
|
||||
#define UART_STOP_1_BITS UART_TCR_STOP_1BITS
|
||||
#define UART_STOP_1_5_BITS UART_TCR_STOP_1_5BITS
|
||||
#define UART_STOP_2_BITS UART_TCR_STOP_2BITS
|
||||
|
||||
#define UART_HWFC_DISABLE UART_MCR_AFCE_DISABLE
|
||||
#define UART_HWFC_ENABLE UART_MCR_AFCE_ENABLE
|
||||
|
||||
#define UART_PARITY_ENABLE UART_TCR_PENS_ENABLE
|
||||
#define UART_PARITY_DISABLE UART_TCR_PEN_DISABLE
|
||||
|
||||
#define UART_PARITY_EVEN (UART_TCR_EPS_EVEN | UART_PARITY_ENABLE)
|
||||
#define UART_PARITY_ODD (UART_TCR_EPS_ODD | UART_PARITY_ENABLE)
|
||||
|
||||
#define UART_BAUDRATE_2400 (0x0120271CUL)
|
||||
#define UART_BAUDRATE_4800 (0x0240271CUL)
|
||||
#define UART_BAUDRATE_9600 (0x0480271CUL)
|
||||
#define UART_BAUDRATE_12800 (0x04802719UL)
|
||||
#define UART_BAUDRATE_14400 (0x04802718UL)
|
||||
#define UART_BAUDRATE_19200 (0x04802716UL)
|
||||
#define UART_BAUDRATE_23040 (0x04802715UL)
|
||||
#define UART_BAUDRATE_38400 (0x04802713UL)
|
||||
#define UART_BAUDRATE_57600 (0x04802712UL)
|
||||
#define UART_BAUDRATE_115200 (0x04802711UL)
|
||||
#define UART_BAUDRATE_128000 (0x030007D3UL)
|
||||
#define UART_BAUDRATE_230400 (0x09002711UL)
|
||||
#define UART_BAUDRATE_256000 (0x060007D3UL)
|
||||
#define UART_BAUDRATE_460800 (0x12002711UL)
|
||||
#define UART_BAUDRATE_921600 (0x24002711UL)
|
||||
#define UART_BAUDRATE_1M (0x00100011UL)
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define uarx_size (132)
|
||||
|
||||
|
||||
extern uint8_t __attribute__((aligned(4))) uart_txdmabuff[UART_BUFF_LEN];
|
||||
extern uint8_t __attribute__((aligned(4))) uart_rxdmabuff[UART_BUFF_LEN];
|
||||
extern uint8_t Myrx_buff[];
|
||||
extern uint8_t rx_complete;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_uart_init(uint8_t reg_idx, UART_InitCfg_t *uart_cfg);
|
||||
void xc_uart_enable_rx_it(uint8_t reg_idx);
|
||||
void xc_uart_disable_rx_it(uint8_t reg_idx);
|
||||
void xc_uart_send_byte(uint8_t reg_idx, uint8_t byte);
|
||||
void xc_uart_send_data(uint8_t reg_idx, uint8_t *data, uint16_t len);
|
||||
uint16_t xc_uart_receive_data(uint8_t reg_idx, uint8_t *data);
|
||||
void xc_uart_register_receive_cb(uart_handler_callback uart_cb);
|
||||
#endif /* __XC6xxx_HAL_UART_H__ */
|
||||
@@ -0,0 +1,316 @@
|
||||
/*!
|
||||
* \file xc_drv_uart_dma.c
|
||||
*
|
||||
* \brief Target xinchip uart dma driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_uart_dma.h"
|
||||
#if (UART_DMA_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
volatile bool uart0_tx_tfr_flag = true;
|
||||
volatile bool uart1_tx_tfr_flag = true;
|
||||
static volatile bool err_flag = false;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__weak void uart0_dma_tx_callback(uint8_t eCode)
|
||||
{
|
||||
xc_dma_disable( );
|
||||
uart0_tx_tfr_flag = true;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__weak void uart1_dma_tx_callback(uint8_t eCode)
|
||||
{
|
||||
xc_dma_disable( );
|
||||
uart1_tx_tfr_flag = true;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__weak void uart0_dma_rx_callback(uint8_t eCode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__weak void uart1_dma_rx_callback(uint8_t eCode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void uartx_dma_tx_err(uint8_t eCode)
|
||||
{
|
||||
// -------
|
||||
// This function is called by the IRQ handler.
|
||||
// We use this function to deal with interrupts that the DMA
|
||||
// driver is unable to cater for (these are application
|
||||
// specific). All of the interrupts handled by this function
|
||||
// are cleared by the DMA driver, so there's no need to clear here.
|
||||
// -------
|
||||
|
||||
// Check the source of the interrupt
|
||||
|
||||
if(eCode == DMA_IRQ_ERR) {
|
||||
|
||||
// Just inform the application that this interrupt has occured.
|
||||
err_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t xc_uart_dma_tx_config(uint8_t uart_idx, uint32_t ch_num, uint16_t blockSize, uint8_t *tx_buff)
|
||||
{
|
||||
DMA_Chx_Cfg_t ch_cfg;
|
||||
uint8_t errorCode = DMA_OK;
|
||||
uint32_t uart_prf_addr = 0;
|
||||
|
||||
if(uart_idx == UART2_IDX) {
|
||||
errorCode = DMA_EPERM;
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
if(uart_idx == UART0_IDX) {
|
||||
uart_prf_addr = XC_REG_UART_BASE_ADDR;
|
||||
} else if(uart_idx == UART1_IDX) {
|
||||
uart_prf_addr = XC_REG_UART_BASE_ADDR + uart_offset[uart_idx];
|
||||
}
|
||||
|
||||
ch_cfg.sar = (uint32_t)tx_buff;
|
||||
ch_cfg.dar = (uint32_t)uart_prf_addr;
|
||||
|
||||
ch_cfg.ctl_src_msize = DMA_MSIZE_1;
|
||||
ch_cfg.ctl_dst_msize = DMA_MSIZE_1;
|
||||
|
||||
ch_cfg.ctl_sinc = DMA_ADDR_INCREMENT;
|
||||
ch_cfg.ctl_dinc = DMA_ADDR_NOCHANGE;
|
||||
|
||||
ch_cfg.ctl_src_tr_width = DMA_TRANS_WIDTH_8;
|
||||
ch_cfg.ctl_dst_tr_width = DMA_TRANS_WIDTH_8;
|
||||
|
||||
ch_cfg.ctl_tt_fc = DMA_MEM2PRF_DMA;
|
||||
|
||||
ch_cfg.ctl_block_ts = blockSize;
|
||||
|
||||
ch_cfg.cfg_hs_sel_src = DMA_HS_HARDWARE;
|
||||
ch_cfg.cfg_hs_sel_dst = DMA_HS_HARDWARE;
|
||||
|
||||
ch_cfg.cfg_fifo_mode = DMA_FIFO_MODE_SINGLE;
|
||||
|
||||
if(uart_idx == UART0_IDX)
|
||||
ch_cfg.cfg_dst_per = UART0_DMA_TX_HS_IF0;
|
||||
else if(uart_idx == UART1_IDX)
|
||||
ch_cfg.cfg_dst_per = UART1_DMA_TX_HS_IF1;
|
||||
|
||||
// ch_cfg.cfg_ch_prior = DMAC_PRIORITY_0;
|
||||
// Now we can intialise the channel configuration structure for
|
||||
// DMA channel 0 by loading the structure members with the
|
||||
// contents of the DMAC's channel 0 registers.
|
||||
errorCode = xc_dma_set_channel_config((eDMA_Ch_Num)ch_num, &ch_cfg);
|
||||
if(errorCode != 0) {
|
||||
DEBUG("\nERROR: Failed to initialise configuration\n");
|
||||
}
|
||||
|
||||
xc_dma_set_listener((eDMA_Ch_Num)ch_num, uartx_dma_tx_err);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_uart_dma_send(uint8_t uart_idx, uint32_t ch_num, uint16_t tx_size, uint8_t *tx_buff)
|
||||
{
|
||||
uint8_t errorCode;
|
||||
|
||||
errorCode = xc_uart_dma_tx_config(uart_idx, ch_num, tx_size, tx_buff);
|
||||
if(errorCode != 0) {
|
||||
DEBUG("\nERROR: Failed XC_UART_DMA_TX_CONFIG\n");
|
||||
}
|
||||
xc_dma_enable( );
|
||||
|
||||
if(uart_idx == UART0_IDX) {
|
||||
uart0_tx_tfr_flag = false;
|
||||
errorCode = xc_dma_start_transfer(ch_num, uart0_dma_tx_callback);
|
||||
} else if(uart_idx == UART1_IDX) {
|
||||
uart1_tx_tfr_flag = false;
|
||||
errorCode = xc_dma_start_transfer(ch_num, uart1_dma_tx_callback);
|
||||
}
|
||||
|
||||
if(errorCode != 0) {
|
||||
DEBUG("\nERROR: Failed Uart DMA_StartTransfer Tx\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
uint8_t xc_uart_dma_rx_config(uint8_t uart_idx, uint32_t ch_num, uint16_t blockSize, uint8_t *rx_buff)
|
||||
{
|
||||
DMA_Chx_Cfg_t ch_cfg;
|
||||
uint8_t errorCode = DMA_OK;
|
||||
uint32_t uart_prf_addr = 0;
|
||||
|
||||
if(uart_idx == UART2_IDX) {
|
||||
errorCode = DMA_EPERM;
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
if(uart_idx == UART0_IDX) {
|
||||
uart_prf_addr = XC_REG_UART_BASE_ADDR;
|
||||
} else if(uart_idx == UART1_IDX) {
|
||||
uart_prf_addr = XC_REG_UART_BASE_ADDR + uart_offset[uart_idx];
|
||||
}
|
||||
|
||||
ch_cfg.sar = (uint32_t)uart_prf_addr;
|
||||
ch_cfg.dar = (uint32_t)rx_buff;
|
||||
|
||||
ch_cfg.ctl_src_msize = DMA_MSIZE_1;
|
||||
ch_cfg.ctl_dst_msize = DMA_MSIZE_1;
|
||||
|
||||
ch_cfg.ctl_sinc = DMA_ADDR_NOCHANGE;
|
||||
ch_cfg.ctl_dinc = DMA_ADDR_INCREMENT;
|
||||
|
||||
ch_cfg.ctl_src_tr_width = DMA_TRANS_WIDTH_8;
|
||||
ch_cfg.ctl_dst_tr_width = DMA_TRANS_WIDTH_8;
|
||||
|
||||
ch_cfg.ctl_tt_fc = DMA_PRF2MEM_DMA;
|
||||
|
||||
if(uart_idx == UART0_IDX){
|
||||
ch_cfg.cfg_src_per = UART0_DMA_RX_HS_IF8;
|
||||
} else if(uart_idx == UART1_IDX) {
|
||||
ch_cfg.cfg_src_per = UART1_DMA_RX_HS_IF9;
|
||||
}
|
||||
|
||||
ch_cfg.ctl_block_ts = blockSize;
|
||||
|
||||
ch_cfg.cfg_hs_sel_src = DMA_HS_HARDWARE;
|
||||
ch_cfg.cfg_hs_sel_dst = DMA_HS_HARDWARE;
|
||||
|
||||
ch_cfg.cfg_fifo_mode = DMA_FIFO_MODE_SINGLE;
|
||||
|
||||
if(uart_idx == UART0_IDX)
|
||||
ch_cfg.cfg_dst_per = UART0_DMA_TX_HS_IF0;
|
||||
else if(uart_idx == UART1_IDX)
|
||||
ch_cfg.cfg_dst_per = UART1_DMA_TX_HS_IF1;
|
||||
|
||||
// Now we can intialise the channel configuration structure for
|
||||
// DMA channel 0 by loading the structure members with the
|
||||
// contents of the DMAC's channel 0 registers.
|
||||
errorCode = xc_dma_set_channel_config((eDMA_Ch_Num)ch_num, &ch_cfg);
|
||||
if(errorCode != 0) {
|
||||
DEBUG("\nERROR: Failed to initialise configuration\n");
|
||||
}
|
||||
|
||||
xc_dma_set_listener((eDMA_Ch_Num)ch_num, uartx_dma_tx_err);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_uart_dma_receive(uint8_t uart_idx, uint32_t ch_num, uint16_t rx_size, uint8_t *rx_buff)
|
||||
{
|
||||
uint8_t errorCode;
|
||||
|
||||
errorCode = xc_uart_dma_rx_config(uart_idx, ch_num, rx_size, rx_buff);
|
||||
if(errorCode != 0) {
|
||||
DEBUG("\nERROR: Failed XC_UART_DMA_TX_CONFIG\n");
|
||||
}
|
||||
|
||||
xc_dma_enable( );
|
||||
|
||||
if(uart_idx == UART0_IDX) {
|
||||
errorCode = xc_dma_start_transfer((eDMA_Ch_Num)ch_num, uart0_dma_rx_callback);
|
||||
}else if(uart_idx == UART1_IDX){
|
||||
errorCode = xc_dma_start_transfer((eDMA_Ch_Num)ch_num, uart1_dma_rx_callback);
|
||||
}
|
||||
|
||||
if(errorCode != 0) {
|
||||
DEBUG("\nERROR: Failed Uart DMA_StartTransfer Tx\n");
|
||||
}
|
||||
}
|
||||
#endif //(UART_DMA_ON)
|
||||
@@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* \file xc_drv_uart_dma.h
|
||||
*
|
||||
* \brief The header of xc_drv_uart_dma.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
#ifndef __XC_DRV_UART_DMA_H__
|
||||
#define __XC_DRV_UART_DMA_H__
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_dma.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern volatile bool uart0_tx_tfr_flag;
|
||||
extern volatile bool uart1_tx_tfr_flag;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t xc_uart_dma_tx_config(uint8_t uart_idx, uint32_t ch_num, uint16_t blockSize, uint8_t *tx_buff);
|
||||
void xc_uart_dma_send(uint8_t uart_idx, uint32_t ch_num, uint16_t rx_size, uint8_t *tx_buff);
|
||||
uint8_t xc_uart_dma_rx_config(uint8_t uart_idx, uint32_t ch_num, uint16_t blockSize, uint8_t *rx_buff);
|
||||
void xc_uart_dma_receive(uint8_t uart_idx, uint32_t ch_num, uint16_t rx_size, uint8_t *rx_buff);
|
||||
|
||||
#endif /* __XC_DRV_UART_DMA_H__ */
|
||||
@@ -0,0 +1,146 @@
|
||||
/*!
|
||||
* \file xc6xxx_hal_wdt.c
|
||||
*
|
||||
* \brief Target xc6xxx hal wdt implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
--------------------------------------------------------------------------------------*/
|
||||
#include "xc_drv_wdt.h"
|
||||
#if (WDT_ON)
|
||||
/*------------------------------------------------------------------------------------
|
||||
Local Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
static uint8_t reload_val ;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_wdt_init(WDT_InitCfg_t *wdt_cfg)
|
||||
{
|
||||
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
/*
|
||||
SYS_DISABLE | M0_ENABLE : SYS RST, for low-power reset or quick system reset;
|
||||
SYS_ENABLE | M0_DISABLE: M0 RST, only for m0 reset;
|
||||
SYS_DISABLE | M0_DISABLE: M0 RST, m0 reset and low-power reset;
|
||||
*/
|
||||
cpr_rstctl_wdtrst_mask_set(
|
||||
(WDT_SYS_RSTN_MASK_DISABLE | WDT_M0_RSTN_MASK_ENABLE));
|
||||
cpr_lp_ctl__wdt_pclk_sel__setf(wdt_cfg->PclkSel);
|
||||
cpr_lp_ctl__wdt_tclk_en__setf(ENABLE);
|
||||
|
||||
wdt_cr__wdt_rmod__setf(wdt_cfg->WorkMode);
|
||||
wdt_torr__wdt_top__setf(wdt_cfg->ReloadValue);
|
||||
reload_val = wdt_cfg->ReloadValue;
|
||||
}
|
||||
|
||||
void xc_wdt_start(void)
|
||||
{
|
||||
wdt_cr__wdt_rpl__setf(WDT_CR_RPL_4PCLK);
|
||||
wdt_cr__wdt_en__setf(ENABLE);
|
||||
wdt_crr__setf(WDT_CRR_CRR_ENABLE);
|
||||
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
|
||||
void xc_ext32k_wdt_init(WDT_InitCfg_t *wdt_cfg)
|
||||
{
|
||||
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
/*
|
||||
SYS_DISABLE | M0_ENABLE : SYS RST, for low-power reset or quick system reset;
|
||||
SYS_ENABLE | M0_DISABLE: M0 RST, only for m0 reset;
|
||||
SYS_DISABLE | M0_DISABLE: M0 RST, m0 reset and low-power reset;
|
||||
*/
|
||||
// cpr_rstctl_wdtrst_mask_set(
|
||||
// (WDT_SYS_RSTN_MASK_DISABLE | WDT_M0_RSTN_MASK_ENABLE));
|
||||
|
||||
cpr_rstctl_wdtrst_mask_set(
|
||||
(WDT_SYS_RSTN_MASK_ENABLE | WDT_M0_RSTN_MASK_DISABLE));
|
||||
cpr_lp_ctl__wdt_pclk_sel__setf(wdt_cfg->PclkSel);
|
||||
cpr_lp_ctl__wdt_tclk_en__setf(ENABLE);
|
||||
|
||||
wdt_cr__wdt_rmod__setf(wdt_cfg->WorkMode);
|
||||
wdt_torr__wdt_top__setf(wdt_cfg->ReloadValue);
|
||||
reload_val = wdt_cfg->ReloadValue;
|
||||
}
|
||||
|
||||
void xc_ext32k_wdt_start(void)
|
||||
{
|
||||
wdt_cr__wdt_rpl__setf(WDT_CR_RPL_4PCLK);
|
||||
wdt_cr__wdt_en__setf(ENABLE);
|
||||
wdt_crr__setf(WDT_CRR_CRR_ENABLE);
|
||||
}
|
||||
|
||||
void xc_wdt_stop(void)
|
||||
{
|
||||
wdt_cr__wdt_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
void xc_wdt_refresh(void)
|
||||
{
|
||||
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(ENABLE);
|
||||
uint8_t val = wdt_icr_get();
|
||||
|
||||
wdt_torr__wdt_top__setf(val);
|
||||
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
void xc_wdt_reload(void)
|
||||
{
|
||||
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(ENABLE);
|
||||
uint8_t val = wdt_icr_get();
|
||||
|
||||
wdt_torr__wdt_top__setf(reload_val);
|
||||
|
||||
wdt_crr__setf(WDT_CRR_CRR_ENABLE);
|
||||
cpr_ctlapbclken_grctl__wdt_pclk_en__setf(DISABLE);
|
||||
}
|
||||
|
||||
void WDT_Handler()
|
||||
{
|
||||
DEBUG("WDT_Handler\n");
|
||||
|
||||
#if XTAL_32K
|
||||
cprao_aon_ctl_clk32k_set(0x109);
|
||||
|
||||
WDT_InitCfg_t wdt_cfg ;
|
||||
|
||||
wdt_cfg.WorkMode = WDT_WORK_MODE0;
|
||||
wdt_cfg.ReloadValue = WDT_CLK_32M_RESET_MODE0_4096US;
|
||||
wdt_cfg.PclkSel = WDT_WORK_32M;
|
||||
xc_wdt_init(&wdt_cfg);
|
||||
xc_wdt_start();
|
||||
while(1);
|
||||
#endif
|
||||
xc_wdt_refresh();
|
||||
}
|
||||
|
||||
#endif //(WDT_ON)
|
||||
@@ -0,0 +1,287 @@
|
||||
/*!
|
||||
* \file xc6xxx_hal_wdt.h
|
||||
*
|
||||
* \brief The header of xc6xxx_hal_wdt.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC_DRV_WDT_H_
|
||||
#define __XC_DRV_WDT_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
|
||||
#define WDT_SYS_RSTN_MASK_DISABLE (0x00)
|
||||
#define WDT_SYS_RSTN_MASK_ENABLE (0x01)
|
||||
#define WDT_M0_RSTN_MASK_ENABLE (0x02)
|
||||
#define WDT_M0_RSTN_MASK_DISABLE (0x00)
|
||||
|
||||
#define WDT_CR_RPL_2PCLK (0UL)
|
||||
#define WDT_CR_RPL_4PCLK (1UL)
|
||||
#define WDT_CR_RPL_8PCLK (2UL)
|
||||
#define WDT_CR_RPL_16PCLK (3UL)
|
||||
#define WDT_CR_RPL_32PCLK (4UL)
|
||||
#define WDT_CR_RPL_64PCLK (5UL)
|
||||
#define WDT_CR_RPL_128PCLK (6UL)
|
||||
#define WDT_CR_RPL_256PCLK (7UL)
|
||||
|
||||
#define WDT_CRR_CRR_ENABLE (0x76UL)
|
||||
|
||||
|
||||
|
||||
#define WDT_CLK_32K_RESET_MODE0_2048MS 0x00
|
||||
#define WDT_CLK_32K_RESET_MODE0_4096MS 0x01
|
||||
#define WDT_CLK_32K_RESET_MODE0_8192MS 0x02
|
||||
#define WDT_CLK_32K_RESET_MODE0_16384MS 0x03
|
||||
#define WDT_CLK_32K_RESET_MODE0_32768MS 0x04
|
||||
#define WDT_CLK_32K_RESET_MODE0_65536MS 0x05
|
||||
#define WDT_CLK_32K_RESET_MODE0_131072MS 0x06
|
||||
#define WDT_CLK_32K_RESET_MODE0_262144MS 0x07
|
||||
#define WDT_CLK_32K_RESET_MODE0_524288MS 0x08
|
||||
#define WDT_CLK_32K_RESET_MODE0_1048576MS 0x09
|
||||
#define WDT_CLK_32K_RESET_MODE0_2097152MS 0x0a
|
||||
#define WDT_CLK_32K_RESET_MODE0_4194304MS 0x0b
|
||||
#define WDT_CLK_32K_RESET_MODE0_8388608MS 0x0c
|
||||
#define WDT_CLK_32K_RESET_MODE0_16777216MS 0x0d
|
||||
#define WDT_CLK_32K_RESET_MODE0_33554432MS 0x0e
|
||||
#define WDT_CLK_32K_RESET_MODE0_67108864MS 0x0f
|
||||
|
||||
#define WDT_CLK_16M_RESET_MODE0_8192US 0x00
|
||||
#define WDT_CLK_16M_RESET_MODE0_16384US 0x01
|
||||
#define WDT_CLK_16M_RESET_MODE0_32768US 0x02
|
||||
#define WDT_CLK_16M_RESET_MODE0_65536US 0x03
|
||||
#define WDT_CLK_16M_RESET_MODE0_131072US 0x04
|
||||
#define WDT_CLK_16M_RESET_MODE0_262144US 0x05
|
||||
#define WDT_CLK_16M_RESET_MODE0_524288US 0x06
|
||||
#define WDT_CLK_16M_RESET_MODE0_1048576US 0x07
|
||||
#define WDT_CLK_16M_RESET_MODE0_2097152US 0x08
|
||||
#define WDT_CLK_16M_RESET_MODE0_4194304US 0x09
|
||||
#define WDT_CLK_16M_RESET_MODE0_8388608US 0x0a
|
||||
#define WDT_CLK_16M_RESET_MODE0_16777216US 0x0b
|
||||
#define WDT_CLK_16M_RESET_MODE0_33554432US 0x0c
|
||||
#define WDT_CLK_16M_RESET_MODE0_67108864US 0x0d
|
||||
#define WDT_CLK_16M_RESET_MODE0_134217728US 0x0e
|
||||
#define WDT_CLK_16M_RESET_MODE0_268435456US 0x0f
|
||||
|
||||
#define WDT_CLK_32M_RESET_MODE0_4096US 0x00
|
||||
#define WDT_CLK_32M_RESET_MODE0_8192US 0x01
|
||||
#define WDT_CLK_32M_RESET_MODE0_16384US 0x02
|
||||
#define WDT_CLK_32M_RESET_MODE0_32768US 0x03
|
||||
#define WDT_CLK_32M_RESET_MODE0_65536US 0x04
|
||||
#define WDT_CLK_32M_RESET_MODE0_131072US 0x05
|
||||
#define WDT_CLK_32M_RESET_MODE0_262144US 0x06
|
||||
#define WDT_CLK_32M_RESET_MODE0_524288US 0x07
|
||||
#define WDT_CLK_32M_RESET_MODE0_1048576US 0x08
|
||||
#define WDT_CLK_32M_RESET_MODE0_2097152US 0x09
|
||||
#define WDT_CLK_32M_RESET_MODE0_4194304US 0x0a
|
||||
#define WDT_CLK_32M_RESET_MODE0_8388608US 0x0b
|
||||
#define WDT_CLK_32M_RESET_MODE0_16777216US 0x0c
|
||||
#define WDT_CLK_32M_RESET_MODE0_33554432US 0x0d
|
||||
#define WDT_CLK_32M_RESET_MODE0_67108864US 0x0e
|
||||
#define WDT_CLK_32M_RESET_MODE0_134217728US 0x0f
|
||||
|
||||
|
||||
#define WDT_CLK_48M_RESET_MODE0_2731US 0x00
|
||||
#define WDT_CLK_48M_RESET_MODE0_5461US 0x01
|
||||
#define WDT_CLK_48M_RESET_MODE0_10923US 0x02
|
||||
#define WDT_CLK_48M_RESET_MODE0_21845US 0x03
|
||||
#define WDT_CLK_48M_RESET_MODE0_43691US 0x04
|
||||
#define WDT_CLK_48M_RESET_MODE0_87381US 0x05
|
||||
#define WDT_CLK_48M_RESET_MODE0_174763US 0x06
|
||||
#define WDT_CLK_48M_RESET_MODE0_349525US 0x07
|
||||
#define WDT_CLK_48M_RESET_MODE0_699051US 0x08
|
||||
#define WDT_CLK_48M_RESET_MODE0_1398101US 0x09
|
||||
#define WDT_CLK_48M_RESET_MODE0_2796203US 0x0a
|
||||
#define WDT_CLK_48M_RESET_MODE0_5592405US 0x0b
|
||||
#define WDT_CLK_48M_RESET_MODE0_11184811US 0x0c
|
||||
#define WDT_CLK_48M_RESET_MODE0_22369621US 0x0d
|
||||
#define WDT_CLK_48M_RESET_MODE0_44739243US 0x0e
|
||||
#define WDT_CLK_48M_RESET_MODE0_89478485US 0x0f
|
||||
|
||||
#define WDT_CLK_64M_RESET_MDOE0_2048US 0x00
|
||||
#define WDT_CLK_64M_RESET_MDOE0_4096US 0x01
|
||||
#define WDT_CLK_64M_RESET_MDOE0_8192US 0x02
|
||||
#define WDT_CLK_64M_RESET_MDOE0_16384US 0x03
|
||||
#define WDT_CLK_64M_RESET_MDOE0_32768US 0x04
|
||||
#define WDT_CLK_64M_RESET_MDOE0_65536US 0x05
|
||||
#define WDT_CLK_64M_RESET_MDOE0_131072US 0x06
|
||||
#define WDT_CLK_64M_RESET_MDOE0_262144US 0x07
|
||||
#define WDT_CLK_64M_RESET_MDOE0_524288US 0x08
|
||||
#define WDT_CLK_64M_RESET_MDOE0_1048576US 0x09
|
||||
#define WDT_CLK_64M_RESET_MDOE0_2097152US 0x0a
|
||||
#define WDT_CLK_64M_RESET_MDOE0_4194304US 0x0b
|
||||
#define WDT_CLK_64M_RESET_MDOE0_8388608US 0x0c
|
||||
#define WDT_CLK_64M_RESET_MDOE0_16777216US 0x0d
|
||||
#define WDT_CLK_64M_RESET_MDOE0_33554432US 0x0e
|
||||
#define WDT_CLK_64M_RESET_MDOE0_67108864US 0x0f
|
||||
|
||||
|
||||
|
||||
#define WDT_CLK_32K_RESET_MODE1_4096MS 0x00
|
||||
#define WDT_CLK_32K_RESET_MODE1_8192MS 0x01
|
||||
#define WDT_CLK_32K_RESET_MODE1_16384MS 0x02
|
||||
#define WDT_CLK_32K_RESET_MODE1_32768MS 0x03
|
||||
#define WDT_CLK_32K_RESET_MODE1_65536MS 0x04
|
||||
#define WDT_CLK_32K_RESET_MODE1_131072MS 0x05
|
||||
#define WDT_CLK_32K_RESET_MODE1_262144MS 0x06
|
||||
#define WDT_CLK_32K_RESET_MODE1_524288MS 0x07
|
||||
#define WDT_CLK_32K_RESET_MODE1_1048576MS 0x08
|
||||
#define WDT_CLK_32K_RESET_MODE1_2097152MS 0x09
|
||||
#define WDT_CLK_32K_RESET_MODE1_4194304MS 0x0a
|
||||
#define WDT_CLK_32K_RESET_MODE1_8388608MS 0x0b
|
||||
#define WDT_CLK_32K_RESET_MODE1_16777216MS 0x0c
|
||||
#define WDT_CLK_32K_RESET_MODE1_33554432MS 0x0d
|
||||
#define WDT_CLK_32K_RESET_MODE1_67108864MS 0x0e
|
||||
#define WDT_CLK_32K_RESET_MODE1_134217728MS 0x0f
|
||||
|
||||
#define WDT_CLK_16M_RESET_MODE1_16384US 0x00
|
||||
#define WDT_CLK_16M_RESET_MODE1_32768US 0x01
|
||||
#define WDT_CLK_16M_RESET_MODE1_65536US 0x02
|
||||
#define WDT_CLK_16M_RESET_MODE1_131072US 0x03
|
||||
#define WDT_CLK_16M_RESET_MODE1_262144US 0x04
|
||||
#define WDT_CLK_16M_RESET_MODE1_524288US 0x05
|
||||
#define WDT_CLK_16M_RESET_MODE1_1048576US 0x06
|
||||
#define WDT_CLK_16M_RESET_MODE1_2097152US 0x07
|
||||
#define WDT_CLK_16M_RESET_MODE1_4194304US 0x08
|
||||
#define WDT_CLK_16M_RESET_MODE1_8388608US 0x09
|
||||
#define WDT_CLK_16M_RESET_MODE1_16777216US 0x0a
|
||||
#define WDT_CLK_16M_RESET_MODE1_33554432US 0x0b
|
||||
#define WDT_CLK_16M_RESET_MODE1_67108864US 0x0c
|
||||
#define WDT_CLK_16M_RESET_MODE1_134217728US 0x0d
|
||||
#define WDT_CLK_16M_RESET_MODE1_268435456US 0x0e
|
||||
#define WDT_CLK_16M_RESET_MODE1_536870912US 0x0f
|
||||
|
||||
#define WDT_CLK_32M_RESET_MODE1_8192US 0x00
|
||||
#define WDT_CLK_32M_RESET_MODE1_16384US 0x01
|
||||
#define WDT_CLK_32M_RESET_MODE1_32768US 0x02
|
||||
#define WDT_CLK_32M_RESET_MODE1_65536US 0x03
|
||||
#define WDT_CLK_32M_RESET_MODE1_131072US 0x04
|
||||
#define WDT_CLK_32M_RESET_MODE1_262144US 0x05
|
||||
#define WDT_CLK_32M_RESET_MODE1_524288US 0x06
|
||||
#define WDT_CLK_32M_RESET_MODE1_1048576US 0x07
|
||||
#define WDT_CLK_32M_RESET_MODE1_2097152US 0x08
|
||||
#define WDT_CLK_32M_RESET_MODE1_4194304US 0x09
|
||||
#define WDT_CLK_32M_RESET_MODE1_8388608US 0x0a
|
||||
#define WDT_CLK_32M_RESET_MODE1_16777216US 0x0b
|
||||
#define WDT_CLK_32M_RESET_MODE1_33554432US 0x0c
|
||||
#define WDT_CLK_32M_RESET_MODE1_67108864US 0x0d
|
||||
#define WDT_CLK_32M_RESET_MODE1_134217728US 0x0e
|
||||
#define WDT_CLK_32M_RESET_MODE1_268435456US 0x0f
|
||||
|
||||
#define WDT_CLK_48M_RESET_MODE1_5461US 0x00
|
||||
#define WDT_CLK_48M_RESET_MODE1_10923US 0x01
|
||||
#define WDT_CLK_48M_RESET_MODE1_21845US 0x02
|
||||
#define WDT_CLK_48M_RESET_MODE1_43691US 0x03
|
||||
#define WDT_CLK_48M_RESET_MODE1_87381US 0x04
|
||||
#define WDT_CLK_48M_RESET_MODE1_174763US 0x05
|
||||
#define WDT_CLK_48M_RESET_MODE1_349525US 0x06
|
||||
#define WDT_CLK_48M_RESET_MODE1_699051US 0x07
|
||||
#define WDT_CLK_48M_RESET_MODE1_1398101US 0x08
|
||||
#define WDT_CLK_48M_RESET_MODE1_2796203US 0x09
|
||||
#define WDT_CLK_48M_RESET_MODE1_5592405US 0x0a
|
||||
#define WDT_CLK_48M_RESET_MODE1_11184811US 0x0b
|
||||
#define WDT_CLK_48M_RESET_MODE1_22369621US 0x0c
|
||||
#define WDT_CLK_48M_RESET_MODE1_44739243US 0x0d
|
||||
#define WDT_CLK_48M_RESET_MODE1_89478485US 0x0e
|
||||
#define WDT_CLK_48M_RESET_MODE1_178956971US 0x0f
|
||||
|
||||
#define WDT_CLK_64M_RESET_MODE1_4096US 0x00
|
||||
#define WDT_CLK_64M_RESET_MODE1_8192US 0x01
|
||||
#define WDT_CLK_64M_RESET_MODE1_16384US 0x02
|
||||
#define WDT_CLK_64M_RESET_MODE1_32768US 0x03
|
||||
#define WDT_CLK_64M_RESET_MODE1_65536US 0x04
|
||||
#define WDT_CLK_64M_RESET_MODE1_131072US 0x05
|
||||
#define WDT_CLK_64M_RESET_MODE1_262144US 0x06
|
||||
#define WDT_CLK_64M_RESET_MODE1_524288US 0x07
|
||||
#define WDT_CLK_64M_RESET_MODE1_1048576US 0x08
|
||||
#define WDT_CLK_64M_RESET_MODE1_2097152US 0x09
|
||||
#define WDT_CLK_64M_RESET_MODE1_4194304US 0x0a
|
||||
#define WDT_CLK_64M_RESET_MODE1_8388608US 0x0b
|
||||
#define WDT_CLK_64M_RESET_MODE1_16777216US 0x0c
|
||||
#define WDT_CLK_64M_RESET_MODE1_33554432US 0x0d
|
||||
#define WDT_CLK_64M_RESET_MODE1_67108864US 0x0e
|
||||
#define WDT_CLK_64M_RESET_MODE1_134217728US 0x0f
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WDT_WORK_MODE0,
|
||||
WDT_WORK_MODE1
|
||||
} WDT_WorkModeTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WDT_ReloadValue_0xFFFF = 0,
|
||||
WDT_ReloadValue_0x1FFFF,
|
||||
WDT_ReloadValue_0x3FFFF,
|
||||
WDT_ReloadValue_0x7FFFF,
|
||||
WDT_ReloadValue_0xFFFFF, // In xip mode with external 32k crystal
|
||||
// oscillator, watchdog reset value can only
|
||||
// start from here
|
||||
WDT_ReloadValue_0x1FFFFF,
|
||||
WDT_ReloadValue_0x3FFFFF,
|
||||
WDT_ReloadValue_0x7FFFFF,
|
||||
WDT_ReloadValue_0xFFFFFF,
|
||||
WDT_ReloadValue_0x1FFFFFF,
|
||||
WDT_ReloadValue_0x3FFFFFF,
|
||||
WDT_ReloadValue_0x7FFFFFF,
|
||||
WDT_ReloadValue_0xFFFFFFF,
|
||||
WDT_ReloadValue_0x1FFFFFFF,
|
||||
WDT_ReloadValue_0x3FFFFFFF,
|
||||
WDT_ReloadValue_0x7FFFFFFF,
|
||||
|
||||
} WDT_ReloadValueTypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WDT_WORK_32M,
|
||||
WDT_WORK_32K,
|
||||
} WDT_WorkSrcTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WDT_ReloadValueTypeDef ReloadValue;
|
||||
WDT_WorkModeTypeDef WorkMode;
|
||||
WDT_WorkSrcTypeDef PclkSel;
|
||||
} WDT_InitCfg_t;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
void xc_wdt_init(WDT_InitCfg_t *WDT_InitStruct);
|
||||
void xc_wdt_start(void);
|
||||
void xc_wdt_stop(void);
|
||||
void xc_wdt_refresh(void);
|
||||
void xc_wdt_reload(void);
|
||||
|
||||
#endif /* __XC6xxx_HAL_WDT_H_ */
|
||||
Reference in New Issue
Block a user