当前位置: 首页 > news >正文

【驱动篇】龙芯LS2K0300之ADC驱动

实验目的

由于LS2K0300久久派开发板4.19内核还没有现成可用的ADC驱动,但是龙芯官方的5.10内核已经提供了ADC驱动,想要在4.19内核使用ADC就要参考5.10内核移植驱动,本次实验主要是关于ADC驱动的移植和使用

驱动移植

主要的驱动代码主要有3个:loongson-2k300-adc.c、loongson-2k300-adc-core.c、loongson-2k300-adc-core.h,位于drivers/iio/adc目录下

loongson-2k300-adc.c

这个是platform_driver代码部分

#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/delay.h>
#include "loongson-2k300-adc-core.h"#define ADC_DATA_MASK 0x0FFF#define ADC_MAX_VOLTAGE 1800
#define ADC_SCALE 4096struct ls2k300_adc_data {void __iomem *base;spinlock_t read_raw_lock; // 添加读取的自旋锁 扫描模式,单次读取时使用
};// 这里是有节点可以读取的关键
#define LS2K300_CHANNEL(num) { \.type = IIO_VOLTAGE, \.indexed = 1, \.channel = num, \.address = ADC_DR, \.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \.scan_index = num, \.scan_type = { \.sign = 's', \.realbits = 12, \.storagebits = 16, \.shift = 12, \.endianness = IIO_CPU, \}, \
}static const struct iio_chan_spec ls2k300_adc_channels[] = {IIO_CHAN_SOFT_TIMESTAMP(8),LS2K300_CHANNEL(0),LS2K300_CHANNEL(1),LS2K300_CHANNEL(2),LS2K300_CHANNEL(3),LS2K300_CHANNEL(4),LS2K300_CHANNEL(5),LS2K300_CHANNEL(6),LS2K300_CHANNEL(7),// 注入通道// { .type = IIO_VOLTAGE, .differential = 1, .channel = 0, .address = ADC_JDR1 },// { .type = IIO_VOLTAGE, .differential = 1, .channel = 1, .address = ADC_JDR2 },// { .type = IIO_VOLTAGE, .differential = 1, .channel = 2, .address = ADC_JDR3 },// { .type = IIO_VOLTAGE, .differential = 1, .channel = 3, .address = ADC_JDR4 },
};// sysfs 下的节点读取时的具体调用函数
static int ls2k300_adc_read_raw(struct iio_dev *indio_dev,struct iio_chan_spec const *chan,int *val, int *val2, long mask)
{struct ls2k300_adc_data *data = iio_priv(indio_dev);unsigned int reg_offset;unsigned long flags;switch (mask) {case IIO_CHAN_INFO_RAW:// 针对 in_voltagex_raw 节点if (chan->differential) {reg_offset = chan->address;} else {reg_offset = chan->address;}// 由于规则通道组只有一个通道,所以这里需要用锁来限定一段时间只能读取一个通道的值。spin_lock_irqsave(&data->read_raw_lock, flags);ADC_RegularChannelConfig(data->base, chan->channel, 1, ADC_SampleTime_64Cycles);adc_software_start_conv_trigger(data->base, ENABLE, 0);adc_eoc_check_conv_end(data->base);*val = ioread16(data->base + reg_offset) & ADC_DATA_MASK;spin_unlock_irqrestore(&data->read_raw_lock, flags);return IIO_VAL_INT;case IIO_CHAN_INFO_SCALE:// 针对 in_voltagex_scale 节点*val = ADC_MAX_VOLTAGE;*val2 = ADC_SCALE;// 返回的值就是 val1 / val2 的那个小数值// scale * raw 就是对应的电压值,单位mVreturn IIO_VAL_FRACTIONAL;default:return -EINVAL;}
}static const struct iio_info ls2k300_adc_info = {.read_raw = ls2k300_adc_read_raw,
};static int ls2k300_adc_probe(struct platform_device *pdev)
{adc_init_info adc_init_struct;struct iio_dev *indio_dev;struct ls2k300_adc_data *data;struct resource *res;int ret;indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));if (!indio_dev) {dev_err(&pdev->dev, "devm_iio_device_alloc failed! probe failed!\n");return -ENOMEM;}data = iio_priv(indio_dev);res = platform_get_resource(pdev, IORESOURCE_MEM, 0);data->base = devm_ioremap_resource(&pdev->dev, res);if (IS_ERR(data->base)) {dev_err(&pdev->dev, "devm_ioremap_resource failed! probe failed! (base: %.llx)\n", (unsigned long long)data->base);return PTR_ERR(data->base);}// 配置 ADC CR1 和 CR2 等寄存器,具体配置根据需要调整// 不使用 DMA, 扫描模式, 单次,规则序列转化数为1, 也就是每次都等待读取完毕。// EOC中断和JEOC中断没开adc_struct_init(&adc_init_struct);adc_init_struct.ADC_Mode = ADC_Mode_Independent;adc_init_struct.ADC_ScanConvMode = ENABLE;adc_init_struct.ADC_ContinuousConvMode = DISABLE;adc_init_struct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;adc_init_struct.ADC_DataAlign = ADC_DataAlign_Right;adc_init_struct.ADC_NbrOfChannel = 1; //规则通道数量 为 1,这是一个一个的触发 扫描模式的单次扫描adc_init_struct.ADC_ClkDivider = 1;  //Loongson Featureadc_init_struct.ADC_JTrigMod = 0;    //Loongson Featureadc_init_struct.ADC_ADCEdge = 0;     //Loongson Featureadc_init_struct.ADC_DiffMod = 0;     //Loongson Featureadc_init(data->base, &adc_init_struct);adc_dev_enable(data->base, ENABLE);// iio 框架信息注册indio_dev->dev.parent = &pdev->dev;indio_dev->info = &ls2k300_adc_info;indio_dev->name = pdev->name;indio_dev->modes = INDIO_DIRECT_MODE;indio_dev->channels = ls2k300_adc_channels;indio_dev->num_channels = ARRAY_SIZE(ls2k300_adc_channels);spin_lock_init(&data->read_raw_lock); // 初始化自旋锁ret = iio_device_register(indio_dev);if (ret) {dev_err(&pdev->dev, "iio_device_register failed! probe failed! (ret: %d)\n", ret);return ret;}platform_set_drvdata(pdev, indio_dev);dev_info(&pdev->dev, "ADC Device registered successfully\n");return 0;
}static int ls2k300_adc_remove(struct platform_device *pdev)
{struct iio_dev *indio_dev = platform_get_drvdata(pdev);iio_device_unregister(indio_dev);return 0;
}static const struct of_device_id ls2k300_adc_of_match[] = {{ .compatible = "ls2k300-adc", },{ }
};
MODULE_DEVICE_TABLE(of, ls2k300_adc_of_match);static struct platform_driver ls2k300_adc_driver = {.driver = {.name = "ls2k300_adc",.of_match_table = ls2k300_adc_of_match,},.probe = ls2k300_adc_probe,.remove = ls2k300_adc_remove,
};
module_platform_driver(ls2k300_adc_driver);MODULE_AUTHOR("oujintao qujintao@loongson.cn");
MODULE_DESCRIPTION("2k300 ADC IIO driver");
MODULE_LICENSE("GPL");

loongson-2k300-adc-core.c

这个是关于ADC的操作部分驱动代码:主要是读写寄存器

#include <linux/module.h>
#include <linux/delay.h>
#include "loongson-2k300-adc-core.h"#define ADC_DATA_MASK       0x0FFF/*******************************************************************************
* Function Name  : adc_init
* Description    : Initializes the ADCx peripheral according to the specified parameters
*                  in the ADC_InitStruct.
* Input          : - ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
*                  - ADC_InitStruct: pointer to an adc_init_info structure that
*                    contains the configuration information for the specified
*                    ADC peripheral.
* Output         : None
* Return         : None
******************************************************************************/
void adc_init(adc_reg_map* ADCx, adc_init_info* ADC_InitStruct)
{unsigned int temp_val_1 = 0;unsigned int temp_val_2 = 0;/*---------------------------- ADCx CR1 Configuration -----------------*//* Get the ADCx CR1 value */temp_val_1 = ADCx->CR1;/* Clear DUALMOD and SCAN bits */temp_val_1 &= CR1_CLEAR_MASK;/* Configure ADCx: Dual mode and scan conversion mode *//* Set DUALMOD bits according to ADC_Mode value *//* Set SCAN bit according to ADC_ScanConvMode value */temp_val_1 |= (unsigned int)(ADC_InitStruct->ADC_Mode | ((unsigned int)ADC_InitStruct->ADC_ScanConvMode << 8) |((unsigned int)((ADC_InitStruct->ADC_ClkDivider)&0x3f) << 24)  |((unsigned int)ADC_InitStruct->ADC_DiffMod << 20) |((unsigned int)ADC_InitStruct->ADC_OutPhaseSel << 30)); //ygtemp_val_1 |= 1 << CR1_EOC_IE_OFFSET;temp_val_1 ^= 1 << CR1_EOC_IE_OFFSET;temp_val_1 |= ADC_InitStruct->ADC_Int_EOC << CR1_EOC_IE_OFFSET;temp_val_1 |= 1 << CR1_J_EOC_IE_OFFSET;temp_val_1 ^= 1 << CR1_J_EOC_IE_OFFSET;temp_val_1 |= ADC_InitStruct->ADC_Int_JEOC << CR1_J_EOC_IE_OFFSET;/* Write to ADCx CR1 */ADCx->CR1 = temp_val_1;/*---------------------------- ADCx CR2 Configuration -----------------*//* Get the ADCx CR2 value */temp_val_1 = ADCx->CR2;/* Clear CONT, ALIGN and EXTSEL bits */temp_val_1 &= CR2_CLEAR_MASK;/* Configure ADCx: external trigger event and continuous conversion mode *//* Set ALIGN bit according to ADC_DataAlign value *//* Set EXTSEL bits according to ADC_ExternalTrigConv value *//* Set CONT bit according to ADC_ContinuousConvMode value */temp_val_1 |= (unsigned int)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv |((unsigned int)ADC_InitStruct->ADC_ContinuousConvMode << 1) |((unsigned int)ADC_InitStruct->ADC_JTrigMod << 24) | //yg((unsigned int)(((ADC_InitStruct->ADC_ClkDivider)>>6)&0xf) << 26)  |((unsigned int)ADC_InitStruct->ADC_ADCEdge << 30)  |((unsigned int)ADC_InitStruct->ADC_ClkMask << 31)) ; //yg/* Write to ADCx CR2 */ADCx->CR2 = temp_val_1;/*---------------------------- ADCx SQR1 Configuration -----------------*//* Get the ADCx SQR1 value */temp_val_1 = ADCx->SQR1;/* Clear L bits */temp_val_1 &= SQR1_CLEAR_MASK;/* Configure ADCx: regular channel sequence length *//* Set L bits according to ADC_NbrOfChannel value */temp_val_2 |= (ADC_InitStruct->ADC_NbrOfChannel - 1);temp_val_1 |= ((unsigned int)temp_val_2 << 20);/* Write to ADCx SQR1 */ADCx->SQR1 = temp_val_1;
}/*******************************************************************************
* Function Name  : adc_struct_init
* Description    : Fills each ADC_InitStruct member with its default value.
* Input          : ADC_InitStruct : pointer to an adc_init_info structure
*                  which will be initialized.
* Output         : None
* Return         : None
*******************************************************************************/
void adc_struct_init(adc_init_info* ADC_InitStruct)
{/* Reset ADC init structure parameters values *//* Initialize the ADC_Mode member */ADC_InitStruct->ADC_Mode = ADC_Mode_Independent;/* initialize the ADC_ScanConvMode member */ADC_InitStruct->ADC_ScanConvMode = DISABLE;/* Initialize the ADC_ContinuousConvMode member */ADC_InitStruct->ADC_ContinuousConvMode = DISABLE;/* Initialize the ADC_ExternalTrigConv member */ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;/* Initialize the ADC_DataAlign member */ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right;/* Initialize the ADC_NbrOfChannel member */ADC_InitStruct->ADC_NbrOfChannel = 1;/* Initialize the ADC_ClkDivider member */ADC_InitStruct->ADC_ClkDivider = 0xff;/* Initialize the ADC_JTrigMod member */ADC_InitStruct->ADC_JTrigMod = 0;/* Initialize the ADC_ADCEdge member */ADC_InitStruct->ADC_ADCEdge = 0;/* Initialize the ADC_DIFFMOD member */ADC_InitStruct->ADC_DiffMod = 0;/* Initialize the ADC_OutPhaseSel member */ADC_InitStruct->ADC_OutPhaseSel = 0;/* Initialize the ADC_ClkMask member */ADC_InitStruct->ADC_ClkMask = 0;/* Initialize CR1 EOC disable */ADC_InitStruct->ADC_Int_EOC = DISABLE;/* Initialize CR1 EOC disable */ADC_InitStruct->ADC_Int_JEOC = DISABLE;
}void ADC_RegularChannelConfig(adc_reg_map* ADCx, unsigned char ADC_Channel, unsigned char Rank, unsigned char ADC_SampleTime)
{unsigned int temp_val_1 = 0, temp_val_2 = 0;/* if ADC_Channel_10 ... ADC_Channel_17 is selected */if (ADC_Channel > ADC_Channel_9) {/* Get the old register value */temp_val_1 = ADCx->SMPR1;/* Calculate the mask to clear */temp_val_2 = SMPR1_SMP_MASK << (3 * (ADC_Channel - 10));/* Clear the old discontinuous mode channel count */temp_val_1 &= ~temp_val_2;/* Calculate the mask to set */temp_val_2 = (unsigned int)ADC_SampleTime << (3 * (ADC_Channel - 10));/* Set the discontinuous mode channel count */temp_val_1 |= temp_val_2;/* Store the new register value */ADCx->SMPR1 = temp_val_1;} else { /* ADC_Channel include in ADC_Channel_[0..9] *//* Get the old register value */temp_val_1 = ADCx->SMPR2;/* Calculate the mask to clear */temp_val_2 = SMPR2_SMP_MASK << (3 * ADC_Channel);/* Clear the old discontinuous mode channel count */temp_val_1 &= ~temp_val_2;/* Calculate the mask to set */temp_val_2 = (unsigned int)ADC_SampleTime << (3 * ADC_Channel);/* Set the discontinuous mode channel count */temp_val_1 |= temp_val_2;/* Store the new register value */ADCx->SMPR2 = temp_val_1;}/* For Rank 1 to 6 */if (Rank < 7) {/* Get the old register value */temp_val_1 = ADCx->SQR3;/* Calculate the mask to clear */temp_val_2 = SQR3_SQ_MASK << (5 * (Rank - 1));/* Clear the old SQx bits for the selected rank */temp_val_1 &= ~temp_val_2;/* Calculate the mask to set */temp_val_2 = (unsigned int)ADC_Channel << (5 * (Rank - 1));/* Set the SQx bits for the selected rank */temp_val_1 |= temp_val_2;/* Store the new register value */ADCx->SQR3 = temp_val_1;} else if (Rank < 13) { /* For Rank 7 to 12 *//* Get the old register value */temp_val_1 = ADCx->SQR2;/* Calculate the mask to clear */temp_val_2 = SQR2_SQ_MASK << (5 * (Rank - 7));/* Clear the old SQx bits for the selected rank */temp_val_1 &= ~temp_val_2;/* Calculate the mask to set */temp_val_2 = (unsigned int)ADC_Channel << (5 * (Rank - 7));/* Set the SQx bits for the selected rank */temp_val_1 |= temp_val_2;/* Store the new register value */ADCx->SQR2 = temp_val_1;} else { /* For Rank 13 to 16 *//* Get the old register value */temp_val_1 = ADCx->SQR1;/* Calculate the mask to clear */temp_val_2 = SQR1_SQ_MASK << (5 * (Rank - 13));/* Clear the old SQx bits for the selected rank */temp_val_1 &= ~temp_val_2;/* Calculate the mask to set */temp_val_2 = (unsigned int)ADC_Channel << (5 * (Rank - 13));/* Set the SQx bits for the selected rank */temp_val_1 |= temp_val_2;/* Store the new register value */ADCx->SQR1 = temp_val_1;}
}/*******************************************************************************
* Function Name  : adc_dev_enable
* Description    : Enables or disables the specified ADC peripheral.
* Input          : - ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
*                  - state: new state of the ADCx peripheral. This parameter
*                    can be: ENABLE or DISABLE.
* Output         : None
* Return         : None
*******************************************************************************/
void adc_dev_enable(adc_reg_map* ADCx, FunctionalState state)
{unsigned int temp;if (state == ENABLE) {temp = ADCx->CR2;temp |= 1 << CR2_ADON_OFFSET;temp ^= 1 << CR2_ADON_OFFSET;temp |= (state << CR2_ADON_OFFSET);ADCx->CR2 = temp;// 触发复位校准和AD校准ADCx->CR2 = temp;temp = ADCx->CR2;temp |= (state << 2) | (state << 3);ADCx->CR2 = temp;
#if 0while (1) {temp = ADCx->CR2;temp &= 1 << 2;if (!temp)break;}
#elsendelay(1000000);
#endif} else {temp = ADCx->CR2;temp |= 1 << CR2_ADON_OFFSET;temp ^= 1 << CR2_ADON_OFFSET;ADCx->CR2 = temp;}
}/*******************************************************************************
* Function Name  : adc_software_start_conv_trigger
* Description    : Enables or disables the selected ADC software start conversion .
* Input          : - ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
*                  - state: new state of the selected ADC software start conversion.
*                    This parameter can be: ENABLE or DISABLE.
* Output         : None
* Return         : None
*******************************************************************************/
void adc_software_start_conv_trigger(adc_reg_map* ADCx, FunctionalState state, unsigned char J_channel)
{unsigned int temp;unsigned char EOC_offset;unsigned char start_offset;unsigned char exttrig_offset;EOC_offset = J_channel ? SR_J_EOC_OFFSET : SR_EOC_OFFSET;start_offset = J_channel ? CR2_EXTTRIG_SW_J_START_OFFSET : CR2_EXTTRIG_SW_START_OFFSET;exttrig_offset = J_channel ? CR2_J_EXTTRIG_OFFSET : CR2_EXTTRIG_OFFSET;if (state == ENABLE) {temp = ADCx->CR2;temp |= 1 << exttrig_offset;ADCx->CR2 = temp;// 先把 EOC 清除temp = ADCx->SR;temp |= 1 << EOC_offset;temp ^= 1 << EOC_offset;ADCx->SR = temp;ADCx->CR2 |= 1 << start_offset;} else {/* Disable the selected ADC conversion on external event and stop the selected ADC conversion */temp = ADCx->CR2;temp |= 1 << start_offset;temp ^= 1 << start_offset;ADCx->CR2 = temp;}
}void adc_eoc_check_conv_end(adc_reg_map* ADCx)
{int max_loop;unsigned int temp;max_loop = 0;while (1) {temp = ADCx->SR;temp &= 1 << 1;ndelay(10);++max_loop;if (temp == 2)break;if (max_loop == 10000) {pr_info("adc_eoc_check_conv_end eoc wait timeout\n");break;}}
}

loongson-2k300-adc-core.h

头文件部分:主要是定义一些ADC相关的寄存器宏和结构体

#ifndef __LOONGSON_2K300_ADC_CORE_H__
#define __LOONGSON_2K300_ADC_CORE_H__typedef enum FunctionalState {DISABLE = 0,ENABLE,
} FunctionalState;// ADC register offsets
#define ADC_SR              0x00
#define ADC_CR1             0x04
#define ADC_CR2             0x08
#define ADC_SMPR1           0x0C
#define ADC_SMPR2           0x10
#define ADC_JOFR1           0x14
#define ADC_JOFR2           0x18
#define ADC_JOFR3           0x1C
#define ADC_JOFR4           0x20
#define ADC_HTR             0x24
#define ADC_LTR             0x28
#define ADC_SQR1            0x2C
#define ADC_SQR2            0x30
#define ADC_SQR3            0x34
#define ADC_JSQR            0x38
#define ADC_JDR1            0x3C
#define ADC_JDR2            0x40
#define ADC_JDR3            0x44
#define ADC_JDR4            0x48
#define ADC_DR              0x4Ctypedef struct
{volatile unsigned int SR;volatile unsigned int CR1;volatile unsigned int CR2;volatile unsigned int SMPR1;volatile unsigned int SMPR2;volatile unsigned int JOFR1;volatile unsigned int JOFR2;volatile unsigned int JOFR3;volatile unsigned int JOFR4;volatile unsigned int HTR;volatile unsigned int LTR;volatile unsigned int SQR1;volatile unsigned int SQR2;volatile unsigned int SQR3;volatile unsigned int JSQR;volatile unsigned int JDR1;volatile unsigned int JDR2;volatile unsigned int JDR3;volatile unsigned int JDR4;volatile unsigned int DR;
} adc_reg_map;/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name          : stm32f10x_adc.h
* Author             : MCD Application Team
* Version            : V2.0.3
* Date               : 09/22/2008
* Description        : This file contains all the functions prototypes for the
*                      ADC firmware library.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************//* Define to prevent recursive inclusion -------------------------------------*/#define   ADC_RCG     (12)/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* ADC DISCNUM mask */
// #define CR1_DISCNUM_Reset           ((unsigned int)0xFFFF1FFF)// /* ADC DISCEN mask */
// #define CR1_DISCEN_Set              ((unsigned int)0x00000800)
// #define CR1_DISCEN_Reset            ((unsigned int)0xFFFFF7FF)// /* ADC JAUTO mask */
// #define CR1_JAUTO_Set               ((unsigned int)0x00000400)
// #define CR1_JAUTO_Reset             ((unsigned int)0xFFFFFBFF)// /* ADC JDISCEN mask */
// #define CR1_JDISCEN_Set             ((unsigned int)0x00001000)
// #define CR1_JDISCEN_Reset           ((unsigned int)0xFFFFEFFF)// /* ADC AWDCH mask */
// #define CR1_AWDCH_Reset             ((unsigned int)0xFFFFFFE0)// /* ADC Analog watchdog enable mode mask */
// #define CR1_AWDMode_Reset           ((unsigned int)0xFF3FFDFF)// /* CR1 register Mask */
#define CR1_CLEAR_MASK              ((unsigned int)0xFFF0FEFF)//
#define SR_EOC_OFFSET 0x1
#define SR_J_EOC_OFFSET 0x2//
#define CR1_EOC_IE_OFFSET 0x5
#define CR1_J_EOC_IE_OFFSET 0x7/* ADC ADON mask */
#define CR2_ADON_OFFSET             0x0/* ADC reset */
// #define CR2_ADC_Reset               ((unsigned int)0x80000000)// /* ADC DMA mask */
// #define CR2_DMA_Set                 ((unsigned int)0x00000100)
// #define CR2_DMA_Reset               ((unsigned int)0xFFFFFEFF)// /* ADC RSTCAL mask */
// #define CR2_RSTCAL_Set              ((unsigned int)0x00000008)// /* ADC CAL mask */
// #define CR2_CAL_Set                 ((unsigned int)0x00000004)// /* ADC SWSTART mask */
// #define CR2_SWSTART_Set             ((unsigned int)0x00400000)// /* ADC EXTTRIG mask */
// #define CR2_EXTTRIG_Set             ((unsigned int)0x00100000)
// #define CR2_EXTTRIG_Reset           ((unsigned int)0xFFEFFFFF)/* ADC Software start mask */
#define CR2_EXTTRIG_SW_START_OFFSET 22
#define CR2_EXTTRIG_SW_J_START_OFFSET 21
#define CR2_EXTTRIG_OFFSET 20
#define CR2_J_EXTTRIG_OFFSET 15
// #define CR2_EXTTRIG_SWSTART_Set     ((unsigned int)0x00500000)
// #define CR2_EXTTRIG_SWSTART_Reset   ((unsigned int)0xFFAFFFFF)/* ADC JEXTSEL mask */
// #define CR2_JEXTSEL_Reset           ((unsigned int)0xFFFF8FFF)// /* ADC JEXTTRIG mask */
// #define CR2_JEXTTRIG_Set            ((unsigned int)0x00008000)
// #define CR2_JEXTTRIG_Reset          ((unsigned int)0xFFFF7FFF)// /* ADC JSWSTART mask */
// #define CR2_JSWSTART_Set            ((unsigned int)0x00200000)// /* ADC injected software start mask */
// #define CR2_JEXTTRIG_JSWSTART_Set   ((unsigned int)0x00208000)
// #define CR2_JEXTTRIG_JSWSTART_Reset ((unsigned int)0xFFDF7FFF)// /* ADC TSPD mask */
// #define CR2_TSVREFE_Set             ((unsigned int)0x00800000)
// #define CR2_TSVREFE_Reset           ((unsigned int)0xFF7FFFFF)// /* CR2 register Mask */
#define CR2_CLEAR_MASK              ((unsigned int)0xFFF1F7FD)// /* ADC SQx mask */
#define SQR3_SQ_MASK 0x1F
#define SQR2_SQ_MASK 0x1F
#define SQR1_SQ_MASK 0x1F// /* SQR1 register Mask */
#define SQR1_CLEAR_MASK             ((unsigned int)0xFF0FFFFF)// /* ADC JSQx mask */
// #define JSQR_JSQ_Set                ((unsigned int)0x0000001F)// /* ADC JL mask */
// #define JSQR_JL_Set                 ((unsigned int)0x00300000)
// #define JSQR_JL_Reset               ((unsigned int)0xFFCFFFFF)// /* ADC SMPx mask */
#define SMPR1_SMP_MASK 0x7
#define SMPR2_SMP_MASK 0x7// /* ADC JDRx registers offset */
// #define JDR_Offset                  ((unsigned char)0x28)// #define DISABLE 0
// #define ENABLE 1/* Includes ------------------------------------------------------------------*/
// #include "../i2c/ls2k0300_map.h"/* Exported types ------------------------------------------------------------*/
/* ADC Init structure definition */
typedef struct
{unsigned int ADC_Mode;int ADC_ScanConvMode;  //CR1 scanint ADC_ContinuousConvMode;//CR2 contunsigned int ADC_ExternalTrigConv;//CR2 extselunsigned int ADC_DataAlign;//CR2 alignunsigned char  ADC_NbrOfChannel;//SQR1 lunsigned short ADC_ClkDivider;//CR1 clkdivunsigned char  ADC_JTrigMod;//CR2 jtrigmodunsigned char  ADC_ADCEdge;//CR2 adcedgeunsigned char  ADC_DiffMod;//CR1 diffmodunsigned char  ADC_OutPhaseSel;//CR1 opsunsigned char  ADC_ClkMask;//CR2 clkmaskunsigned char ADC_Int_EOC; // CR1 EOC enable ?unsigned char ADC_Int_JEOC; // CR1 JEOC enable ?
}adc_init_info;/* Exported constants --------------------------------------------------------*//* ADC dual mode -------------------------------------------------------------*/
#define ADC_Mode_Independent                       ((unsigned int)0x00000000)
#define ADC_Mode_RegInjecSimult                    ((unsigned int)0x00010000)
#define ADC_Mode_RegSimult_AlterTrig               ((unsigned int)0x00020000)
#define ADC_Mode_InjecSimult_FastInterl            ((unsigned int)0x00030000)
#define ADC_Mode_InjecSimult_SlowInterl            ((unsigned int)0x00040000)
#define ADC_Mode_InjecSimult                       ((unsigned int)0x00050000)
#define ADC_Mode_RegSimult                         ((unsigned int)0x00060000)
#define ADC_Mode_FastInterl                        ((unsigned int)0x00070000)
#define ADC_Mode_SlowInterl                        ((unsigned int)0x00080000)
#define ADC_Mode_AlterTrig                         ((unsigned int)0x00090000)#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \((MODE) == ADC_Mode_RegInjecSimult) || \((MODE) == ADC_Mode_RegSimult_AlterTrig) || \((MODE) == ADC_Mode_InjecSimult_FastInterl) || \((MODE) == ADC_Mode_InjecSimult_SlowInterl) || \((MODE) == ADC_Mode_InjecSimult) || \((MODE) == ADC_Mode_RegSimult) || \((MODE) == ADC_Mode_FastInterl) || \((MODE) == ADC_Mode_SlowInterl) || \((MODE) == ADC_Mode_AlterTrig))/* ADC extrenal trigger sources for regular channels conversion --------------*/
/* for ADC1 and ADC2 */
#define ADC_ExternalTrigConv_T1_CC1                ((unsigned int)0x00000000)
#define ADC_ExternalTrigConv_T1_CC2                ((unsigned int)0x00020000)
#define ADC_ExternalTrigConv_T2_CC2                ((unsigned int)0x00060000)
#define ADC_ExternalTrigConv_T3_TRGO               ((unsigned int)0x00080000)
#define ADC_ExternalTrigConv_T4_CC4                ((unsigned int)0x000A0000)
#define ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO    ((unsigned int)0x000C0000)
/* for ADC1, ADC2 and ADC3 */
#define ADC_ExternalTrigConv_T1_CC3                ((unsigned int)0x00040000)
#define ADC_ExternalTrigConv_None                  ((unsigned int)0x000E0000)
/* for ADC3 */
#define ADC_ExternalTrigConv_T3_CC1                ((unsigned int)0x00000000)
#define ADC_ExternalTrigConv_T2_CC3                ((unsigned int)0x00020000)
#define ADC_ExternalTrigConv_T8_CC1                ((unsigned int)0x00060000)
#define ADC_ExternalTrigConv_T8_TRGO               ((unsigned int)0x00080000)
#define ADC_ExternalTrigConv_T5_CC1                ((unsigned int)0x000A0000)
#define ADC_ExternalTrigConv_T5_CC3                ((unsigned int)0x000C0000)#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO) || \((REGTRIG) == ADC_ExternalTrigConv_None) || \((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \((REGTRIG) == ADC_ExternalTrigConv_T5_CC3))/* ADC data align ------------------------------------------------------------*/
#define ADC_DataAlign_Right                        ((unsigned int)0x00000000)
#define ADC_DataAlign_Left                         ((unsigned int)0x00000800)#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \((ALIGN) == ADC_DataAlign_Left))/* ADC channels --------------------------------------------------------------*/
#define ADC_Channel_0                               ((unsigned char)0x00)
#define ADC_Channel_1                               ((unsigned char)0x01)
#define ADC_Channel_2                               ((unsigned char)0x02)
#define ADC_Channel_3                               ((unsigned char)0x03)
#define ADC_Channel_4                               ((unsigned char)0x08)
#define ADC_Channel_5                               ((unsigned char)0x09)
#define ADC_Channel_6                               ((unsigned char)0x0a)
#define ADC_Channel_7                               ((unsigned char)0x0b)
#define ADC_Channel_8                               ((unsigned char)0x18)
#define ADC_Channel_9                               ((unsigned char)0x19)
#define ADC_Channel_10                              ((unsigned char)0x1A)
#define ADC_Channel_11                              ((unsigned char)0x1B)
#define ADC_Channel_12                              ((unsigned char)0x1C)
#define ADC_Channel_13                              ((unsigned char)0x1D)
#define ADC_Channel_14                              ((unsigned char)0x1E)
#define ADC_Channel_15                              ((unsigned char)0x1F)
#define ADC_Channel_16                              ((unsigned char)0x10)
#define ADC_Channel_17                              ((unsigned char)0x11)#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17))/* ADC sampling times --------------------------------------------------------*/
#define ADC_SampleTime_1Cycles                    ((unsigned char)0x00)
#define ADC_SampleTime_2Cycles                    ((unsigned char)0x01)
#define ADC_SampleTime_4Cycles                    ((unsigned char)0x02)
#define ADC_SampleTime_8Cycles                    ((unsigned char)0x03)
#define ADC_SampleTime_16Cycles                   ((unsigned char)0x04)
#define ADC_SampleTime_32Cycles                   ((unsigned char)0x05)
#define ADC_SampleTime_64Cycles                   ((unsigned char)0x06)
#define ADC_SampleTime_128Cycles                  ((unsigned char)0x07)#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1Cycles5)  || \((TIME) == ADC_SampleTime_2Cycles5)  || \((TIME) == ADC_SampleTime_4Cycles5)  || \((TIME) == ADC_SampleTime_8Cycles5)  || \((TIME) == ADC_SampleTime_16Cycles5) || \((TIME) == ADC_SampleTime_32Cycles5) || \((TIME) == ADC_SampleTime_64Cycles5) || \((TIME) == ADC_SampleTime_128Cycles5))/* ADC extrenal trigger sources for injected channels conversion -------------*/
/* For ADC1 and ADC2 */
#define ADC_ExternalTrigInjecConv_T2_TRGO           ((unsigned int)0x00002000)
#define ADC_ExternalTrigInjecConv_T2_CC1            ((unsigned int)0x00003000)
#define ADC_ExternalTrigInjecConv_T3_CC4            ((unsigned int)0x00004000)
#define ADC_ExternalTrigInjecConv_T4_TRGO           ((unsigned int)0x00005000)
#define ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4 ((unsigned int)0x00006000)
/* For ADC1, ADC2 and ADC3 */
#define ADC_ExternalTrigInjecConv_T1_TRGO           ((unsigned int)0x00000000)
#define ADC_ExternalTrigInjecConv_T1_CC4            ((unsigned int)0x00001000)
#define ADC_ExternalTrigInjecConv_None              ((unsigned int)0x00007000)
/* For ADC3 */
#define ADC_ExternalTrigInjecConv_T4_CC3            ((unsigned int)0x00002000)
#define ADC_ExternalTrigInjecConv_T8_CC2            ((unsigned int)0x00003000)
#define ADC_ExternalTrigInjecConv_T8_CC4            ((unsigned int)0x00004000)
#define ADC_ExternalTrigInjecConv_T5_TRGO           ((unsigned int)0x00005000)
#define ADC_ExternalTrigInjecConv_T5_CC4            ((unsigned int)0x00006000)#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4) || \((INJTRIG) == ADC_ExternalTrigInjecConv_None) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4))/* ADC injected channel selection --------------------------------------------*/
#define ADC_InjectedChannel_1                       ((unsigned char)0x14)
#define ADC_InjectedChannel_2                       ((unsigned char)0x18)
#define ADC_InjectedChannel_3                       ((unsigned char)0x1C)
#define ADC_InjectedChannel_4                       ((unsigned char)0x20)#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \((CHANNEL) == ADC_InjectedChannel_2) || \((CHANNEL) == ADC_InjectedChannel_3) || \((CHANNEL) == ADC_InjectedChannel_4))/* ADC analog watchdog selection ---------------------------------------------*/
#define ADC_AnalogWatchdog_SingleRegEnable         ((unsigned int)0x00800200)
#define ADC_AnalogWatchdog_SingleInjecEnable       ((unsigned int)0x00400200)
#define ADC_AnalogWatchdog_SingleRegOrInjecEnable  ((unsigned int)0x00C00200)
#define ADC_AnalogWatchdog_AllRegEnable            ((unsigned int)0x00800000)
#define ADC_AnalogWatchdog_AllInjecEnable          ((unsigned int)0x00400000)
#define ADC_AnalogWatchdog_AllRegAllInjecEnable    ((unsigned int)0x00C00000)
#define ADC_AnalogWatchdog_None                    ((unsigned int)0x00000000)#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \((WATCHDOG) == ADC_AnalogWatchdog_None))/* ADC interrupts definition -------------------------------------------------*/
#define ADC_IT_EOC                                 ((unsigned short)0x0220)
#define ADC_IT_AWD                                 ((unsigned short)0x0140)
#define ADC_IT_JEOC                                ((unsigned short)0x0480)#define IS_ADC_IT(IT) ((((IT) & (unsigned short)0xF81F) == 0x00) && ((IT) != 0x00))
#define IS_ADC_GET_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \((IT) == ADC_IT_JEOC))/* ADC flags definition ------------------------------------------------------*/
#define ADC_FLAG_AWD                               ((unsigned char)0x01)
#define ADC_FLAG_EOC                               ((unsigned char)0x02)
#define ADC_FLAG_JEOC                              ((unsigned char)0x04)
#define ADC_FLAG_JSTRT                             ((unsigned char)0x08)
#define ADC_FLAG_STRT                              ((unsigned char)0x10)#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (unsigned char)0xE0) == 0x00) && ((FLAG) != 0x00))
#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || ((FLAG) == ADC_FLAG_EOC) || \((FLAG) == ADC_FLAG_JEOC) || ((FLAG)== ADC_FLAG_JSTRT) || \((FLAG) == ADC_FLAG_STRT))/* ADC thresholds ------------------------------------------------------------*/
#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF)/* ADC injected offset -------------------------------------------------------*/
#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF)/* ADC injected length -------------------------------------------------------*/
#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4))/* ADC injected rank ---------------------------------------------------------*/
#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4))/* ADC regular length --------------------------------------------------------*/
#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10))/* ADC regular rank ----------------------------------------------------------*/
#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10))/* ADC regular discontinuous mode number -------------------------------------*/
#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8))//Loongson Feature
#define RCH0  ADC_Channel_0
#define RCH1  ADC_Channel_1
#define RCH2  ADC_Channel_2
#define RCH3  ADC_Channel_3
#define RCH4  ADC_Channel_4
#define RCH5  ADC_Channel_5
#define RCH6  ADC_Channel_6
#define RCH7  ADC_Channel_7//Loongson Feature
#define JCH0  ADC_Channel_0
#define JCH1  ADC_Channel_1
#define JCH2  ADC_Channel_2
#define JCH3  ADC_Channel_3void adc_init(adc_reg_map* ADCx, adc_init_info* ADC_InitStruct);
void adc_struct_init(adc_init_info* ADC_InitStruct);
void ADC_RegularChannelConfig(adc_reg_map* ADCx, unsigned char ADC_Channel, unsigned char Rank, unsigned char ADC_SampleTime);
void adc_dev_enable(adc_reg_map* ADCx, FunctionalState state);
void adc_software_start_conv_trigger(adc_reg_map* ADCx, FunctionalState state, unsigned char J_channel);
void adc_eoc_check_conv_end(adc_reg_map* ADCx);#endif /* __LOONGSON_2K300_ADC_CORE_H__ */

Kconfig

需要在drivers/iio/adc下的Kconfig加入以下代码

config LS_2K300_ADCtristate "ls2k300 driver"select IIO_BUFFERselect IIO_TRIGGERED_BUFFERhelploongson 2k300 ADC driver

Makefile

需要在drivers/iio/adc下的Makefile加入以下代码

obj-$(CONFIG_LS_2K300_ADC) += loongson-2k300-adc.o loongson-2k300-adc-core.o

loongson_2k0300.dtsi

dtsi文件下加入以下代码

adc: adc@0x1611c000 {compatible = "ls2k300-adc";reg = <0 0x1611c000 0 0x50>;status = "disabled";num-channels = <0>;
};

loongson_2k0300_pai_99.dts

dts设备树下加入adc节点

&adc {status = "okay";
};

.config

在内核根目录下的配置文件加入以下开关

CONFIG_IIO=y
CONFIG_LS_2K300_ADC=y

修改完毕后重新编译内核,将内核部署到开发板/boot目录下,重启开发板发现/sys/bus/iio/devices/iio/device0目录下已经生成了相应的in_voltageX_raw节点

在这里插入图片描述

接口

久久派上集成8路12位ADC采样接口, 支持单端采样, 也支持差分采样, 参考电压Vref为1.8V

PIN信号定义备注
1P3V33.3V 电源输出
2GND0地线
3ADC 通道 40/4 通道可以独立采样, 也可以作为差分采样
4ADC 通道 00/4 通道可以独立采样, 也可以作为差分采样
5ADC 通道 11/5 通道可以独立采样, 也可以作为差分采样
6ADC 通道 51/5 通道可以独立采样, 也可以作为差分采样
7ADC 通道 22/6 通道可以独立采样, 也可以作为差分采样
8ADC 通道 62/6 通道可以独立采样, 也可以作为差分采样
9ADC 通道 33/7 通道可以独立采样, 也可以作为差分采样
10ADC 通道 73/7 通道可以独立采样, 也可以作为差分采样

原理图如下,J1针脚处可见ADC并不是按顺序分布的

在这里插入图片描述

测试

以读取ADC0通道为例,测试命令如下(其中raw为ADC原始数据,scale为单位分辨率所占的电压值,两者相乘可得到实际电压值)

raw=$(cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw)
scale=$(cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale)
echo "vol_raw : $raw,vol_scale:$scale"

使用电位器调节到1.8V左右,和读取的数值较为接近:0.439453125 * 4095 / 1000约等于1.8V

在这里插入图片描述

参考

linux-5.10: linux for loongson2 (gitee.com)

相关文章:

【驱动篇】龙芯LS2K0300之ADC驱动

实验目的 由于LS2K0300久久派开发板4.19内核还没有现成可用的ADC驱动&#xff0c;但是龙芯官方的5.10内核已经提供了ADC驱动&#xff0c;想要在4.19内核使用ADC就要参考5.10内核移植驱动&#xff0c;本次实验主要是关于ADC驱动的移植和使用 驱动移植 主要的驱动代码主要有3个…...

Python入门 2024/7/3

目录 for循环的基础语法 遍历字符串 练习&#xff1a;数一数有几个a range语句 三个语法 语法1 语法2 语法3 练习&#xff1a;有几个偶数 变量作用域 for循环的嵌套使用 打印九九乘法表 发工资案例 continue和break语句 函数的基础定义语法 函数声明 函数调用 …...

Go 语言 Map(集合)

Go 语言 Map(集合) Map 是 Go 语言中一种非常重要的数据结构,它用于存储键值对。在 Go 中,Map 是一种无序的键值对的集合,其中每个键都是唯一的,而值则可以是任何类型。Map 是 Go 语言的内置类型,使用起来非常方便,同时也是许多 Go 程序中不可或缺的一部分。 Map 的声明…...

SpringCloud学习Day7:Seata

概念 Seata是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务 工作流程 TC以Seata服务器形式独立部署&#xff0c;TM和RM则是以Seata Client的形式集成在微服务中运行...

【ubuntu中关于驱动得问题】—— 如何将nouveau驱动程序加入黑名单和安装NVIDIA显卡驱动

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、nouveau驱动程序加入黑名单二、安装NVIDIA显卡驱动总结 前言 NVIDIA显卡驱动是用于支持和优化NVIDIA显卡在计算机系统中运行的关键软件组件。该驱动程序能…...

LabVIEW从测试曲线中提取特征值

在LabVIEW中开发用于从测试曲线中提取特征值的功能时&#xff0c;可以考虑以下几点&#xff1a; 数据采集与处理&#xff1a; 确保你能够有效地采集和处理测试曲线数据。这可能涉及使用DAQ模块或其他数据采集设备来获取曲线数据&#xff0c;并在LabVIEW中进行处理和分析。 特…...

【应届应知应会】SQL常用知识点50道

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;借他一双眼&#xff0c;愿这盛世如先生所愿 个性签名&#xff1a;人生乏味啊&#xff0c;我欲令之光怪陆离 本文封面由 凌七七~❤ 友情提供 目录 数据库的概念 (什么是数据库) RDBMS NOSQL 数据库的分类 …...

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【21】【购物车】

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【21】【购物车】 购物车需求描述购物车数据结构数据Model抽取实现流程&#xff08;参照京东&#xff09;代码实现参考 购物车需求描述 用户可以在登录状态下将商品添加到购物车【用户购物…...

科技赋能智慧应急:“数字孪生+无人机”在防汛救灾中的应用

近期&#xff0c;全国多地暴雨持续&#xff0c;“麻辣王子工厂停工”“水上派出所成水上的派出所了”等相关词条冲上热搜&#xff0c;让人们看到了全国各地城市内涝、洪涝带来的严重灾情。暴雨带来的影响可见一斑&#xff0c;潜在的洪水、泥石流、山体滑坡等地质灾害更应提高警…...

urfread刷算法|构建一棵树

大意 示例标签串&#xff1a; 处理结果&#xff1a; 题目1 根据标签串创建树 需求 需求&#xff1a;给出一个字符串&#xff0c;将这个字符串转换为一棵树。 字符串可以在代码里见到&#xff0c;是以#开头&#xff0c;按照\分割的字符串。 你需要将这个字符串&#xff0…...

在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野

在卷积神经网络&#xff08;CNN&#xff09;中为什么可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的感受野 flyfish 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;可以使用多个较小的卷积核替代一个较大的卷积核&#xff0c;以达到相同的…...

【学习笔记】Mybatis-Plus(四):MP中内置的插件

内置插件 目前MP已经存在的内部插件包括如下&#xff1a; 插件类名作用PaginationInnerInterceptor分页插件。可以代替以前的PageHelperOptimisticLockerInnerInterceptor乐观锁插件。用于幂等性操作&#xff0c;采用版本更新记录DynamicTableNameInnerInterceptor动态表名Te…...

GlusterFS分布式存储系统

GlusterFS分布式存储系统 一&#xff0c;分布式文件系统理论基础 1.1 分布式文件系统出现 计算机通过文件系统管理&#xff0c;存储数据&#xff0c;而现在数据信息爆炸的时代中人们可以获取的数据成指数倍的增长&#xff0c;单纯通过增加硬盘个数来扩展计算机文件系统的存储…...

微信公众平台测试账号本地微信功能测试说明

使用场景 在本地测试微信登录功能时&#xff0c;因为微信需要可以互联网访问的域名接口&#xff0c;所以本地使用花生壳做内网穿透&#xff0c;将前端服务的端口和后端服务端口进行绑定&#xff0c;获得花生壳提供的两个外网域名。 微信测试账号入口 绑定回调接口 回调接口的…...

Lua语言入门

目录 Lua语言1 搭建Lua开发环境1.1 安装Lua解释器WindowsLinux 1.2 IntelliJ安装Lua插件在线安装本地安装 2 Lua语法2.1 数据类型2.2 变量全局变量局部变量命名规范局部变量作用域 2.3 注释单行注释多行注释 2.4 赋值2.5 操作符数学操作符比较操作符逻辑操作符连接操作符取长度…...

卷积神经网络有哪些应用场景

卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;简称CNN&#xff09;的应用场景非常广泛&#xff0c;尤其是在处理具有网格结构的数据&#xff08;如图像、视频&#xff09;时表现出色。以下是一些主要的应用场景&#xff1a; 1. 图像识别与分类 图像分类…...

std::unordered_map和std::map在性能上有何不同

std::unordered_map和std::map在性能上的不同主要体现在以下几个方面&#xff1a; 1. 底层数据结构 std::unordered_map&#xff1a;基于哈希表实现&#xff0c;通过哈希函数计算元素的存储位置。哈希表能够直接通过哈希值快速定位到元素的位置&#xff0c;从而实现高效的查找…...

C++20中的基于范围的for循环(range-based for loop)

C11中引入了对基于范围的for循环(range-based for loop)的支持&#xff1a;该循环对一系列值(例如容器中的所有元素)进行操作。代码段如下&#xff1a; const std::vector<int> vec{ 1,2,3,4,5 }; for (const auto& i : vec)std::cout << i << ", …...

PCIe驱动开发(2)— 第一个简单驱动编写和测试

PCIe驱动开发&#xff08;2&#xff09;— 第一个简单驱动编写和测试 一、前言 教程参考&#xff1a;02_实战部分_PCIE设备测试 教程参考&#xff1a;03_PCIe设备驱动源码解析 二、驱动编写 新建hello_pcie.c文件 touch hello_pcie.c然后编写内容如下所示&#xff1a; #i…...

k8s-第七节-ConfigMap Secret

ConfigMap & Secret ConfigMap 数据库连接地址&#xff0c;这种可能根据部署环境变化的或者其他容器配置选项的包括容器更新或者扩容时可以统一配置 Kubernetes 为我们提供了 ConfigMap&#xff0c;可以方便的配置一些变量。 https://kubernetes.io/zh/docs/concepts/c…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...