first draft of pulling in sunxi functions

This commit is contained in:
Tony Kuker 2022-10-29 21:10:02 -05:00
parent c71c2a2b7a
commit 0c964578df
4 changed files with 462 additions and 8 deletions

View File

@ -13,6 +13,15 @@
"cstdint": "cpp",
"stdexcept": "cpp",
"deque": "cpp",
"vector": "cpp"
"vector": "cpp",
"compare": "cpp",
"cwchar": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"limits": "cpp",
"new": "cpp",
"string": "cpp",
"string_view": "cpp"
}
}

View File

@ -128,8 +128,8 @@ SRC_GPIO_TEST = \
gpiotest.cpp
SRC_GPIO_TEST += $(shell find ./hal -name '*.cpp')
vpath %.h ./ ./controllers ./devices ./monitor ./hal ./hal/boards ./rascsi ./rasctl ../BPI-WiringPi2/wiringPi/
vpath %.cpp ./ ./controllers ./devices ./monitor ./test ./hal ./hal/boards ./rascsi ./rasctl
vpath %.h ./ ./controllers ./devices ./monitor ./hal ./hal/boards ./hal/pi_defs ./rascsi ./rasctl ../BPI-WiringPi2/wiringPi/
vpath %.cpp ./ ./controllers ./devices ./monitor ./test ./hal ./hal/boards ./hal/pi_defs ./rascsi ./rasctl
vpath %.o ./$(OBJDIR)
vpath ./$(BINDIR)

View File

@ -1,13 +1,33 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
// for Raspberry Pi (And Banana Pi)
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// Copyright (c) 2012-2015 Ben Croston
// Copyright (C) 2022 akuker
//
// Large portions of this functionality were derived from c_gpio.c, which
// is part of the RPI.GPIO library available here:
// https://github.com/BPI-SINOVOIP/RPi.GPIO/blob/master/source/c_gpio.c
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// [ GPIO-SCSI bus ]
//https://github.com/BPI-SINOVOIP/RPi.GPIO/blob/master/source/bpi-m2p.h
//---------------------------------------------------------------------------
#include "hal/gpiobus_allwinner.h"
@ -23,6 +43,44 @@ extern int wiringPiMode;
bool GPIOBUS_Allwinner::Init(mode_e mode, board_type::rascsi_board_type_e rascsi_type)
{
GPIOBUS::Init(mode, rascsi_type);
int mem_fd;
uint8_t *gpio_mem;
uint8_t *r_gpio_mem;
uint32_t peri_base;
uint32_t gpio_base;
unsigned char buf[4];
FILE *fp;
char buffer[1024];
char hardware[1024];
int found = 0;
printf("enter to sunxi_setup\n");
// mmap the GPIO memory registers
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
return SETUP_DEVMEM_FAIL;
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
return SETUP_MALLOC_FAIL;
if ((uint32_t)gpio_mem % PAGE_SIZE)
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, SUNXI_GPIO_BASE);
pio_map = gpio_map + (SUNXI_GPIO_REG_OFFSET>>2);
//printf("gpio_mem[%x] gpio_map[%x] pio_map[%x]\n", gpio_mem, gpio_map, pio_map);
//R_PIO GPIO LMN
r_gpio_map = (uint32_t *)mmap( (caddr_t)0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, SUNXI_R_GPIO_BASE);
r_pio_map = r_gpio_map + (SUNXI_R_GPIO_REG_OFFSET>>2);
//printf("r_gpio_map[%x] r_pio_map[%x]\n", r_gpio_map, r_pio_map);
if ((uint32_t)gpio_map < 0)
return SETUP_MMAP_FAIL;
return SETUP_OK;
// wiringPiSetup();
// wiringPiMode = WPI_MODE_GPIO;
@ -426,3 +484,279 @@ uint32_t GPIOBUS_Allwinner::Acquire()
}
#pragma GCC diagnostic pop
int mtk_setup(void)
{
int gpio_mmap_fd = 0;
if ((gpio_mmap_fd = open("/dev/mem", O_RDWR|O_SYNC)) < 0) {
fprintf(stderr, "unable to open mmap file");
return -1;
}
gpio_mmap_reg = (uint8_t*)mmap(NULL, 8 * 1024, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, gpio_mmap_fd, 0x10005000);
if (gpio_mmap_reg == MAP_FAILED) {
perror("foo");
fprintf(stderr, "failed to mmap");
gpio_mmap_reg = NULL;
close(gpio_mmap_fd);
return -1;
}
printf("gpio_mmap_fd=%d, gpio_map=%x", gpio_mmap_fd, gpio_mmap_reg);
return SETUP_OK;
}
uint32_t GPIOBUS_Allwinner::sunxi_readl(volatile uint32_t *addr)
{
printf("sunxi_readl\n");
uint32_t val = 0;
uint32_t mmap_base = (uint32_t)addr & (~MAP_MASK);
uint32_t mmap_seek = ((uint32_t)addr - mmap_base) >> 2;
val = *(gpio_map + mmap_seek);
return val;
}
void GPIOBUS_Allwinner::sunxi_writel(volatile uint32_t *addr, uint32_t val)
{
printf("sunxi_writel\n");
uint32_t mmap_base = (uint32_t)addr & (~MAP_MASK);
uint32_t mmap_seek =( (uint32_t)addr - mmap_base) >> 2;
*(gpio_map + mmap_seek) = val;
}
int GPIOBUS_Allwinner::sunxi_setup(void)
{
int mem_fd;
uint8_t *gpio_mem;
uint8_t *r_gpio_mem;
uint32_t peri_base;
uint32_t gpio_base;
unsigned char buf[4];
FILE *fp;
char buffer[1024];
char hardware[1024];
int found = 0;
printf("enter to sunxi_setup\n");
// mmap the GPIO memory registers
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0)
return SETUP_DEVMEM_FAIL;
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
return SETUP_MALLOC_FAIL;
if ((uint32_t)gpio_mem % PAGE_SIZE)
gpio_mem += PAGE_SIZE - ((uint32_t)gpio_mem % PAGE_SIZE);
gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, SUNXI_GPIO_BASE);
pio_map = gpio_map + (SUNXI_GPIO_REG_OFFSET>>2);
//printf("gpio_mem[%x] gpio_map[%x] pio_map[%x]\n", gpio_mem, gpio_map, pio_map);
//R_PIO GPIO LMN
r_gpio_map = (uint32_t *)mmap( (caddr_t)0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, SUNXI_R_GPIO_BASE);
r_pio_map = r_gpio_map + (SUNXI_R_GPIO_REG_OFFSET>>2);
//printf("r_gpio_map[%x] r_pio_map[%x]\n", r_gpio_map, r_pio_map);
if ((uint32_t)gpio_map < 0)
return SETUP_MMAP_FAIL;
return SETUP_OK;
}
void GPIOBUS_Allwinner::sunxi_set_pullupdn(int gpio, int pud)
{
uint32_t regval = 0;
int bank = GPIO_BANK(gpio); //gpio >> 5
int index = GPIO_PUL_INDEX(gpio); // (gpio & 0x1f) >> 4
int offset = GPIO_PUL_OFFSET(gpio); // (gpio) & 0x0F) << 1
printf("sunxi_set_pullupdn\n");
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
/* DK, for PL and PM */
if(bank >= 11) {
bank -= 11;
pio = &((sunxi_gpio_reg_t *) r_pio_map)->gpio_bank[bank];
}
regval = *(&pio->PULL[0] + index);
regval &= ~(3 << offset);
regval |= pud << offset;
*(&pio->PULL[0] + index) = regval;
}
void GPIOBUS_Allwinner::sunxi_setup_gpio(int gpio, int direction, int pud)
{
uint32_t regval = 0;
int bank = GPIO_BANK(gpio); //gpio >> 5
int index = GPIO_CFG_INDEX(gpio); // (gpio & 0x1F) >> 3
int offset = GPIO_CFG_OFFSET(gpio); // ((gpio & 0x1F) & 0x7) << 2
printf("sunxi_setup_gpio\n");
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
/* DK, for PL and PM */
if(bank >= 11) {
bank -= 11;
pio = &((sunxi_gpio_reg_t *) r_pio_map)->gpio_bank[bank];
}
set_pullupdn(gpio, pud);
regval = *(&pio->CFG[0] + index);
regval &= ~(0x7 << offset); // 0xf?
if (INPUT == direction) {
*(&pio->CFG[0] + index) = regval;
} else if (OUTPUT == direction) {
regval |= (1 << offset);
*(&pio->CFG[0] + index) = regval;
} else {
printf("line:%dgpio number error\n",__LINE__);
}
}
// Contribution by Eric Ptak <trouch@trouch.com>
int GPIOBUS_Allwinner::sunxi_gpio_function(int gpio)
{
uint32_t regval = 0;
int bank = GPIO_BANK(gpio); //gpio >> 5
int index = GPIO_CFG_INDEX(gpio); // (gpio & 0x1F) >> 3
int offset = GPIO_CFG_OFFSET(gpio); // ((gpio & 0x1F) & 0x7) << 2
printf("sunxi_gpio_function\n");
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
/* DK, for PL and PM */
if(bank >= 11) {
bank -= 11;
pio = &((sunxi_gpio_reg_t *) r_pio_map)->gpio_bank[bank];
}
regval = *(&pio->CFG[0] + index);
regval >>= offset;
regval &= 7;
return regval; // 0=input, 1=output, 4=alt0
}
void GPIOBUS_Allwinner::sunxi_output_gpio(int gpio, int value)
{
int bank = GPIO_BANK(gpio); //gpio >> 5
int num = GPIO_NUM(gpio); // gpio & 0x1F
printf("gpio(%d) bank(%d) num(%d)\n", gpio, bank, num);
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
/* DK, for PL and PM */
if(bank >= 11) {
bank -= 11;
pio = &((sunxi_gpio_reg_t *) r_pio_map)->gpio_bank[bank];
}
if (value == 0)
*(&pio->DAT) &= ~(1 << num);
else
*(&pio->DAT) |= (1 << num);
}
int GPIOBUS_Allwinner::sunxi_input_gpio(int gpio)
{
uint32_t regval = 0;
int bank = GPIO_BANK(gpio); //gpio >> 5
int num = GPIO_NUM(gpio); // gpio & 0x1F
printf("gpio(%d) bank(%d) num(%d)\n", gpio, bank, num);
sunxi_gpio_t *pio = &((sunxi_gpio_reg_t *) pio_map)->gpio_bank[bank];
/* DK, for PL and PM */
if(bank >= 11) {
bank -= 11;
pio = &((sunxi_gpio_reg_t *) r_pio_map)->gpio_bank[bank];
}
regval = *(&pio->DAT);
regval = regval >> num;
regval &= 1;
return regval;
}
int GPIOBUS_Allwinner::bpi_piGpioLayout (void)
{
FILE *bpiFd ;
char buffer[1024];
char hardware[1024];
struct BPIBoards *board;
static int gpioLayout = -1 ;
if (gpioLayout != -1) // No point checking twice
return gpioLayout ;
bpi_found = 0; // -1: not init, 0: init but not found, 1: found
if ((bpiFd = fopen("/var/lib/bananapi/board.sh", "r")) == NULL) {
return -1;
}
while(!feof(bpiFd)) {
fgets(buffer, sizeof(buffer), bpiFd);
sscanf(buffer, "BOARD=%s", hardware);
//printf("BPI: buffer[%s] hardware[%s]\n",buffer, hardware);
// Search for board:
for (board = bpiboard ; board->name != NULL ; ++board) {
//printf("BPI: name[%s] hardware[%s]\n",board->name, hardware);
if (strcmp (board->name, hardware) == 0) {
//gpioLayout = board->gpioLayout;
gpioLayout = board->model; // BPI: use model to replace gpioLayout
//printf("BPI: name[%s] gpioLayout(%d)\n",board->name, gpioLayout);
if(gpioLayout >= 21) {
bpi_found = 1;
break;
}
}
}
if(bpi_found == 1) {
break;
}
}
fclose(bpiFd);
//printf("BPI: name[%s] gpioLayout(%d)\n",board->name, gpioLayout);
return gpioLayout ;
}
int GPIOBUS_Allwinner::bpi_get_rpi_info(rpi_info *info)
{
struct BPIBoards *board=bpiboard;
static int gpioLayout = -1 ;
char ram[64];
char manufacturer[64];
char processor[64];
char type[64];
gpioLayout = bpi_piGpioLayout () ;
printf("BPI: gpioLayout(%d)\n", gpioLayout);
if(bpi_found == 1) {
board = &bpiboard[gpioLayout];
printf("BPI: name[%s] gpioLayout(%d)\n",board->name, gpioLayout);
sprintf(ram, "%dMB", piMemorySize [board->mem]);
sprintf(type, "%s", piModelNames [board->model]);
//add by jackzeng
//jude mtk platform
if(strcmp(board->name, "bpi-r2") == 0){
bpi_found_mtk = 1;
printf("found mtk board\n");
}
sprintf(manufacturer, "%s", piMakerNames [board->maker]);
info->p1_revision = 3;
info->type = type;
info->ram = ram;
info->manufacturer = manufacturer;
if(bpi_found_mtk == 1){
info->processor = "MTK";
}else{
info->processor = "Allwinner";
}
strcpy(info->revision, "4001");
// pin_to_gpio = board->physToGpio ;
pinToGpio_BP = board->pinToGpio ;
physToGpio_BP = board->physToGpio ;
pinTobcm_BP = board->pinTobcm ;
//printf("BPI: name[%s] bType(%d) model(%d)\n",board->name, bType, board->model);
return 0;
}
return -1;
}

View File

@ -91,6 +91,97 @@ class GPIOBUS_Allwinner : public GPIOBUS
volatile uint32_t *pads = nullptr; // PADS register
static volatile uint32_t *gpio_map;
int bpi_piGpioLayout (void)
{
FILE *bpiFd ;
char buffer[1024];
char hardware[1024];
struct BPIBoards *board;
static int gpioLayout = -1 ;
if (gpioLayout != -1) // No point checking twice
return gpioLayout ;
bpi_found = 0; // -1: not init, 0: init but not found, 1: found
if ((bpiFd = fopen("/var/lib/bananapi/board.sh", "r")) == NULL) {
return -1;
}
while(!feof(bpiFd)) {
fgets(buffer, sizeof(buffer), bpiFd);
sscanf(buffer, "BOARD=%s", hardware);
//printf("BPI: buffer[%s] hardware[%s]\n",buffer, hardware);
// Search for board:
for (board = bpiboard ; board->name != NULL ; ++board) {
//printf("BPI: name[%s] hardware[%s]\n",board->name, hardware);
if (strcmp (board->name, hardware) == 0) {
//gpioLayout = board->gpioLayout;
gpioLayout = board->model; // BPI: use model to replace gpioLayout
//printf("BPI: name[%s] gpioLayout(%d)\n",board->name, gpioLayout);
if(gpioLayout >= 21) {
bpi_found = 1;
break;
}
}
}
if(bpi_found == 1) {
break;
}
}
fclose(bpiFd);
//printf("BPI: name[%s] gpioLayout(%d)\n",board->name, gpioLayout);
return gpioLayout ;
}
int bpi_get_rpi_info(rpi_info *info)
{
struct BPIBoards *board=bpiboard;
static int gpioLayout = -1 ;
char ram[64];
char manufacturer[64];
char processor[64];
char type[64];
gpioLayout = bpi_piGpioLayout () ;
printf("BPI: gpioLayout(%d)\n", gpioLayout);
if(bpi_found == 1) {
board = &bpiboard[gpioLayout];
printf("BPI: name[%s] gpioLayout(%d)\n",board->name, gpioLayout);
sprintf(ram, "%dMB", piMemorySize [board->mem]);
sprintf(type, "%s", piModelNames [board->model]);
//add by jackzeng
//jude mtk platform
if(strcmp(board->name, "bpi-r2") == 0){
bpi_found_mtk = 1;
printf("found mtk board\n");
}
sprintf(manufacturer, "%s", piMakerNames [board->maker]);
info->p1_revision = 3;
info->type = type;
info->ram = ram;
info->manufacturer = manufacturer;
if(bpi_found_mtk == 1){
info->processor = "MTK";
}else{
info->processor = "Allwinner";
}
strcpy(info->revision, "4001");
// pin_to_gpio = board->physToGpio ;
pinToGpio_BP = board->pinToGpio ;
physToGpio_BP = board->physToGpio ;
pinTobcm_BP = board->pinTobcm ;
//printf("BPI: name[%s] bType(%d) model(%d)\n",board->name, bType, board->model);
return 0;
}
return -1;
}
#if !defined(__x86_64__) && !defined(__X86__)
volatile uint32_t *level = nullptr; // GPIO input level
#endif
@ -132,4 +223,24 @@ class GPIOBUS_Allwinner : public GPIOBUS
array<uint32_t, 256> tblDatSet = {}; // Table setting table
#endif
uint32_t sunxi_readl(volatile uint32_t *addr);
void sunxi_writel(volatile uint32_t *addr, uint32_t val);
int sunxi_setup(void);
void sunxi_set_pullupdn(int gpio, int pud);
void sunxi_setup_gpio(int gpio, int direction, int pud);
int sunxi_gpio_function(int gpio);
void sunxi_output_gpio(int gpio, int value);
int sunxi_input_gpio(int gpio);
};