// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/
#include <common.h>
#include <command.h>
#include <dm.h>
#include <errno.h>
#include <stdio.h>
#include <dm/pinctrl.h>
#include <dm/uclass-internal.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/gpio.h>
#define LIMIT_DEVNAME 30
struct gpio_describe {
const char *pGroup;
const char pins[32];
};
static const char *pname[]={"PA","PB","PC","PD","PE","PF","PG","PH","PI","PJ","PK","PL"};
static int get_serial_input(uint32_t timeout)
{
unsigned long time_start;
int input;
time_start = get_timer(0);
for(;;)
{
if(tstc()) {
input =getchar();
if(input > 0)
return input;
}
if(get_timer(time_start) > timeout){
return -1;
}
}
}
static int sunxi_gpio_output(u32 pin, u32 val)
{
u32 dat;
u32 bank = GPIO_BANK(pin);
u32 num = GPIO_NUM(pin);
struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
dat = readl(&pio->dat);
if (val)
dat |= 0x1 << num;
else
dat &= ~(0x1 << num);
writel(dat, &pio->dat);
return 0;
}
static int sunxi_gpio_input(u32 pin)
{
u32 dat;
u32 bank = GPIO_BANK(pin);
u32 num = GPIO_NUM(pin);
struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
dat = readl(&pio->dat);
dat >>= num;
return dat & 0x1;
}
static int get_gpio_by_name(const char *pin)
{
int group=0,idx=0;
if((pin[0] == 'p')||(pin[0]=='P'))
{
group = pin[1] - (pin[1] > 'a' ? 'a' : 'A');
idx = dectoul(&pin[2], NULL);
return (group * 32 + idx);
}
return -1;
}
#define GROUP_SIZE 8
static struct gpio_describe all_gpio[GROUP_SIZE]={
{.pGroup="PB",.pins={0,1,2,3,4,5,6,7,-1}},
{.pGroup="PC",.pins={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,-1}},
{.pGroup="PD",.pins={'x','x',2,3,4,5,6,7,10,11,12,13,14,15,18,19,20,21,22,23,24,25,26,27,-1}},
{.pGroup="PE",.pins={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,-1}},
{.pGroup="PF",.pins={0,1,'x',3,'x',5,-1}},
{.pGroup="PG",.pins={0,1,2,3,4,5,6,7,8,9,10,11,12,13,-1}},
{.pGroup="PH",.pins={0,1,2,3,4,5,6,7,8,9,-1}},
{.pGroup="PL",.pins={0,1,2,3,4,5,6,7,8,9,10,11,-1}},
};
static char gname[GROUP_SIZE*32][8];
static int gno[GROUP_SIZE*32];
static int gtotal=0;
static int tick =0;
static void create_gpio_map(void)
{
struct gpio_describe *pdescribe;
for(int i=0;i<GROUP_SIZE;i++)
{
pdescribe = &all_gpio[i];
for(int k=0;k<32;k++){
if(pdescribe->pins[k] == 'x'){
continue;
}
if(pdescribe->pins[k] < 0){
break;
}
sprintf(gname[gtotal],"%s%d",pdescribe->pGroup,pdescribe->pins[k]);
gno[gtotal] =get_gpio_by_name(gname[gtotal]);
if(gno[gtotal] > 0){
sunxi_gpio_set_cfgpin(gno[gtotal], SUNXI_GPIO_OUTPUT);
gtotal++;
}
}
}
}
static void simulate_set_bsp(int bsp)
{
tick =(1000*1000 + (bsp / 2)) / bsp;
}
static void simulate_uart_delay(void)
{
__udelay(tick);
}
static void simulate_uart_send(char *str,int gpio)
{
char data;
while(*str){
data =*str++;
sunxi_gpio_output(gpio,0); //start
simulate_uart_delay();
for(int i=0;i<8;i++){
sunxi_gpio_output(gpio,data & 0x01);
simulate_uart_delay();
data >>=1;
}
sunxi_gpio_output(gpio,1); //stop
simulate_uart_delay();
}
}
static int do_pin_detect(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
char io_name[16];
printf("show GPIO name on itself\n");
create_gpio_map();
simulate_set_bsp(2400);
while(get_serial_input(50) < 0){
for(int i=0;i<gtotal;i++){
sprintf(io_name,"%s \n",gname[i]);
simulate_uart_send(io_name,gno[i]);
}
}
return 0;
}
U_BOOT_CMD(pindetect, CONFIG_SYS_MAXARGS, 1, do_pin_detect,
"the GPIO name is displaied on itself in UART at bsp 2400",
"\nexample: pindetect - all pins name on itself gpio\n"
)
以上代码在 R16 uboot中测试通过,因公司网络限制不能上传资源,个人自行测试。
]]>之前看过一个更骚的操作(仅对于FPGA有效),可以给每个引脚安排一个输出当前引脚编号的UART发送单元,之后只需要用一个串口模块就能读取每个信号的对应引脚编号了。
同样的方法,借助1个TIMER,MCU/SOC也完全可以,波特率调低点就行。
]]>演技担当黄晓明 说:JTAG工具.rar
用这个软件可以控制 支持JTAG扫描链的芯片的PIN脚输出输入这个支持测试altera的引脚吗
都是可以的,只要网站能下载PIN定义资料就可以
]]>之前看过一个更骚的操作(仅对于FPGA有效),可以给每个引脚安排一个输出当前引脚编号的UART发送单元,之后只需要用一个串口模块就能读取每个信号的对应引脚编号了。
这个思路还蛮清奇的
]]>哦,不过探测部分引出的io,应该可行
]]>JTAG工具.rar
用这个软件可以控制 支持JTAG扫描链的芯片的PIN脚输出输入
这个支持测试altera的引脚吗
]]>有这个劲头和精力,还不如花点钱买个有资料的板子玩玩
除非碰到大批量的板子,非常便宜,那还值得搞搞
当时间和精力都很充沛,但是钱又有限的情况下....
算了, 你们有钱人是不会明白这种乐趣的.
除非碰到大批量的板子,非常便宜,那还值得搞搞
]]>