Private
Public Access
2
0

Add support for MIPS-based boards Omega2 and Linkit Smart 7688

Signed-off-by: Serge Vakulenko <vak@besm6.org>
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
Serge Vakulenko
2017-10-04 12:08:52 -07:00
committed by Brendan Le Foll
parent 668776fbfd
commit 6770be911b
14 changed files with 867 additions and 1 deletions

View File

@@ -166,12 +166,14 @@ if (DETECTED_ARCH STREQUAL "i586" OR DETECTED_ARCH STREQUAL "x86_64"
set (X86PLAT ON)
elseif (DETECTED_ARCH MATCHES "arm.*")
set (ARMPLAT ON)
elseif (DETECTED_ARCH MATCHES "mips")
set (MIPSPLAT ON)
elseif (DETECTED_ARCH STREQUAL "MOCK")
set (MOCKPLAT ON)
elseif (DETECTED_ARCH STREQUAL "PERIPHERALMAN")
set (PERIPHERALMAN ON)
else ()
message (FATAL_ERROR "Only x86, arm, PERIPHERALMAN and mock platforms currently supported")
message (FATAL_ERROR "Only x86, arm, mips, PERIPHERALMAN and mock platforms currently supported")
endif()
if (BUILDSWIGPYTHON OR BUILDTESTS)

View File

@@ -41,6 +41,11 @@ ARM
* [phyBOARD-Wega](../master/docs/phyboard-wega.md)
* [96Boards](../master/docs/96boards.md)
MIPS
---
* [Linkit Smart 7688](../master/docs/linkit_7688.md)
* [Onion Omega2](../master/docs/omega2.md)
FPGA
----
* [DE10-Nano](../master/docs/de_nano_soc.md)

View File

@@ -57,6 +57,8 @@ typedef enum {
MRAA_PHYBOARD_WEGA = 14, /**< The phyBOARD-Wega */
MRAA_DE_NANO_SOC = 15, /**< Terasic DE-Nano-SoC Board */
MRAA_UP2 = 16, /**< The UP^2 Board */
MRAA_MTK_LINKIT = 17, /**< Mediatek MT7688 based Linkit boards */
MRAA_MTK_OMEGA2 = 18, /**< MT7688 based Onion Omega2 board */
// USB platform extenders start at 256
MRAA_FTDI_FT4222 = 256, /**< FTDI FT4222 USB to i2c bridge */

View File

@@ -45,6 +45,8 @@ set(archdetect_c_code "
#error cmake_ARCH x86_64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
#error cmake_ARCH mips
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)

View File

@@ -56,6 +56,8 @@ Specific platform information for supported platforms is documented here:
- @ref firmata
- @ref grovepi
- @ref mock
- @ref linkit_7688
- @ref omega2
## DEBUGGING

65
docs/linkit_7688.md Normal file
View File

@@ -0,0 +1,65 @@
Linkit Smart 7688 {#linkit}
=================
The Linkit Smart 7688 is based on the MediaTek MT7688 system on a chip, which
includes a MIPS 24KEc 580 MHz processor and 128 megabytes of RAM.
Features:
* 20 GPIO pins
* 4 PWM pins
* 3 UART ports
* 1 SPI master port
* 1 SPI slave port (not supported by libmraa)
* 1 I2C port
* 1 I2S port (not supported by libmraa)
![Pinout](http://www.cnx-software.com/wp-content/uploads/2015/12/Link_Smart_7688_Pinout.png)
Revision Support
----------------
* Linkit Smart 7688
* Linkit Smart 7688 Duo
Pin Mapping
-----------
| MRAA Number | Physical Pin | Function |
|-------------|--------------|------------------------|
| --- | P0 | (Reset) |
| 1 | P1 | GPIO43 (Eth LED) |
| --- | P2 | (Eth RD+) |
| --- | P3 | (Eth RD-) |
| --- | P4 | (Eth TD+) |
| --- | P5 | (Eth TD-) |
| --- | P6 | (USB D+) |
| --- | P7 | (USB D-) |
| 8 | P8 | GPIO20, UART TX2, PWM2 |
| 9 | P9 | GPIO21, UART RX2, PWM3 |
| --- | GND | GND |
| --- | 3V3 | 3V3 |
| --- | VCC | VCC |
| --- | 5V | 5V |
| 10 | P10 | GPIO2, (I2S WS) |
| 11 | P11 | GPIO3, (I2S CLK) |
| 12 | P12 | GPIO0, (I2S SDI) |
| 13 | P13 | GPIO1, (I2S SDO) |
| 14 | P14 | GPIO37 (REF_CLK) |
| 15 | P15 | GPIO44 (WiFi LED) |
| 16 | P16 | GPIO46, UART RX1 |
| 17 | P17 | GPIO45, UART TX1 |
| 18 | P18 | GPIO13, UART RX0 |
| 19 | P19 | GPIO12, UART TX0 |
| 20 | P20 | GPIO5, I2C SDA |
| 21 | P21 | GPIO4, I2C SCL |
| 22 | P22 | SPI MOSI |
| 23 | P23 | SPI MISO |
| 24 | P24 | SPI SCK |
| 25 | P25 | GPIO6, SPI CS |
| 26 | P26 | GPIO18, PWM0 |
| 27 | P27 | GPIO19, PWM1 |
| 28 | P28 | GPIO17, (SPIS MOSI) |
| 29 | P29 | GPIO16, (SPIS MISO) |
| 30 | P30 | GPIO15, (SPIS SCK) |
| 31 | P31 | GPIO14, (SPIS CS) |

67
docs/omega2.md Normal file
View File

@@ -0,0 +1,67 @@
Onion Omega2 {#omega2}
============
The Omega2 board is based on the MediaTek MT7688 system on a chip, which
includes a MIPS 24KEc 580 MHz processor and 128 megabytes of RAM.
Features:
* 15 GPIO pins
* 2 PWM pins
* 2 UART ports
* 1 SPI master port
* 1 I2C port
* 1 I2S port (not supported by libmraa)
![Pinout](https://raw.githubusercontent.com/OnionIoT/Onion-Docs/master/Omega2/Documentation/Hardware-Overview/img/Omega-2-Pinout-Diagram.png)
Revision Support
----------------
* Omega2
* Omega2+
Pin Mapping
-----------
Left side:
| MRAA Number | Function |
|-------------|------------------------|
| --- | GND |
| 1 | GPIO11 |
| 2 | GPIO3, (I2S CLK) |
| 3 | GPIO2, (I2S WS) |
| 4 | GPIO17 |
| 5 | GPIO16 |
| 6 | GPIO15 |
| 7 | GPIO46, UART RX1 |
| 8 | GPIO45, UART TX1 |
| 9 | SPI MISO |
| 10 | SPI MOSI |
| 11 | SPI SCK |
| 12 | GPIO6, SPI CS |
| 13 | GPIO1, (I2S SDO) |
| 14 | GPIO0, (I2S SDI) |
| --- | (Reset) |
Right side:
| MRAA Number | Function |
|-------------|------------------------|
| --- | GND |
| --- | VIN 3V3 |
| --- | (USB D+) |
| --- | (USB D-) |
| 20 | GPIO13, UART RX0 |
| 21 | GPIO12, UART TX0 |
| 22 | FW RST |
| --- | VOUT 3V3 |
| --- | (Eth TX-) |
| --- | (Eth TX+) |
| --- | (Eth RX-) |
| --- | (Eth RX+) |
| 28 | GPIO18, PWM0 |
| 29 | GPIO19, PWM1 |
| 30 | GPIO4, I2C SCL |
| 31 | GPIO5, I2C SDA |

40
include/mips/mediatek.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* Author: Serge Vakulenko <vak@besm6.org>
* Copyright (c) 2017 Serge Vakulenko.
*
* 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.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "mraa_internal.h"
mraa_board_t *
mraa_mtk_linkit();
mraa_board_t *
mraa_mtk_omega2();
#ifdef __cplusplus
}
#endif

View File

@@ -65,6 +65,13 @@ mraa_platform_t mraa_x86_platform();
*/
mraa_platform_t mraa_arm_platform();
/**
* runtime detect running mips platforms
*
* @return mraa_platform_t of the init'ed platform
*/
mraa_platform_t mraa_mips_platform();
/**
* setup a mock platform
*

View File

@@ -97,6 +97,11 @@ set (mraa_LIB_ARM_SRCS_NOAUTO
${PROJECT_SOURCE_DIR}/src/arm/de_nano_soc.c
)
set (mraa_LIB_MIPS_SRCS_NOAUTO
${PROJECT_SOURCE_DIR}/src/mips/mips.c
${PROJECT_SOURCE_DIR}/src/mips/mediatek.c
)
set (mraa_LIB_MOCK_SRCS_NOAUTO
${PROJECT_SOURCE_DIR}/src/mock/mock.c
${PROJECT_SOURCE_DIR}/src/mock/mock_board.c
@@ -134,6 +139,11 @@ if (ARMPLAT)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DARMPLAT=1")
endif()
if (MIPSPLAT)
add_subdirectory(mips)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMIPSPLAT=1")
endif()
if (MOCKPLAT)
add_subdirectory(mock)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMOCKPLAT=1")

3
src/mips/CMakeLists.txt Normal file
View File

@@ -0,0 +1,3 @@
message (INFO " - Adding MIPS platforms")
set (mraa_LIB_PLAT_SRCS_NOAUTO ${mraa_LIB_SRCS_NOAUTO}
${mraa_LIB_MIPS_SRCS_NOAUTO} PARENT_SCOPE)

593
src/mips/mediatek.c Normal file
View File

@@ -0,0 +1,593 @@
/*
* Author: Serge Vakulenko <vak@besm6.org>
* Copyright (c) 2017 Serge Vakulenko.
*
* 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.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <mraa/common.h>
#include "mraa_internal.h"
#include "common.h"
#define MMAP_PATH "/dev/mem"
#define MT7628_GPIOMODE_BASE 0x10000000
#define MT7628_BLOCK_SIZE 0x1000
#define MT7628_GPIO_CTRL 0x600
#define MT7628_GPIO_DATA 0x620
#define MT7628_GPIO_SET 0x630
#define MT7628_GPIO_CLEAR 0x640
// MMAP
static uint8_t *mmap_reg = NULL;
static int mmap_fd = 0;
static int mmap_size;
static uint8_t *gpio_mmap_reg = NULL;
static int gpio_mmap_fd = 0;
static unsigned int mmap_count = 0;
static mraa_result_t
mtk_mmap_write(mraa_gpio_context dev, int value)
{
if (value) {
*(volatile uint32_t*) (mmap_reg + MT7628_GPIO_SET + (dev->pin / 32) * 4) =
(uint32_t)(1 << (dev->pin % 32));
} else {
*(volatile uint32_t*) (mmap_reg + MT7628_GPIO_CLEAR + (dev->pin / 32) * 4) =
(uint32_t)(1 << (dev->pin % 32));
}
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_mmap_unsetup()
{
if (mmap_reg == NULL) {
syslog(LOG_ERR, "linkit mmap: null register cant unsetup");
return MRAA_ERROR_INVALID_RESOURCE;
}
munmap(mmap_reg, mmap_size);
mmap_reg = NULL;
if (close(mmap_fd) != 0) {
return MRAA_ERROR_INVALID_RESOURCE;
}
return MRAA_SUCCESS;
}
static int
mtk_mmap_read(mraa_gpio_context dev)
{
uint32_t value = *(volatile uint32_t*) (mmap_reg + MT7628_GPIO_DATA + (dev->pin / 32) * 4);
if (value & (uint32_t)(1 << (dev->pin % 32))) {
return 1;
}
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_mmap_setup(mraa_gpio_context dev, mraa_boolean_t en)
{
if (dev == NULL) {
syslog(LOG_ERR, "linkit mmap: context not valid");
return MRAA_ERROR_INVALID_HANDLE;
}
if (en == 0) {
if (dev->mmap_write == NULL && dev->mmap_read == NULL) {
syslog(LOG_ERR, "linkit mmap: can't disable disabled mmap gpio");
return MRAA_ERROR_INVALID_PARAMETER;
}
dev->mmap_write = NULL;
dev->mmap_read = NULL;
mmap_count--;
if (mmap_count == 0) {
return mtk_mmap_unsetup();
}
return MRAA_SUCCESS;
}
if (dev->mmap_write != NULL && dev->mmap_read != NULL) {
syslog(LOG_ERR, "linkit mmap: can't enable enabled mmap gpio");
return MRAA_ERROR_INVALID_PARAMETER;
}
// Might need to make some elements of this thread safe.
// For example only allow one thread to enter the following block
// to prevent mmap'ing twice.
if (mmap_reg == NULL) {
if ((mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) {
syslog(LOG_ERR, "linkit map: unable to open %s", MMAP_PATH);
return MRAA_ERROR_INVALID_HANDLE;
}
mmap_reg = (uint8_t*) mmap(NULL, MT7628_BLOCK_SIZE, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, mmap_fd, 0x10000000);
if (mmap_reg == MAP_FAILED) {
syslog(LOG_ERR, "linkit mmap: failed to mmap");
mmap_reg = NULL;
close(mmap_fd);
return MRAA_ERROR_NO_RESOURCES;
}
}
dev->mmap_write = &mtk_mmap_write;
dev->mmap_read = &mtk_mmap_read;
mmap_count++;
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_mmap_gpiomode(void)
{
if ((gpio_mmap_fd = open(MMAP_PATH, O_RDWR)) < 0) {
syslog(LOG_ERR, "linkit map: unable to open %s", MMAP_PATH);
return MRAA_ERROR_INVALID_HANDLE;
}
gpio_mmap_reg = (uint8_t*) mmap(NULL, MT7628_BLOCK_SIZE, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, gpio_mmap_fd, MT7628_GPIOMODE_BASE);
if (gpio_mmap_reg == MAP_FAILED) {
syslog(LOG_ERR, "linkit gpio_mmap: failed to mmap");
gpio_mmap_reg = NULL;
close(gpio_mmap_fd);
return MRAA_ERROR_NO_RESOURCES;
}
return MRAA_SUCCESS;
}
static void
mtk_set_pinmux(unsigned int mask, unsigned int shift, unsigned int val)
{
unsigned int reg;
unsigned int offset = 0x60;
if (shift >= 32) {
shift -= 32;
offset += 4;
}
reg = *(volatile uint32_t*) (gpio_mmap_reg + offset);
reg &= ~(mask << shift);
reg |= (val << shift);
*(volatile uint32_t*) (gpio_mmap_reg + offset) = reg;
}
enum {
MUX_GPIO = 0,
MUX_SPI_S,
MUX_SPI_CS1,
MUX_I2S,
MUX_UART0,
MUX_I2C,
MUX_UART1,
MUX_UART2,
MUX_PWM0,
MUX_PWM1,
MUX_EPHY,
MUX_WLED,
__MUX_MAX,
};
// Map GPIO pins to mux groups.
static unsigned char gpio_mux_groups[64];
static struct pinmux {
char *name;
char *func[4];
unsigned int shift;
unsigned int mask;
} mt7688_mux[] = {
{
.name = "refclk",
.func = { "refclk", "gpio", NULL, NULL },
.shift = 18,
.mask = 0x1,
}, {
.name = "spi_s",
.func = { "spi_s", "gpio", "utif", "pwm" },
.shift = 2,
.mask = 0x3,
}, {
.name = "spi_cs1",
.func = { "spi_cs1", "gpio", NULL, "refclk" },
.shift = 4,
.mask = 0x3,
}, {
.name = "i2s",
.func = { "i2s", "gpio", "pcm", NULL },
.shift = 6,
.mask = 0x3,
}, {
.name = "uart0",
.func = { "uart", "gpio", NULL, NULL },
.shift = 8,
.mask = 0x3,
}, {
.name = "i2c",
.func = { "i2c", "gpio", NULL, NULL },
.shift = 20,
.mask = 0x3,
}, {
.name = "uart1",
.func = { "uart", "gpio", NULL, NULL },
.shift = 24,
.mask = 0x3,
}, {
.name = "uart2",
.func = { "uart", "gpio", "pwm", NULL },
.shift = 26,
.mask = 0x3,
}, {
.name = "pwm0",
.func = { "pwm", "gpio", NULL, NULL },
.shift = 28,
.mask = 0x3,
}, {
.name = "pwm1",
.func = { "pwm", "gpio", NULL, NULL },
.shift = 30,
.mask = 0x3,
}, {
.name = "ephy",
.func = { "ephy", "gpio", NULL, NULL },
.shift = 34,
.mask = 0x3,
}, {
.name = "wled",
.func = { "wled", "gpio", NULL, NULL },
.shift = 32,
.mask = 0x3,
},
};
static mraa_result_t
mtk_gpio_init_pre(int pin)
{
struct pinmux *m = &mt7688_mux[gpio_mux_groups[pin]];
mtk_set_pinmux(m->mask, m->shift, 1);
return MRAA_SUCCESS;
}
static void
mtk_select_function(unsigned int id, char *name)
{
int i;
if (id >= __MUX_MAX)
return;
for (i = 0; i < 4; i++) {
if (!mt7688_mux[id].func[i] || strcmp(mt7688_mux[id].func[i], name))
continue;
mtk_set_pinmux(mt7688_mux[id].mask, mt7688_mux[id].shift, i);
syslog(LOG_INFO, "mraa: set pinmux %s -> %s\n", mt7688_mux[id].name, name);
return;
}
}
static mraa_result_t
mtk_i2c_init_pre(unsigned int bus)
{
mtk_select_function(MUX_I2C, "i2c");
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_pwm_init_post(mraa_pwm_context pwm)
{
switch(pwm->pin) {
case 0:
mtk_select_function(MUX_PWM0, "pwm");
break;
case 1:
mtk_select_function(MUX_PWM1, "pwm");
break;
case 2:
case 3:
mtk_select_function(MUX_UART2, "pwm");
break;
}
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_spi_init_pre(int bus)
{
mtk_select_function(MUX_SPI_CS1, "spi_cs1");
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_uart_init_pre(int index)
{
switch(index) {
case 0:
mtk_select_function(MUX_UART0, "uart");
break;
case 1:
mtk_select_function(MUX_UART1, "uart");
break;
case 2:
mtk_select_function(MUX_UART2, "uart");
break;
}
return MRAA_SUCCESS;
}
static mraa_result_t
mtk_i2c_freq(mraa_i2c_context dev, mraa_i2c_mode_t mode)
{
switch (mode) {
case MRAA_I2C_STD:
break;
default:
syslog(LOG_ERR, "Invalid i2c frequency");
return MRAA_ERROR_INVALID_PARAMETER;
}
return MRAA_SUCCESS;
}
/*
* Add a pin descriptor.
*/
static void
mtk_add_pin(mraa_board_t *b, int index, int pin, const char *name, int mux,
mraa_boolean_t valid, mraa_boolean_t gpio, mraa_boolean_t pwm,
mraa_boolean_t fast_gpio, mraa_boolean_t spi, mraa_boolean_t i2c,
mraa_boolean_t aio, mraa_boolean_t uart)
{
strncpy(b->pins[index].name, name, MRAA_PIN_NAME_SIZE);
b->pins[index].gpio.pinmap = pin;
gpio_mux_groups[pin] = mux;
b->pins[index].capabilities.valid = valid;
b->pins[index].capabilities.gpio = gpio;
b->pins[index].capabilities.pwm = pwm;
b->pins[index].capabilities.fast_gpio = fast_gpio;
b->pins[index].capabilities.spi = spi;
b->pins[index].capabilities.i2c = i2c;
b->pins[index].capabilities.aio = aio;
b->pins[index].capabilities.uart = uart;
if (gpio) {
b->gpio_count++;
}
}
/*
* Add UART device.
*/
static void
mtk_add_uart(mraa_board_t *b, char *path, int tx_pin, int rx_pin)
{
b->uart_dev[b->uart_dev_count].device_path = path;
b->uart_dev[b->uart_dev_count].tx = tx_pin;
b->uart_dev[b->uart_dev_count].rx = rx_pin;
++b->uart_dev_count;
}
/*
* Allocate an instance for generic MT7688 board.
*/
static mraa_board_t *
mtk_common(char *name, int pin_count)
{
int i;
if (mtk_mmap_gpiomode())
return NULL;
mraa_board_t *b = (mraa_board_t*) malloc(sizeof(mraa_board_t));
if (b == NULL) {
return NULL;
}
memset(b, 0, sizeof(mraa_board_t));
b->platform_name = name;
b->phy_pin_count = pin_count;
b->aio_count = 0;
b->adc_raw = 0;
b->adc_supported = 0;
b->pwm_default_period = 500;
b->pwm_max_period = 1000000;
b->pwm_min_period = 1;
b->adv_func = (mraa_adv_func_t*) calloc(1, sizeof(mraa_adv_func_t));
if (b->adv_func == NULL) {
return NULL;
}
b->adv_func->i2c_init_pre = &mtk_i2c_init_pre;
b->adv_func->pwm_init_post = &mtk_pwm_init_post;
b->adv_func->spi_init_pre = &mtk_spi_init_pre;
b->adv_func->uart_init_pre = &mtk_uart_init_pre;
b->adv_func->gpio_init_pre = &mtk_gpio_init_pre;
b->adv_func->i2c_set_frequency_replace = &mtk_i2c_freq;
b->pins = (mraa_pininfo_t*) malloc(sizeof(mraa_pininfo_t) * b->phy_pin_count);
memset(b->pins, 0, sizeof(mraa_pininfo_t) * b->phy_pin_count);
memset(gpio_mux_groups, -1, sizeof(gpio_mux_groups));
b->adv_func->gpio_mmap_setup = &mtk_mmap_setup;
for (i = 0; i < b->phy_pin_count; i++) {
snprintf(b->pins[i].name, MRAA_PIN_NAME_SIZE, "GPIO%d", i);
b->pins[i].capabilities = (mraa_pincapabilities_t){ 0, 0, 0, 0, 0, 0, 0, 0 };
}
//
// I2C bus
//
b->i2c_bus_count = 1;
b->def_i2c_bus = 0;
b->i2c_bus[0].bus_id = 0;
b->i2c_bus[0].sda = 5; // GPIO5
b->i2c_bus[0].scl = 4; // GPIO4
//
// SPI bus
//
b->spi_bus_count = 1;
b->def_spi_bus = 0;
b->spi_bus[0].bus_id = 32766;
b->spi_bus[0].slave_s = 1;
b->spi_bus[0].mosi = 8; // GPIO8
b->spi_bus[0].miso = 9; // GPIO9
b->spi_bus[0].sclk = 7; // GPIO7
b->spi_bus[0].cs = 6; // GPIO6
return b;
}
/*
* Mediatek Linkit Smart 7688 board (and Duo)
*/
mraa_board_t *
mraa_mtk_linkit()
{
mraa_board_t *b = mtk_common("LinkIt Smart 7688", 32);
if (b == NULL) {
return NULL;
}
//
// GPIO pins
// gpio spi i2c uart
mtk_add_pin(b, 1, 43, "GPIO43", MUX_EPHY, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 8, 20, "GPIO20", MUX_UART2, 1, 1, 1, 0, 0, 0, 0, 1);
b->pins[8].uart.parent_id = 2;
b->pins[8].pwm.parent_id = 0;
b->pins[8].pwm.pinmap = 2;
mtk_add_pin(b, 9, 21, "GPIO21", MUX_UART2, 1, 1, 1, 0, 0, 0, 0, 1);
b->pins[9].uart.parent_id = 2;
b->pins[9].pwm.parent_id = 0;
b->pins[9].pwm.pinmap = 3;
mtk_add_pin(b, 10, 2, "GPIO2", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 11, 3, "GPIO3", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 12, 0, "GPIO0", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 13, 1, "GPIO1", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 14, 37, "GPIO37", MUX_GPIO, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 15, 44, "GPIO44", MUX_WLED, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 16, 46, "GPIO46", MUX_UART1, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[16].uart.parent_id = 1;
mtk_add_pin(b, 17, 45, "GPIO45", MUX_UART1, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[17].uart.parent_id = 1;
mtk_add_pin(b, 18, 13, "GPIO13", MUX_UART0, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[18].uart.parent_id = 0;
mtk_add_pin(b, 19, 12, "GPIO12", MUX_UART0, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[19].uart.parent_id = 0;
mtk_add_pin(b, 20, 5, "GPIO5", MUX_I2C, 1, 1, 0, 0, 0, 1, 0, 0);
b->pins[20].i2c.pinmap = 0;
mtk_add_pin(b, 21, 4, "GPIO4", MUX_I2C, 1, 1, 0, 0, 0, 1, 0, 0);
b->pins[21].i2c.pinmap = 0;
mtk_add_pin(b, 22, 8, "SPI_MOSI", MUX_GPIO, 1, 0, 0, 0, 1, 0, 0, 0);
mtk_add_pin(b, 23, 9, "SPI_MISO", MUX_GPIO, 1, 0, 0, 0, 1, 0, 0, 0);
mtk_add_pin(b, 24, 7, "SPI_CLK", MUX_GPIO, 1, 0, 0, 0, 1, 0, 0, 0);
mtk_add_pin(b, 25, 6, "GPIO6", MUX_SPI_CS1, 1, 1, 0, 0, 1, 0, 0, 0);
b->pins[25].spi.pinmap = 0;
mtk_add_pin(b, 26, 18, "GPIO18", MUX_PWM0, 1, 1, 1, 0, 0, 0, 0, 0);
b->pins[26].pwm.parent_id = 0;
b->pins[26].pwm.pinmap = 0;
mtk_add_pin(b, 27, 19, "GPIO19", MUX_PWM1, 1, 1, 1, 0, 0, 0, 0, 0);
b->pins[27].pwm.parent_id = 0;
b->pins[27].pwm.pinmap = 1;
mtk_add_pin(b, 28, 17, "GPIO17", MUX_SPI_S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 29, 16, "GPIO16", MUX_SPI_S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 30, 15, "GPIO15", MUX_SPI_S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 31, 14, "GPIO14", MUX_SPI_S, 1, 1, 0, 0, 0, 0, 0, 0);
//
// UARTs
//
mtk_add_uart(b, "/dev/ttyS0", 12, 13); // GPIO12, GPIO13 at pins P19, P18
mtk_add_uart(b, "/dev/ttyS1", 45, 46); // GPIO45, GPIO46 at pins P17, P16
mtk_add_uart(b, "/dev/ttyS2", 20, 21); // GPIO20, GPIO21 at pins P8, P9
b->def_uart_dev = 0;
return b;
}
/*
* Onion Omega2 and Omega2+ boards
*/
mraa_board_t *
mraa_mtk_omega2()
{
mraa_board_t *b = mtk_common("Onion Omega2", 32);
if (b == NULL) {
return NULL;
}
//
// GPIO pins, left side
// gpio spi i2c uart
mtk_add_pin(b, 1, 11, "GPIO11", MUX_GPIO, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 2, 3, "GPIO3", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 3, 2, "GPIO2", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 4, 17, "GPIO17", MUX_GPIO, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 5, 16, "GPIO16", MUX_GPIO, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 6, 15, "GPIO15", MUX_GPIO, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 7, 46, "GPIO46", MUX_UART1, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[7].uart.parent_id = 1;
mtk_add_pin(b, 8, 45, "GPIO45", MUX_UART1, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[8].uart.parent_id = 1;
mtk_add_pin(b, 9, 9, "SPI_MISO", MUX_GPIO, 1, 0, 0, 0, 1, 0, 0, 0);
mtk_add_pin(b, 10, 8, "SPI_MOSI", MUX_GPIO, 1, 0, 0, 0, 1, 0, 0, 0);
mtk_add_pin(b, 11, 7, "SPI_CLK", MUX_GPIO, 1, 0, 0, 0, 1, 0, 0, 0);
mtk_add_pin(b, 12, 6, "GPIO6", MUX_SPI_CS1, 1, 1, 0, 0, 1, 0, 0, 0);
b->pins[12].spi.pinmap = 0;
mtk_add_pin(b, 13, 1, "GPIO1", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 14, 0, "GPIO0", MUX_I2S, 1, 1, 0, 0, 0, 0, 0, 0);
//
// GPIO pins, right side
// gpio spi i2c uart
mtk_add_pin(b, 20, 13, "GPIO13", MUX_UART0, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[20].uart.parent_id = 0;
mtk_add_pin(b, 21, 12, "GPIO12", MUX_UART0, 1, 1, 0, 0, 0, 0, 0, 1);
b->pins[21].uart.parent_id = 0;
mtk_add_pin(b, 22, 38, "FW_RST", MUX_GPIO, 1, 1, 0, 0, 0, 0, 0, 0);
mtk_add_pin(b, 28, 18, "GPIO18", MUX_PWM0, 1, 1, 1, 0, 0, 0, 0, 0);
b->pins[28].pwm.parent_id = 0;
b->pins[28].pwm.pinmap = 0;
mtk_add_pin(b, 29, 19, "GPIO19", MUX_PWM1, 1, 1, 1, 0, 0, 0, 0, 0);
b->pins[29].pwm.parent_id = 0;
b->pins[29].pwm.pinmap = 1;
mtk_add_pin(b, 30, 4, "GPIO4", MUX_I2C, 1, 1, 0, 0, 0, 1, 0, 0);
b->pins[30].i2c.pinmap = 0;
mtk_add_pin(b, 31, 5, "GPIO5", MUX_I2C, 1, 1, 0, 0, 0, 1, 0, 0);
b->pins[31].i2c.pinmap = 0;
//
// UARTs
//
mtk_add_uart(b, "/dev/ttyS0", 12, 13); // GPIO12, GPIO13 at pins 21, 22
mtk_add_uart(b, "/dev/ttyS1", 45, 46); // GPIO45, GPIO46 at pins 8, 7
b->def_uart_dev = 0;
return b;
}

65
src/mips/mips.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* Author: Serge Vakulenko <vak@besm6.org>
* Copyright (c) 2017 Serge Vakulenko.
*
* 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.
*/
#include <stdlib.h>
#include <string.h>
#include "mraa_internal.h"
#include "mips/mediatek.h"
mraa_platform_t
mraa_mips_platform()
{
mraa_platform_t platform_type = MRAA_UNKNOWN_PLATFORM;
size_t len = 100;
char* line = malloc(len);
FILE* fh = fopen("/proc/cpuinfo", "r");
if (fh != NULL) {
while (getline(&line, &len, fh) != -1) {
if (strncmp(line, "machine", 7) == 0) {
if (strstr(line, "MediaTek LinkIt Smart 7688")) {
platform_type = MRAA_MTK_LINKIT;
}
if (strstr(line, "Onion Omega2")) {
platform_type = MRAA_MTK_OMEGA2;
}
}
}
fclose(fh);
}
free(line);
switch (platform_type) {
case MRAA_MTK_LINKIT:
plat = mraa_mtk_linkit();
break;
case MRAA_MTK_OMEGA2:
plat = mraa_mtk_omega2();
break;
default:
plat = NULL;
syslog(LOG_ERR, "Unknown Platform, currently not supported by MRAA");
}
return platform_type;
}

View File

@@ -144,6 +144,9 @@ imraa_init()
#elif defined(ARMPLAT)
// Use runtime ARM platform detection
platform_type = mraa_arm_platform();
#elif defined(MIPSPLAT)
// Use runtime ARM platform detection
platform_type = mraa_mips_platform();
#elif defined(MOCKPLAT)
// Use mock platform
platform_type = mraa_mock_platform();