mirror of https://github.com/OpenIPC/firmware.git
				
				
				
			Add HiSilicon AV300 support to GPIO scanner
							parent
							
								
									ccc0fb19b7
								
							
						
					
					
						commit
						2389e91c80
					
				|  | @ -1,101 +1,91 @@ | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <setjmp.h> | ||||||
|  | #include <signal.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <sys/mman.h> | ||||||
|  | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
|   #include <stdio.h> | #define DEFAULT_MD_LEN 128 | ||||||
|   #include <stdlib.h> | #define PAGE_SIZE 0x1000 | ||||||
|   #include <string.h> | #define PAGE_SIZE_MASK (~(0xfff)) | ||||||
|   #include <fcntl.h> |  | ||||||
|   #include <unistd.h> |  | ||||||
|   #include <fcntl.h> |  | ||||||
|   #include <setjmp.h> |  | ||||||
|   #include <signal.h> |  | ||||||
|   #include <sys/mman.h> |  | ||||||
| 
 | 
 | ||||||
|   #define DEFAULT_MD_LEN 128 | typedef struct tag_MMAP_Node { | ||||||
|   #define PAGE_SIZE 0x1000 |  | ||||||
|   #define PAGE_SIZE_MASK (~(0xfff)) |  | ||||||
| 
 |  | ||||||
|   typedef struct tag_MMAP_Node |  | ||||||
|   { |  | ||||||
|   unsigned long Start_P; |   unsigned long Start_P; | ||||||
|   unsigned long Start_V; |   unsigned long Start_V; | ||||||
|   unsigned long length; |   unsigned long length; | ||||||
|   unsigned long refcount; |   unsigned long refcount; | ||||||
|     struct tag_MMAP_Node * next; |   struct tag_MMAP_Node *next; | ||||||
|   }TMMAP_Node_t; | } TMMAP_Node_t; | ||||||
| 
 | 
 | ||||||
|   TMMAP_Node_t * pTMMAPNode = NULL; | TMMAP_Node_t *pTMMAPNode = NULL; | ||||||
|   int fd = -1; | int fd = -1; | ||||||
|   const char dev[]="/dev/mem"; | const char dev[] = "/dev/mem"; | ||||||
|   jmp_buf *sigbus_jmp; // global
 | jmp_buf *sigbus_jmp; // global
 | ||||||
| 
 | 
 | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| void print_bin(unsigned long data) | void print_bin(unsigned long data) { | ||||||
| { |  | ||||||
|   int i; |   int i; | ||||||
|   unsigned long ulbit; |   unsigned long ulbit; | ||||||
|   for (i = 7; i >= 0; i--) |   for (i = 7; i >= 0; i--) { | ||||||
|   { |  | ||||||
|     ulbit = data >> i; |     ulbit = data >> i; | ||||||
|     if (ulbit & 1) printf("1"); else printf("0"); |     if (ulbit & 1) | ||||||
|  |       printf("1"); | ||||||
|  |     else | ||||||
|  |       printf("0"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| void signal_handler (int sig) | void signal_handler(int sig) { | ||||||
| { |   if (sig == SIGBUS) { | ||||||
|   if (sig == SIGBUS) |     // printf("signal_handler SIGBUS!\n");
 | ||||||
|   { |     if (sigbus_jmp) | ||||||
|     //printf("signal_handler SIGBUS!\n");
 |       siglongjmp(*sigbus_jmp, 1); | ||||||
|     if(sigbus_jmp) siglongjmp(*sigbus_jmp, 1); |  | ||||||
|     // no one to catch the error, so abort
 |     // no one to catch the error, so abort
 | ||||||
|     abort(); |     abort(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| int set_handler() | int set_handler() { | ||||||
| { |  | ||||||
|   struct sigaction act; |   struct sigaction act; | ||||||
|   memset (&act, 0, sizeof(act)); |   memset(&act, 0, sizeof(act)); | ||||||
|   act.sa_sigaction = (void *)signal_handler; |   act.sa_sigaction = (void *)signal_handler; | ||||||
|   act.sa_flags = SA_SIGINFO; |   act.sa_flags = SA_SIGINFO; | ||||||
|   if (sigaction(SIGBUS, &act, 0)) |   if (sigaction(SIGBUS, &act, 0)) { | ||||||
|   { |     perror("sigaction"); | ||||||
|     perror ("sigaction"); |  | ||||||
|     return -1; |     return -1; | ||||||
|   } |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| void * memmap(unsigned long phy_addr, unsigned long size) | void *memmap(unsigned long phy_addr, unsigned long size) { | ||||||
| { |  | ||||||
|   unsigned long phy_addr_in_page; |   unsigned long phy_addr_in_page; | ||||||
|   unsigned long page_diff; |   unsigned long page_diff; | ||||||
|   unsigned long size_in_page; |   unsigned long size_in_page; | ||||||
|   unsigned long value = 0; |   unsigned long value = 0; | ||||||
|   TMMAP_Node_t * pTmp; |   TMMAP_Node_t *pTmp; | ||||||
|   TMMAP_Node_t * pNew; |   TMMAP_Node_t *pNew; | ||||||
|   void *addr=NULL; |   void *addr = NULL; | ||||||
|   if(size == 0) |   if (size == 0) { | ||||||
|   { |  | ||||||
|     printf("memmap():size can't be zero!\n"); |     printf("memmap():size can't be zero!\n"); | ||||||
|     return NULL; |     return NULL; | ||||||
|   } |   } | ||||||
|   /* проверить, было ли преобразовано пространство физической памяти */ |   /* проверить, было ли преобразовано пространство физической памяти */ | ||||||
|   pTmp = pTMMAPNode; |   pTmp = pTMMAPNode; | ||||||
|   while(pTmp != NULL) |   while (pTmp != NULL) { | ||||||
|   { |     if ((phy_addr >= pTmp->Start_P) && | ||||||
|     if( (phy_addr >= pTmp->Start_P) && ( (phy_addr + size) <= (pTmp->Start_P + pTmp->length) ) ) |         ((phy_addr + size) <= (pTmp->Start_P + pTmp->length))) { | ||||||
|     { |  | ||||||
|       pTmp->refcount++; /* referrence count increase by 1  */ |       pTmp->refcount++; /* referrence count increase by 1  */ | ||||||
|       return (void *)(pTmp->Start_V + phy_addr - pTmp->Start_P); |       return (void *)(pTmp->Start_V + phy_addr - pTmp->Start_P); | ||||||
|     } |     } | ||||||
|     pTmp = pTmp->next; |     pTmp = pTmp->next; | ||||||
|   } |   } | ||||||
|   /* not mmaped yet */ |   /* not mmaped yet */ | ||||||
|   if(fd < 0) |   if (fd < 0) { | ||||||
|   { |  | ||||||
|     /* dev not opened yet, so open it */ |     /* dev not opened yet, so open it */ | ||||||
|     fd = open (dev, O_RDWR | O_SYNC); |     fd = open(dev, O_RDWR | O_SYNC); | ||||||
|     if(fd < 0) |     if (fd < 0) { | ||||||
|     { |  | ||||||
|       printf("memmap():open %s error!\n", dev); |       printf("memmap():open %s error!\n", dev); | ||||||
|       return NULL; |       return NULL; | ||||||
|     } |     } | ||||||
|  | @ -104,17 +94,16 @@ void * memmap(unsigned long phy_addr, unsigned long size) | ||||||
|   phy_addr_in_page = phy_addr & PAGE_SIZE_MASK; |   phy_addr_in_page = phy_addr & PAGE_SIZE_MASK; | ||||||
|   page_diff = phy_addr - phy_addr_in_page; |   page_diff = phy_addr - phy_addr_in_page; | ||||||
|   /* size in page_size */ |   /* size in page_size */ | ||||||
|   size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE; |   size_in_page = ((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE; | ||||||
|   addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page); |   addr = mmap((void *)0, size_in_page, PROT_READ | PROT_WRITE, MAP_SHARED, fd, | ||||||
|   if(addr == MAP_FAILED) |               phy_addr_in_page); | ||||||
|   { |   if (addr == MAP_FAILED) { | ||||||
|     printf("memmap():mmap @ 0x%x error!\n", phy_addr_in_page); |     printf("memmap():mmap @ 0x%lx error!\n", phy_addr_in_page); | ||||||
|     return NULL; |     return NULL; | ||||||
|   } |   } | ||||||
|   /* add this mmap to MMAP Node */ |   /* add this mmap to MMAP Node */ | ||||||
|   pNew = (TMMAP_Node_t *)malloc(sizeof(TMMAP_Node_t)); |   pNew = (TMMAP_Node_t *)malloc(sizeof(TMMAP_Node_t)); | ||||||
|   if(NULL == pNew) |   if (NULL == pNew) { | ||||||
|   { |  | ||||||
|     printf("memmap():malloc new node failed!\n"); |     printf("memmap():malloc new node failed!\n"); | ||||||
|     return NULL; |     return NULL; | ||||||
|   } |   } | ||||||
|  | @ -123,150 +112,134 @@ void * memmap(unsigned long phy_addr, unsigned long size) | ||||||
|   pNew->length = size_in_page; |   pNew->length = size_in_page; | ||||||
|   pNew->refcount = 1; |   pNew->refcount = 1; | ||||||
|   pNew->next = NULL; |   pNew->next = NULL; | ||||||
|   if(pTMMAPNode == NULL) |   if (pTMMAPNode == NULL) { | ||||||
|   { |  | ||||||
|     pTMMAPNode = pNew; |     pTMMAPNode = pNew; | ||||||
|   } |   } else { | ||||||
|   else |  | ||||||
|   { |  | ||||||
|     pTmp = pTMMAPNode; |     pTmp = pTMMAPNode; | ||||||
|     while(pTmp->next != NULL) |     while (pTmp->next != NULL) { | ||||||
|     { |  | ||||||
|       pTmp = pTmp->next; |       pTmp = pTmp->next; | ||||||
|     } |     } | ||||||
|     pTmp->next = pNew; |     pTmp->next = pNew; | ||||||
|   } |   } | ||||||
|   return (void *)(addr+page_diff); |   return (void *)(addr + page_diff); | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| unsigned long GetValueRegister(unsigned long adress) | unsigned long GetValueRegister(unsigned long adress) { | ||||||
| { |  | ||||||
|   void *pMem = NULL; |   void *pMem = NULL; | ||||||
|   unsigned long value = -1; |   unsigned long value = -1; | ||||||
|   jmp_buf sigbus_jmpbuf; |   jmp_buf sigbus_jmpbuf; | ||||||
|   sigbus_jmp = &sigbus_jmpbuf; |   sigbus_jmp = &sigbus_jmpbuf; | ||||||
|   if(sigsetjmp(sigbus_jmpbuf, 1) == 0) |   if (sigsetjmp(sigbus_jmpbuf, 1) == 0) { | ||||||
|   { |     pMem = memmap(adress, DEFAULT_MD_LEN); | ||||||
|     pMem = memmap(adress,DEFAULT_MD_LEN); |     if (pMem == NULL) { | ||||||
|     if (pMem == NULL) |  | ||||||
|     { |  | ||||||
|       printf("memmap failed!\n"); |       printf("memmap failed!\n"); | ||||||
|       return -1; |       return -1; | ||||||
|     } |     } | ||||||
|     value = *(unsigned int*)pMem; //читаем региср
 |     value = *(unsigned int *)pMem; //читаем региср
 | ||||||
|   } |   } | ||||||
|   return value; |   return value; | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| int SetValueRegister(unsigned long adress, unsigned long value) | int SetValueRegister(unsigned long adress, unsigned long value) { | ||||||
| { |  | ||||||
|   void *pMem = NULL; |   void *pMem = NULL; | ||||||
|   pMem = memmap(adress,DEFAULT_MD_LEN); |   pMem = memmap(adress, DEFAULT_MD_LEN); | ||||||
|   if (pMem == NULL) |   if (pMem == NULL) { | ||||||
|   { |  | ||||||
|     printf("memmap failed!\n"); |     printf("memmap failed!\n"); | ||||||
|     return -1; |     return -1; | ||||||
|   } |   } | ||||||
|   *(unsigned int*)pMem = value; //пишем в регистр
 |   *(unsigned int *)pMem = value; //пишем в регистр
 | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| void get_chip_gpio_adress(unsigned long *Chip_Id, unsigned long *GPIO_Groups, unsigned long *GPIO_Base, unsigned long *GPIO_Offset) | void get_chip_gpio_adress(unsigned long *Chip_Id, unsigned long *GPIO_Groups, | ||||||
| { |                           unsigned long *GPIO_Base, | ||||||
|   switch (*Chip_Id) |                           unsigned long *GPIO_Offset) { | ||||||
|   { |   *GPIO_Offset = 0x10000; | ||||||
|  | 
 | ||||||
|  |   switch (*Chip_Id) { | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516A100 одна группа
 |   // Default: 0x3516A100 одна группа
 | ||||||
|     //Hi3516Av100	A7 @ 600 MHz	0x2014_0000
 |   // Hi3516Av100	A7 @ 600 MHz	0x2014_0000
 | ||||||
|   case 0x3516A100: |   case 0x3516A100: | ||||||
|     *GPIO_Groups = 17; //пропустить G15
 |     *GPIO_Groups = 17; //пропустить G15
 | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|     //Default: 0x3516A100
 |   // Default: 0x3516A100
 | ||||||
|     //Hi3516Dv100	A7 @600 MHz	0x2014_0000
 |   // Hi3516Dv100	A7 @600 MHz	0x2014_0000
 | ||||||
|   case 0x3516D100: |   case 0x3516D100: | ||||||
|     *GPIO_Groups = 15; |     *GPIO_Groups = 15; | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|    //Hi3518Ev100	ARM926 @ 440 MHz	0x2014_0000
 |   // Hi3518Ev100	ARM926 @ 440 MHz	0x2014_0000
 | ||||||
|   case 0x35180100: |   case 0x35180100: | ||||||
|     *GPIO_Groups = 12; |     *GPIO_Groups = 12; | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|      *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Hi3516Cv100	ARM926 @ 440 MHz	0x2014_0000
 |   // Hi3516Cv100	ARM926 @ 440 MHz	0x2014_0000
 | ||||||
|   case 0x3516C100: |   case 0x3516C100: | ||||||
|     *GPIO_Groups = 12; |     *GPIO_Groups = 12; | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516C300
 |   // Default: 0x3516C300
 | ||||||
|     //Hi3516Cv300	ARM926 @ 800 MHz	0x1214_0000
 |   // Hi3516Cv300	ARM926 @ 800 MHz	0x1214_0000
 | ||||||
|   case 0x3516C300: |   case 0x3516C300: | ||||||
|     *GPIO_Groups = 9; |     *GPIO_Groups = 9; | ||||||
|     *GPIO_Base = 0x12140000; |     *GPIO_Base = 0x12140000; | ||||||
|       *GPIO_Offset = 0x1000; |     break; | ||||||
|  |   case 0x3516A300: | ||||||
|  |     *GPIO_Groups = 12; | ||||||
|  |     *GPIO_Base = 0x120D0000; | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516E200
 |   // Default: 0x3516E200
 | ||||||
|     //Hi3516Ev200	A7 @ 900MHz	0x120B_0000
 |   // Hi3516Ev200	A7 @ 900MHz	0x120B_0000
 | ||||||
|   case 0x3516E200: |   case 0x3516E200: | ||||||
|     *GPIO_Groups = 9; |     *GPIO_Groups = 9; | ||||||
|     *GPIO_Base = 0x120B0000; |     *GPIO_Base = 0x120B0000; | ||||||
|       *GPIO_Offset = 0x1000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516E300
 |   // Default: 0x3516E300
 | ||||||
|     //Hi3516Ev300	A7 @ 900MHz	0x120B_0000
 |   // Hi3516Ev300	A7 @ 900MHz	0x120B_0000
 | ||||||
|   case 0x3516E300: |   case 0x3516E300: | ||||||
|     *GPIO_Groups = 10; |     *GPIO_Groups = 10; | ||||||
|     *GPIO_Base = 0x120B0000; |     *GPIO_Base = 0x120B0000; | ||||||
|       *GPIO_Offset = 0x1000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3518E200 одна группа
 |   // Default: 0x3518E200 одна группа
 | ||||||
|     //Hi3516Cv200	ARM926 @ 540 MHz	0x2014_0000
 |   // Hi3516Cv200	ARM926 @ 540 MHz	0x2014_0000
 | ||||||
|   case 0x3516C200: |   case 0x3516C200: | ||||||
|     *GPIO_Groups = 9; |     *GPIO_Groups = 9; | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|     //Default: 0x3518E200
 |   // Default: 0x3518E200
 | ||||||
|     //Hi3518Ev200	ARM926 @ 540 MHz	0x2014_0000
 |   // Hi3518Ev200	ARM926 @ 540 MHz	0x2014_0000
 | ||||||
|   case 0x3518E200: |   case 0x3518E200: | ||||||
|     *GPIO_Groups = 9; |     *GPIO_Groups = 9; | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|     //Default: 0x3518E200
 |   // Default: 0x3518E200
 | ||||||
|     //Hi3518Ev201	ARM926 @ 540 MHz	0x2014_0000
 |   // Hi3518Ev201	ARM926 @ 540 MHz	0x2014_0000
 | ||||||
|   case 0x3518E201: |   case 0x3518E201: | ||||||
|     *GPIO_Groups = 9; |     *GPIO_Groups = 9; | ||||||
|     *GPIO_Base = 0x20140000; |     *GPIO_Base = 0x20140000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x35350100: |   case 0x35350100: | ||||||
|     *GPIO_Groups = 15; |     *GPIO_Groups = 15; | ||||||
|     *GPIO_Base = 0x20150000; |     *GPIO_Base = 0x20150000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x3536C100: |   case 0x3536C100: | ||||||
|     *GPIO_Groups = 14; //пропустить G4
 |     *GPIO_Groups = 14; //пропустить G4
 | ||||||
|     *GPIO_Base = 0x12150000; |     *GPIO_Base = 0x12150000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x3536D100: |   case 0x3536D100: | ||||||
|     *GPIO_Groups = 6; |     *GPIO_Groups = 6; | ||||||
|     *GPIO_Base = 0x12150000; |     *GPIO_Base = 0x12150000; | ||||||
|       *GPIO_Offset = 0x10000; |  | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   default: |   default: | ||||||
|  | @ -278,8 +251,7 @@ void get_chip_gpio_adress(unsigned long *Chip_Id, unsigned long *GPIO_Groups, un | ||||||
|   } |   } | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| void get_chip_id(unsigned long *Chip_Id, unsigned char *cpu, unsigned char *hardware) | void get_chip_id(unsigned long *Chip_Id, char *cpu, char *hardware) { | ||||||
| { |  | ||||||
|   unsigned long SCBASE; |   unsigned long SCBASE; | ||||||
|   unsigned long SCSYSID0 = 0xEE0; |   unsigned long SCSYSID0 = 0xEE0; | ||||||
|   unsigned long SCSYSID1 = 0xEE4; |   unsigned long SCSYSID1 = 0xEE4; | ||||||
|  | @ -292,229 +264,245 @@ void get_chip_id(unsigned long *Chip_Id, unsigned char *cpu, unsigned char *hard | ||||||
| 
 | 
 | ||||||
|   //---------------------------------------------
 |   //---------------------------------------------
 | ||||||
|   SCBASE = 0x20050000; |   SCBASE = 0x20050000; | ||||||
|   if(GetValueRegister(SCBASE)==-1) //читаем сначала один базовый адрес
 |   if (GetValueRegister(SCBASE) == -1) //читаем сначала один базовый адрес
 | ||||||
|   { |   { | ||||||
|     SCBASE = 0x12020000; |     SCBASE = 0x12020000; | ||||||
|     if(GetValueRegister(SCBASE)==-1) //затем читаем другой
 |     if (GetValueRegister(SCBASE) == -1) //затем читаем другой
 | ||||||
|     { |     { | ||||||
|       sprintf(cpu,"unknown"); |       sprintf(cpu, "unknown"); | ||||||
|       *Chip_Id = 0; |       *Chip_Id = 0; | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   //---------------------------------------------
 |   //---------------------------------------------
 | ||||||
|   if((GetValueRegister(SCBASE+SCSYSID0) & 0xFF000000) >> 24 == 0x35) //если старший байт = 0x35 значит все ID в одном регистре
 |   if ((GetValueRegister(SCBASE + SCSYSID0) & 0xFF000000) >> 24 == | ||||||
|  |       0x35) //если старший байт = 0x35 значит все ID в одном регистре
 | ||||||
|   { |   { | ||||||
|     *Chip_Id = GetValueRegister(SCBASE+SCSYSID0); |     *Chip_Id = GetValueRegister(SCBASE + SCSYSID0); | ||||||
|     Chip_Ver = 0; |     Chip_Ver = 0; | ||||||
|   } |   } else { | ||||||
|   else |     Chip_Ver = (GetValueRegister(SCBASE + SCSYSID0) & 0xFF000000) >> | ||||||
|   { |                24; //старший байт регистра может быть версия чипа
 | ||||||
|     Chip_Ver = (GetValueRegister(SCBASE+SCSYSID0) & 0xFF000000) >> 24; //старший байт регистра может быть версия чипа
 |     SCSYSID0 = GetValueRegister(SCBASE + SCSYSID0) & | ||||||
|     SCSYSID0 = GetValueRegister(SCBASE+SCSYSID0) & 0xFF; //читаем младший байт регистра
 |                0xFF; //читаем младший байт регистра
 | ||||||
|     SCSYSID1 = GetValueRegister(SCBASE+SCSYSID1) & 0xFF; //читаем младший байт регистра
 |     SCSYSID1 = GetValueRegister(SCBASE + SCSYSID1) & | ||||||
|     SCSYSID2 = GetValueRegister(SCBASE+SCSYSID2) & 0xFF; //читаем младший байт регистра
 |                0xFF; //читаем младший байт регистра
 | ||||||
|     SCSYSID3 = GetValueRegister(SCBASE+SCSYSID3) & 0xFF; //читаем младший байт регистра
 |     SCSYSID2 = GetValueRegister(SCBASE + SCSYSID2) & | ||||||
|     *Chip_Id = (SCSYSID3<<24)+(SCSYSID2<<16)+(SCSYSID1<<8)+(SCSYSID0); |                0xFF; //читаем младший байт регистра
 | ||||||
|  |     SCSYSID3 = GetValueRegister(SCBASE + SCSYSID3) & | ||||||
|  |                0xFF; //читаем младший байт регистра
 | ||||||
|  |     *Chip_Id = | ||||||
|  |         (SCSYSID3 << 24) + (SCSYSID2 << 16) + (SCSYSID1 << 8) + (SCSYSID0); | ||||||
|   } |   } | ||||||
|   //---------------------------------------------
 |   //---------------------------------------------
 | ||||||
|   if((*Chip_Id==0x3518E200)&(Chip_Ver==0x01)) *Chip_Id=0x3516C200; |   if ((*Chip_Id == 0x3518E200) & (Chip_Ver == 0x01)) | ||||||
|   if((*Chip_Id==0x3518E200)&(Chip_Ver==0x02)) *Chip_Id=0x3518E200; |     *Chip_Id = 0x3516C200; | ||||||
|   if((*Chip_Id==0x3518E200)&(Chip_Ver==0x03)) *Chip_Id=0x3518E201; |   if ((*Chip_Id == 0x3518E200) & (Chip_Ver == 0x02)) | ||||||
|  |     *Chip_Id = 0x3518E200; | ||||||
|  |   if ((*Chip_Id == 0x3518E200) & (Chip_Ver == 0x03)) | ||||||
|  |     *Chip_Id = 0x3518E201; | ||||||
|   //---------------------------------------------
 |   //---------------------------------------------
 | ||||||
|   if((*Chip_Id==0x3516A100)&(Chip_Ver==0x01)) *Chip_Id=0x3516A100; |   if ((*Chip_Id == 0x3516A100) & (Chip_Ver == 0x01)) | ||||||
|   if((*Chip_Id==0x3516A100)&(Chip_Ver==0x02)) *Chip_Id=0x3516D100; |     *Chip_Id = 0x3516A100; | ||||||
|  |   if ((*Chip_Id == 0x3516A100) & (Chip_Ver == 0x02)) | ||||||
|  |     *Chip_Id = 0x3516D100; | ||||||
|   //---------------------------------------------
 |   //---------------------------------------------
 | ||||||
|   switch (*Chip_Id) |   switch (*Chip_Id) { | ||||||
|   { |  | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516A100
 |   // Default: 0x3516A100
 | ||||||
|   case 0x3516A100: |   case 0x3516A100: | ||||||
|       sprintf(cpu,"Hi3516Av100"); |     sprintf(cpu, "Hi3516Av100"); | ||||||
|       sprintf(hardware,"A7 @ 600 MHz"); |     sprintf(hardware, "A7 @ 600 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516A100
 |   // Default: 0x3516A100
 | ||||||
|   case 0x3516D100: |   case 0x3516D100: | ||||||
|       sprintf(cpu,"Hi3516Dv100"); |     sprintf(cpu, "Hi3516Dv100"); | ||||||
|       sprintf(hardware,"A7 @ 600 MHz"); |     sprintf(hardware, "A7 @ 600 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x35180100
 |   // Default: 0x35180100
 | ||||||
|   case 0x35180100: |   case 0x35180100: | ||||||
|       sprintf(cpu,"Hi3518Ev100"); |     sprintf(cpu, "Hi3518Ev100"); | ||||||
|       sprintf(hardware,"ARM926 @ 440 MHz"); |     sprintf(hardware, "ARM926 @ 440 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x3516C100: |   case 0x3516C100: | ||||||
|       sprintf(cpu,"Hi3516Cv100"); |     sprintf(cpu, "Hi3516Cv100"); | ||||||
|       sprintf(hardware,"ARM926 @ 440 MHz"); |     sprintf(hardware, "ARM926 @ 440 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516C300
 |   // Default: 0x3516C300
 | ||||||
|   case 0x3516C300: |   case 0x3516C300: | ||||||
|       sprintf(cpu,"Hi3516Cv300"); |     sprintf(cpu, "Hi3516Cv300"); | ||||||
|       sprintf(hardware,"ARM926 @ 800 MHz"); |     sprintf(hardware, "ARM926 @ 800 MHz"); | ||||||
|  |     break; | ||||||
|  |   case 0x3516A300: | ||||||
|  |     sprintf(cpu, "Hi3516Av300"); | ||||||
|  |     sprintf(hardware, "A7 dual core @ 900MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516E200
 |   // Default: 0x3516E200
 | ||||||
|   case 0x3516E200: |   case 0x3516E200: | ||||||
|       sprintf(cpu,"Hi3516Ev200"); |     sprintf(cpu, "Hi3516Ev200"); | ||||||
|       sprintf(hardware,"A7 @ 900MHz"); |     sprintf(hardware, "A7 @ 900MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3516E300
 |   // Default: 0x3516E300
 | ||||||
|   case 0x3516E300: |   case 0x3516E300: | ||||||
|       sprintf(cpu,"Hi3516Ev300"); |     sprintf(cpu, "Hi3516Ev300"); | ||||||
|       sprintf(hardware,"A7 @ 900MHz"); |     sprintf(hardware, "A7 @ 900MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|     //Default: 0x3518E200 одна группа
 |   // Default: 0x3518E200 одна группа
 | ||||||
|   case 0x3516C200: |   case 0x3516C200: | ||||||
|       sprintf(cpu,"Hi3516Cv200"); |     sprintf(cpu, "Hi3516Cv200"); | ||||||
|       sprintf(hardware,"ARM926 @ 540 MHz"); |     sprintf(hardware, "ARM926 @ 540 MHz"); | ||||||
|     break; |     break; | ||||||
|     //Default: 0x3518E200
 |   // Default: 0x3518E200
 | ||||||
|   case 0x3518E200: |   case 0x3518E200: | ||||||
|       sprintf(cpu,"Hi3518Ev200"); |     sprintf(cpu, "Hi3518Ev200"); | ||||||
|       sprintf(hardware,"ARM926 @ 540 MHz"); |     sprintf(hardware, "ARM926 @ 540 MHz"); | ||||||
|     break; |     break; | ||||||
|     //Default: 0x3518E200
 |   // Default: 0x3518E200
 | ||||||
|   case 0x3518E201: |   case 0x3518E201: | ||||||
|       sprintf(cpu,"Hi3518Ev201"); |     sprintf(cpu, "Hi3518Ev201"); | ||||||
|       sprintf(hardware,"ARM926 @ 540 MHz"); |     sprintf(hardware, "ARM926 @ 540 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x35350100: |   case 0x35350100: | ||||||
|       sprintf(cpu,"Hi3535v100"); |     sprintf(cpu, "Hi3535v100"); | ||||||
|       sprintf(hardware,"A9 dual-core @ 900 MHz"); |     sprintf(hardware, "A9 dual-core @ 900 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x3536C100: |   case 0x3536C100: | ||||||
|       sprintf(cpu,"Hi3536Cv100"); |     sprintf(cpu, "Hi3536Cv100"); | ||||||
|       sprintf(hardware,"A7 dual-core @ 1.3 GHz"); |     sprintf(hardware, "A7 dual-core @ 1.3 GHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   case 0x3536D100: |   case 0x3536D100: | ||||||
|       sprintf(cpu,"Hi3536Dv100"); |     sprintf(cpu, "Hi3536Dv100"); | ||||||
|       sprintf(hardware,"A7 @ 850 MHz"); |     sprintf(hardware, "A7 @ 850 MHz"); | ||||||
|     break; |     break; | ||||||
|   //-------------------------------------------
 |   //-------------------------------------------
 | ||||||
|   default: //чип не поддерживается
 |   default: //чип не поддерживается
 | ||||||
|       sprintf(cpu,"unknown"); |     sprintf(cpu, "unknown"); | ||||||
|       sprintf(hardware,"unknown"); |     sprintf(hardware, "unknown"); | ||||||
|     break; |     break; | ||||||
|     //---------------------------------
 |     //---------------------------------
 | ||||||
|   } |   } | ||||||
| } | } | ||||||
| //************************************************************
 | //************************************************************
 | ||||||
| int main(int argc, char *argv[]) | int main(int argc, char *argv[]) { | ||||||
| { |  | ||||||
|   unsigned long Chip_Id = 0; |   unsigned long Chip_Id = 0; | ||||||
|   unsigned char CPU[50]={""}; |   char CPU[50] = {""}; | ||||||
|   unsigned char HARDWARE[50]={""}; |   char HARDWARE[50] = {""}; | ||||||
|   unsigned long GPIO_Groups,GPIO_Base,GPIO_Offset; |   unsigned long GPIO_Groups, GPIO_Base, GPIO_Offset; | ||||||
|   unsigned long adress = 0; |   unsigned long adress = 0; | ||||||
|   unsigned long direct = 0; |   unsigned long direct = 0; | ||||||
|   unsigned long value = 0; |   unsigned long value = 0; | ||||||
|   unsigned long OldValue[20]; |   unsigned long OldValue[20]; | ||||||
|   int bit,old_bit,new_bit; |   int bit, old_bit, new_bit; | ||||||
|   int i,group,mask; |   int i, group, mask; | ||||||
|   int HeaderByte,Skip,SkipPin; |   int HeaderByte, Skip, SkipPin; | ||||||
|   //---------------------------------------------------------------
 |   //---------------------------------------------------------------
 | ||||||
|   if(set_handler()==-1) |   if (set_handler() == -1) { | ||||||
|   { |  | ||||||
|     printf("Set handler Error!\n"); |     printf("Set handler Error!\n"); | ||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|   get_chip_id(&Chip_Id,&CPU[0],&HARDWARE[0]); |   get_chip_id(&Chip_Id, &CPU[0], &HARDWARE[0]); | ||||||
|   printf("For skip pin exaple: %s 12 14 ...\n",argv[0]); |   printf("For skip pin exaple: %s 12 14 ...\n", argv[0]); | ||||||
|   printf("================ Hisilicon GPIO Scaner (2021) OpenIPC.org collective =================\n"); |   printf("================ Hisilicon GPIO Scaner (2021) OpenIPC.org collective " | ||||||
|   printf("Chip_Id: 0x%08X, CPU: %s, Hardware: %s\n",Chip_Id,CPU,HARDWARE); |          "=================\n"); | ||||||
|   if(!strcmp(CPU,"unknown")) //чип не поддерживается
 |   printf("Chip_Id: 0x%08lX, CPU: %s, Hardware: %s\n", Chip_Id, CPU, HARDWARE); | ||||||
|  |   if (!strcmp(CPU, "unknown")) //чип не поддерживается
 | ||||||
|   { |   { | ||||||
|     printf("This CPU not support!\n"); |     printf("This CPU not support!\n"); | ||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|   get_chip_gpio_adress(&Chip_Id,&GPIO_Groups,&GPIO_Base,&GPIO_Offset); |   get_chip_gpio_adress(&Chip_Id, &GPIO_Groups, &GPIO_Base, &GPIO_Offset); | ||||||
|   //-----------------------------
 |   //-----------------------------
 | ||||||
|   for(group=0; group<GPIO_Groups; group++) |   for (group = 0; group < GPIO_Groups; group++) { | ||||||
|   { |     adress = GPIO_Base + (group * GPIO_Offset) + 0x3fc; //регистр данных портов
 | ||||||
|     adress=GPIO_Base+(group*GPIO_Offset)+0x3fc;  //регистр данных портов
 |  | ||||||
|     value = GetValueRegister(adress); |     value = GetValueRegister(adress); | ||||||
|     OldValue[group]=value; //запоминаем в массив значение
 |     OldValue[group] = value; //запоминаем в массив значение
 | ||||||
|     printf("Gr:%2d, Addr:0x%08lX, Data:0x%02lX = 0b",group,adress,value); |     printf("Gr:%2d, Addr:0x%08lX, Data:0x%02lX = 0b", group, adress, value); | ||||||
|     print_bin(value); //выводим бинарный вид
 |     print_bin(value); //выводим бинарный вид
 | ||||||
|     adress=GPIO_Base+(group*GPIO_Offset)+0x400; //регистр направления портов
 |     adress = | ||||||
|     direct=GetValueRegister(adress); |         GPIO_Base + (group * GPIO_Offset) + 0x400; //регистр направления портов
 | ||||||
|     printf(", Addr:0x%08lX, Dir:0x%02lX = 0b",adress,direct); |     direct = GetValueRegister(adress); | ||||||
|  |     printf(", Addr:0x%08lX, Dir:0x%02lX = 0b", adress, direct); | ||||||
|     print_bin(direct); |     print_bin(direct); | ||||||
|     printf("\n"); |     printf("\n"); | ||||||
|   } |   } | ||||||
|   if(argc > 1) |   if (argc > 1) { | ||||||
|   { |     printf("-------------------------------------------------------------------" | ||||||
|     printf("--------------------------------------------------------------------------------------\n"); |            "-------------------\n"); | ||||||
|     for (i = 1; i < argc; i++) printf("Skip Pin: GPIO%s\n",argv[i]); |     for (i = 1; i < argc; i++) | ||||||
|  |       printf("Skip Pin: GPIO%s\n", argv[i]); | ||||||
|   } |   } | ||||||
|   printf("--------------------------------------------------------------------------------------\n"); |   printf("---------------------------------------------------------------------" | ||||||
|  |          "-----------------\n"); | ||||||
|   printf("While change value...\n"); |   printf("While change value...\n"); | ||||||
|   //-----------------------------
 |   //-----------------------------
 | ||||||
|   while(1) |   while (1) { | ||||||
|   { |     for (group = 0; group < GPIO_Groups; group++) { | ||||||
|     for(group=0; group<GPIO_Groups; group++) |       adress = | ||||||
|     { |           GPIO_Base + (group * GPIO_Offset) + 0x3fc; //регистр данных портов
 | ||||||
|       adress=GPIO_Base+(group*GPIO_Offset)+0x3fc; //регистр данных портов
 |  | ||||||
|       value = GetValueRegister(adress); |       value = GetValueRegister(adress); | ||||||
|       if(OldValue[group]!=value) //старый и новый байты не равны
 |       if (OldValue[group] != value) //старый и новый байты не равны
 | ||||||
|       { |       { | ||||||
|     	HeaderByte=0; |         HeaderByte = 0; | ||||||
|         for (bit = 7; bit >= 0; bit--) //цикл побитного сравнения
 |         for (bit = 7; bit >= 0; bit--) //цикл побитного сравнения
 | ||||||
|         { |         { | ||||||
|           old_bit = (OldValue[group]>>bit)&1; |           old_bit = (OldValue[group] >> bit) & 1; | ||||||
| 	      new_bit = (value>>bit)&1; |           new_bit = (value >> bit) & 1; | ||||||
| 	      Skip=0; |           Skip = 0; | ||||||
|           //-------------------------------
 |           //-------------------------------
 | ||||||
| 	      if(argc > 1) //Есть пин для пропуска
 |           if (argc > 1) //Есть пин для пропуска
 | ||||||
|           { |           { | ||||||
| 	        for (i = 1; i < argc; i++) |             for (i = 1; i < argc; i++) { | ||||||
| 	        { |               SkipPin = atoi(argv[i]); | ||||||
| 	          SkipPin=atoi(argv[i]); |               if (((group * 8) + bit) == SkipPin) | ||||||
| 	          if(((group*8)+bit)==SkipPin) Skip=1; |                 Skip = 1; | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|           //-------------------------------
 |           //-------------------------------
 | ||||||
| 	      if(Skip==0) |           if (Skip == 0) { | ||||||
|  |             if (old_bit != new_bit) { | ||||||
|  |               if (HeaderByte == 0) //еще не выводили заголовок измененения байта
 | ||||||
|               { |               { | ||||||
|             if(old_bit!=new_bit) |                 printf("-------------------------------------------------------" | ||||||
|             { |                        "-------------------------------\n"); | ||||||
|               if(HeaderByte==0) //еще не выводили заголовок измененения байта
 |                 printf("Gr:%d, Addr:0x%08lX, Data:0x%02lX = 0b", group, adress, | ||||||
|               { |                        OldValue[group]); | ||||||
|                 printf("--------------------------------------------------------------------------------------\n"); |  | ||||||
|         	    printf("Gr:%d, Addr:0x%08lX, Data:0x%02lX = 0b",group,adress,OldValue[group]); |  | ||||||
|                 print_bin(OldValue[group]); |                 print_bin(OldValue[group]); | ||||||
|         	    printf(" --> 0x%02lX = 0b",value); |                 printf(" --> 0x%02lX = 0b", value); | ||||||
|                 print_bin(value); |                 print_bin(value); | ||||||
|                 printf("\n"); |                 printf("\n"); | ||||||
|         	    HeaderByte=1; |                 HeaderByte = 1; | ||||||
|               } |               } | ||||||
|               adress=GPIO_Base+(group*GPIO_Offset)+0x400; //регистр направления портов
 |               adress = GPIO_Base + (group * GPIO_Offset) + | ||||||
|  |                        0x400; //регистр направления портов
 | ||||||
|               direct = GetValueRegister(adress); |               direct = GetValueRegister(adress); | ||||||
|               direct = (direct>>bit)&1; //получили бит направления порта 0-вход 1-выход
 |               direct = (direct >> bit) & | ||||||
|               adress=GPIO_Base+(group*GPIO_Offset)+(1<<bit+2); |                        1; //получили бит направления порта 0-вход 1-выход
 | ||||||
|               if(direct==1) |               adress = GPIO_Base + (group * GPIO_Offset) + (1 << (bit + 2)); | ||||||
|               { |               if (direct == 1) { | ||||||
|                 mask=value & 1<<bit; |                 mask = value & 1 << bit; | ||||||
|                 printf("Mask: \"himm 0x%08lX 0x%02lX\", GPIO%d_%d, GPIO%d, Dir:Output, Level:%d\n",adress,mask,group,bit,(group*8)+bit,new_bit); |                 printf("Mask: \"himm 0x%08lX 0x%02X\", GPIO%d_%d, GPIO%d, " | ||||||
|               } |                        "Dir:Output, Level:%d\n", | ||||||
|               else |                        adress, mask, group, bit, (group * 8) + bit, new_bit); | ||||||
|               { |               } else { | ||||||
|                 mask=value & 1<<bit; |                 mask = value & 1 << bit; | ||||||
|                 printf("Mask: \"himm 0x%08lX 0x%02lX\", GPIO%d_%d, GPIO%d, Dir:Input, Level:%d\n",adress,mask,group,bit,(group*8)+bit,new_bit); |                 printf("Mask: \"himm 0x%08lX 0x%02X\", GPIO%d_%d, GPIO%d, " | ||||||
|  |                        "Dir:Input, Level:%d\n", | ||||||
|  |                        adress, mask, group, bit, (group * 8) + bit, new_bit); | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         OldValue[group]=value; //запоминаем новое значение
 |         OldValue[group] = value; //запоминаем новое значение
 | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     usleep(100000); |     usleep(100000); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue