|
|
|
|
/******************************************************************************
|
|
|
|
|
* file lib/process/pd_cpld.c
|
|
|
|
|
* author YuLiang
|
|
|
|
|
* version 1.0.0
|
|
|
|
|
* date 31-July-2023
|
|
|
|
|
* brief This file provides all the CPLD operation functions.
|
|
|
|
|
*
|
|
|
|
|
******************************************************************************
|
|
|
|
|
* Attention
|
|
|
|
|
*
|
|
|
|
|
* <h2><center>© COPYRIGHT(c) 2023 LandPower</center></h2>
|
|
|
|
|
*
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
|
* are permitted provided that the following conditions are met:
|
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
|
* 3. Neither the name of LandPower nor the names of its contributors may be used to
|
|
|
|
|
* endorse or promote products derived from this software without specific
|
|
|
|
|
* prior written permission.
|
|
|
|
|
*
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
*
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* 标准C库头文件. */
|
|
|
|
|
|
|
|
|
|
/* 用户代码头文件. */
|
|
|
|
|
#include "cmd.h"
|
|
|
|
|
#include "hwgpio.h"
|
|
|
|
|
#include "pd_cpld.h"
|
|
|
|
|
|
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
|
|
#define CPLD_CS_1 gpio_val_set(cpld_cs_idx, 1)
|
|
|
|
|
#define CPLD_CS_0 gpio_val_set(cpld_cs_idx, 0)
|
|
|
|
|
|
|
|
|
|
#define CPLD_SCLK_1 gpio_val_set(cpld_sclk_idx, 1)
|
|
|
|
|
#define CPLD_SCLK_0 gpio_val_set(cpld_sclk_idx, 0)
|
|
|
|
|
|
|
|
|
|
#define CPLD_MOSI_1 gpio_val_set(cpld_mosi_idx, 1)
|
|
|
|
|
#define CPLD_MOSI_0 gpio_val_set(cpld_mosi_idx, 0)
|
|
|
|
|
|
|
|
|
|
#define CPLD_MISO_READ(_val_) gpio_val_get(cpld_miso_idx, _val_)
|
|
|
|
|
|
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
|
|
cpld_version_t cpld_version;
|
|
|
|
|
static pthread_mutex_t cpld_mutex; // 多线程同时操作的信号量.
|
|
|
|
|
static int32_t cpld_cs_idx;
|
|
|
|
|
static int32_t cpld_sclk_idx;
|
|
|
|
|
static int32_t cpld_mosi_idx;
|
|
|
|
|
static int32_t cpld_miso_idx;
|
|
|
|
|
|
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
|
|
/* 读取 CPLD 寄存器. */
|
|
|
|
|
CMD(cpld_reg_read,
|
|
|
|
|
cpld_reg_read_cmd,
|
|
|
|
|
"cpld read WORD",
|
|
|
|
|
"CPLD\n"
|
|
|
|
|
"CPLD register read.\n"
|
|
|
|
|
"Register address (HH)\n")
|
|
|
|
|
{
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
uint16_t reg = 0;
|
|
|
|
|
uint16_t temp = 0;
|
|
|
|
|
char* str = NULL;
|
|
|
|
|
|
|
|
|
|
reg = strtol(argv[0], &str, 16);
|
|
|
|
|
if (*str != '\0')
|
|
|
|
|
{
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpld_read(reg, 1, &temp);
|
|
|
|
|
vty_out(vty, "Read reg 0x%02x value: 0x%04x%s\n", reg, temp, VTY_NEWLINE);
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 写 CPLD 寄存器. */
|
|
|
|
|
CMD(cpld_reg_write,
|
|
|
|
|
cpld_reg_write_cmd,
|
|
|
|
|
"cpld write WORD WORD",
|
|
|
|
|
"CPLD\n"
|
|
|
|
|
"CPLD register write\n"
|
|
|
|
|
"Register address (HH)\n"
|
|
|
|
|
"Value (HHHH)\n")
|
|
|
|
|
{
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
uint16_t reg = 0;
|
|
|
|
|
uint16_t temp = 0;
|
|
|
|
|
char* str = NULL;
|
|
|
|
|
|
|
|
|
|
reg = strtol(argv[0], &str, 16);
|
|
|
|
|
if (*str != '\0')
|
|
|
|
|
{
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
temp = strtol(argv[1], &str, 16);
|
|
|
|
|
if (*str != '\0')
|
|
|
|
|
{
|
|
|
|
|
return CMD_ERR_NO_MATCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpld_write(reg, 1, &temp);
|
|
|
|
|
vty_out(vty, "Write reg 0x%02x value: 0x%04x%s", reg, temp, VTY_NEWLINE);
|
|
|
|
|
cpld_read(reg, 1, &temp);
|
|
|
|
|
vty_out(vty, "Read reg 0x%02x value: 0x%04x%s\n", reg, temp, VTY_NEWLINE);
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 显示 CPLD 信息. */
|
|
|
|
|
CMD(show_cpld,
|
|
|
|
|
show_cpld_cmd,
|
|
|
|
|
"show cpld",
|
|
|
|
|
SHOW_STR
|
|
|
|
|
"CPLD\n")
|
|
|
|
|
{
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
vty_out(vty, "Version: %04x-%02x-%02x%s\n", cpld_version.year, cpld_version.month, cpld_version.day, VTY_NEWLINE);
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//SPI可以同时读取和写入数据,因此一个函数即可满足要求
|
|
|
|
|
int32_t _cpld_half_word_write(uint16_t data)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
if(data & 0x8000)
|
|
|
|
|
{
|
|
|
|
|
CPLD_MOSI_1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CPLD_MOSI_0;
|
|
|
|
|
}
|
|
|
|
|
data <<= 1;
|
|
|
|
|
|
|
|
|
|
CPLD_SCLK_1;
|
|
|
|
|
CPLD_SCLK_0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//SPI可以同时读取和写入数据,因此一个函数即可满足要求
|
|
|
|
|
int32_t _cpld_half_word_read(uint16_t *data)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i = 0;
|
|
|
|
|
uint8_t gpio_val = 0;
|
|
|
|
|
uint16_t data_rx = 0;
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
CPLD_SCLK_1;
|
|
|
|
|
|
|
|
|
|
data_rx <<= 1;
|
|
|
|
|
CPLD_MISO_READ(&gpio_val);
|
|
|
|
|
if (gpio_val)
|
|
|
|
|
{
|
|
|
|
|
data_rx |= 0x01;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CPLD_SCLK_0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*data = data_rx;
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Internal functions --------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Interface functions -------------------------------------------------------*/
|
|
|
|
|
/* CPLD 模块初始化代码. */
|
|
|
|
|
int32_t cpld_handle_init(void)
|
|
|
|
|
{
|
|
|
|
|
uint16_t temp = 0;
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
/* 申请信号量, 防止多个线程同时操作 fifo. */
|
|
|
|
|
if (pthread_mutex_init(&cpld_mutex, NULL) != 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_FIFO_ERR, "ERROR at mutex init return %s!\r\n", safe_strerror(errno));
|
|
|
|
|
return E_SYS_CALL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 申请 GPIO. */
|
|
|
|
|
cpld_cs_idx = gpio_export(GPIO_CPLD_CS);
|
|
|
|
|
if (cpld_cs_idx < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_cs_idx);
|
|
|
|
|
return E_BAD_PARAM;
|
|
|
|
|
}
|
|
|
|
|
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_cs_idx, GPIO_DIR_OUT));
|
|
|
|
|
|
|
|
|
|
cpld_sclk_idx = gpio_export(GPIO_CPLD_SCLK);
|
|
|
|
|
if (cpld_sclk_idx < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_sclk_idx);
|
|
|
|
|
return E_BAD_PARAM;
|
|
|
|
|
}
|
|
|
|
|
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_sclk_idx, GPIO_DIR_OUT));
|
|
|
|
|
|
|
|
|
|
cpld_mosi_idx = gpio_export(GPIO_CPLD_MOSI);
|
|
|
|
|
if (cpld_mosi_idx < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_mosi_idx);
|
|
|
|
|
return E_BAD_PARAM;
|
|
|
|
|
}
|
|
|
|
|
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_mosi_idx, GPIO_DIR_OUT));
|
|
|
|
|
|
|
|
|
|
cpld_miso_idx = gpio_export(GPIO_CPLD_MISO);
|
|
|
|
|
if (cpld_miso_idx < 0)
|
|
|
|
|
{
|
|
|
|
|
DBG(DBG_M_PD_CPLD, "ERROR return %d!\r\n", cpld_miso_idx);
|
|
|
|
|
return E_BAD_PARAM;
|
|
|
|
|
}
|
|
|
|
|
LD_E_RETURN(DBG_M_PD_CPLD, gpio_dir_set(cpld_miso_idx, GPIO_DIR_IN));
|
|
|
|
|
|
|
|
|
|
CPLD_CS_1;
|
|
|
|
|
CPLD_SCLK_0;
|
|
|
|
|
|
|
|
|
|
/* 获取版本号. */
|
|
|
|
|
cpld_read(CPLD_REG_V0, 1, &temp);
|
|
|
|
|
cpld_version.year = temp;
|
|
|
|
|
cpld_read(CPLD_REG_V1, 1, &temp);
|
|
|
|
|
cpld_version.month = temp >> 8;
|
|
|
|
|
cpld_version.day = temp & 0x00ff;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* 注册命令. */
|
|
|
|
|
cmd_install_element(COMMON_NODE, &show_cpld_cmd);
|
|
|
|
|
cmd_install_element(ENABLE_NODE, &cpld_reg_read_cmd);
|
|
|
|
|
cmd_install_element(ENABLE_NODE, &cpld_reg_write_cmd);
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t cpld_read(uint16_t addr, uint16_t len, uint16_t *data)
|
|
|
|
|
{
|
|
|
|
|
int32_t i = 0;
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&cpld_mutex);
|
|
|
|
|
CPLD_CS_0;
|
|
|
|
|
|
|
|
|
|
_cpld_half_word_write(0x8000 | addr);
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
_cpld_half_word_read(data + i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CPLD_CS_1;
|
|
|
|
|
pthread_mutex_unlock(&cpld_mutex);
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t cpld_write(uint16_t addr, uint16_t len, uint16_t *data)
|
|
|
|
|
{
|
|
|
|
|
int32_t i = 0;
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&cpld_mutex);
|
|
|
|
|
CPLD_CS_0;
|
|
|
|
|
|
|
|
|
|
_cpld_half_word_write(0x7fff & addr);
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < len; i++)
|
|
|
|
|
{
|
|
|
|
|
_cpld_half_word_write(data[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CPLD_CS_1;
|
|
|
|
|
pthread_mutex_unlock(&cpld_mutex);
|
|
|
|
|
|
|
|
|
|
return E_NONE;
|
|
|
|
|
}
|
|
|
|
|
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
|