-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #108 from dong-0412/develop
FreeRTOS adc pwm spi
- Loading branch information
Showing
6 changed files
with
850 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#include "drv_adc.h" | ||
#include "mmio.h" | ||
#include "FreeRTOS.h" | ||
#include "task.h" | ||
|
||
static struct cvi_adc_dev adc_dev_config[] = | ||
{ | ||
{ | ||
.name = "adc1", | ||
.base = SARADC_BASE, | ||
.active_channel = 0, | ||
}, | ||
}; | ||
|
||
// Configure SARADC control register | ||
void cvi_set_saradc_ctrl(uint32_t reg_base, uint32_t value) | ||
{ | ||
value |= mmio_read_32(reg_base + SARADC_CTRL_OFFSET); | ||
mmio_write_32(reg_base + SARADC_CTRL_OFFSET, value); | ||
} | ||
|
||
// Reset SARADC control register | ||
void cvi_reset_saradc_ctrl(uint32_t reg_base, uint32_t value) | ||
{ | ||
value = mmio_read_32(reg_base + SARADC_CTRL_OFFSET) & ~value; | ||
mmio_write_32(reg_base + SARADC_CTRL_OFFSET, value); | ||
} | ||
|
||
// Get SARADC status | ||
uint32_t cvi_get_saradc_status(uint32_t reg_base) | ||
{ | ||
return mmio_read_32(reg_base + SARADC_STATUS_OFFSET); | ||
} | ||
|
||
// Set SARADC clock cycle | ||
void cvi_set_cyc(uint32_t reg_base) | ||
{ | ||
uint32_t value = mmio_read_32(reg_base + SARADC_CYC_SET_OFFSET); | ||
value &= ~SARADC_CYC_CLKDIV_DIV_16; | ||
mmio_write_32(reg_base + SARADC_CYC_SET_OFFSET, value); | ||
value |= SARADC_CYC_CLKDIV_DIV_16; | ||
mmio_write_32(reg_base + SARADC_CYC_SET_OFFSET, value); | ||
} | ||
|
||
// Enable or disable ADC | ||
int adc_enabled(struct cvi_adc_dev *adc_dev, uint32_t channel, uint8_t enabled) | ||
{ | ||
if (channel > SARADC_CH_MAX) | ||
return 1; | ||
|
||
if (enabled) | ||
{ | ||
cvi_set_saradc_ctrl(adc_dev->base, channel << (SARADC_CTRL_SEL_POS+1)); | ||
cvi_set_cyc(adc_dev->base); | ||
cvi_set_saradc_ctrl(adc_dev->base, SARADC_CTRL_START); | ||
} | ||
else | ||
{ | ||
cvi_reset_saradc_ctrl(adc_dev->base, channel << (SARADC_CTRL_SEL_POS+1)); | ||
} | ||
return 0; | ||
} | ||
|
||
// Perform an ADC conversion | ||
int adc_convert(struct cvi_adc_dev *adc_dev, uint32_t channel, uint32_t *value) | ||
{ | ||
uint32_t result; | ||
uint32_t start_time = xTaskGetTickCount(); | ||
|
||
if (channel > SARADC_CH_MAX) | ||
return -1; // 错误码定义为 -1 | ||
|
||
while (cvi_get_saradc_status(adc_dev->base) & SARADC_STATUS_BUSY) | ||
{ | ||
if ((xTaskGetTickCount() - start_time) > pdMS_TO_TICKS(ADC_TIMEOUT_MS)) | ||
return -2; // 超时错误码定义为 -2 | ||
|
||
vTaskDelay(pdMS_TO_TICKS(10)); | ||
} | ||
|
||
result = mmio_read_32(adc_dev->base + SARADC_RESULT(channel - 1)); | ||
if (result & SARADC_RESULT_VALID) | ||
{ | ||
*value = result & SARADC_RESULT_MASK; | ||
} | ||
else | ||
{ | ||
return -3; // 无效结果错误码定义为 -3 | ||
} | ||
return 0; | ||
} | ||
|
||
int adc_sample(uint8_t adc_id, uint32_t channel, uint32_t *value) | ||
{ | ||
if (adc_id >= sizeof(adc_dev_config) / sizeof(adc_dev_config[0])) | ||
return -1; // ADC设备ID越界 | ||
|
||
struct cvi_adc_dev *adc_dev = &adc_dev_config[adc_id]; | ||
adc_dev->active_channel = channel; | ||
|
||
int ret = adc_enabled(adc_dev, adc_dev->active_channel, 1); | ||
if (ret != 0) { | ||
return ret; // 启用ADC失败 | ||
} | ||
|
||
ret = adc_convert(adc_dev, adc_dev->active_channel, value); | ||
adc_enabled(adc_dev, adc_dev->active_channel, 0); // 确保停用ADC,忽略返回值 | ||
|
||
return ret; // 返回转换结果 | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef __DRV_ADC_H__ | ||
#define __DRV_ADC_H__ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
#define SARADC_BASE 0x030F0000 | ||
#define SARADC_CH_MAX 3 | ||
|
||
#define SARADC_CTRL_OFFSET 0x04 | ||
#define SARADC_CTRL_START (1 << 0) | ||
#define SARADC_CTRL_SEL_POS 0x04 | ||
|
||
#define SARADC_STATUS_OFFSET 0x08 | ||
#define SARADC_STATUS_BUSY (1 << 0) | ||
|
||
#define SARADC_CYC_SET_OFFSET 0x0C | ||
#define SARADC_CYC_CLKDIV_DIV_POS (12U) | ||
#define SARADC_CYC_CLKDIV_DIV_MASK (0xF << SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_1 (0U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_2 (1U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_3 (2U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_4 (3U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_5 (4U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_6 (5U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_7 (6U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_8 (7U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_9 (8U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_10 (9U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_11 (10U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_12 (11U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_13 (12U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_14 (13U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_15 (14U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
#define SARADC_CYC_CLKDIV_DIV_16 (15U<< SARADC_CYC_CLKDIV_DIV_POS) | ||
|
||
#define SARADC_RESULT_OFFSET 0x014 | ||
#define SARADC_RESULT(n) (SARADC_RESULT_OFFSET + (n) * 4) | ||
#define SARADC_RESULT_MASK 0x0FFF | ||
#define SARADC_RESULT_VALID (1 << 15) | ||
|
||
#define SARADC_INTR_EN_OFFSET 0x020 //bit0: interrupt enable, RW | ||
|
||
#define SARADC_INTR_CLR_OFFSET 0x024 //bit0: interrupt clear, RWC | ||
|
||
#define SARADC_INTR_STA_OFFSET 0x028 //bit0: interrup masked status, RO,[0]:all channels measurenment in this time is finished | ||
|
||
#define SARADC_INTR_RAW_OFFSET 0x02C //bit 0: interrupt raw status, RO,[0]:all channels measurenment in this time is finished | ||
|
||
#define ADC_DATA_QUEUE_LENGTH 10 | ||
#define ADC_INTR 116 | ||
|
||
#define ADC_TIMEOUT_MS 1000 // 超时时间定义为1000毫秒 | ||
|
||
// ADC device structure | ||
struct cvi_adc_dev | ||
{ | ||
const char *name; | ||
uint32_t base; | ||
uint32_t active_channel; | ||
}; | ||
|
||
int adc_sample(uint8_t adc_id, uint32_t channel, uint32_t *value); | ||
|
||
#endif // __DRV_ADC_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
// #include "FreeRTOS.h" | ||
// #include "task.h" | ||
// #include "semphr.h" | ||
#include "drv_pwm.h" | ||
|
||
|
||
struct cvi_pwm_dev | ||
{ | ||
const char *name; | ||
uint32_t reg_base; | ||
}; | ||
|
||
static const uint64_t count_unit = 100000000; // 100M count per second | ||
static const uint64_t NSEC_COUNT = 1000000000; // ns | ||
|
||
static void cvi_pwm_set_config(uint32_t reg_base, struct pwm_configuration *cfg) | ||
{ | ||
uint64_t duty_clk, period_clk; | ||
|
||
cvi_pwm_set_polarity_high_ch(reg_base, (cfg->channel & PWM_MAX_CH)); | ||
|
||
duty_clk = (cfg->pulse * count_unit) / NSEC_COUNT; | ||
cvi_pwm_set_high_period_ch(reg_base, (cfg->channel & PWM_MAX_CH), duty_clk); | ||
|
||
period_clk = (cfg->period * count_unit) / NSEC_COUNT; | ||
cvi_pwm_set_period_ch(reg_base, (cfg->channel & PWM_MAX_CH), period_clk); | ||
|
||
cvi_pwm_output_en_ch(reg_base, cfg->channel & PWM_MAX_CH); | ||
} | ||
|
||
// 定义 PWM 设备 | ||
static struct cvi_pwm_dev cvi_pwm[] = | ||
{ | ||
{ | ||
.name = "pwm0", | ||
.reg_base = CVI_PWM0_BASE, | ||
}, | ||
{ | ||
.name = "pwm1", | ||
.reg_base = CVI_PWM1_BASE, | ||
}, | ||
{ | ||
.name = "pwm2", | ||
.reg_base = CVI_PWM2_BASE, | ||
}, | ||
{ | ||
.name = "pwm3", | ||
.reg_base = CVI_PWM3_BASE, | ||
}, | ||
}; | ||
|
||
void pwm_init(uint8_t pwm_id, struct pwm_configuration *cfg) | ||
{ | ||
cvi_pwm_set_config(cvi_pwm[pwm_id].reg_base, cfg); | ||
} |
Oops, something went wrong.