Jump to content

Fragen zu RED ohne Master und RS485


BOBmoraine

Recommended Posts

Moin,

ich bin mir nicht ganz sicher, daher wollte ich vorm Bestellen nochmal nachfragen:

RED mit Ethernet- und RS485-Extension kann ich doch benutzen ohne Masterbrick oder?

Oder brauche ich für die Extensions zwingend einen Masterbrick im Stack?

 

Kann ich mit RED+RS485-Extension nun eigentlich die Schnittstelle für Modbus benutzen um mit anderen Teilnehmern zu kommunizieren (z.B. Frequenzumformer), oder ist dazu nen USB-Adapter nötig?

Irgendwo hatte ich im Forum mal gelesen das TCP auf RS485 gemapt wird bei TF oder so.

Ist das noch aktuell, oder kann ich die RS485-Schnittstelle beim RED in größerem Umfang benutzen wie bisher?

Link zu diesem Kommentar
Share on other sites

Du benötigst keinen Master um die Ethernet oder RS485 (oder beide) Extensions zu nutzen.

 

Die RS485 Extension kannst du auf dem RED Brick als normale Linux RS485 Schnittstelle benutzen, dafür gibt es von uns allerdings keinen direkten Software-Support o.ä.

 

Die Implementierung des RS485 Tinkerforge Protokolls kannst du im brickd finden: https://github.com/Tinkerforge/brickd/blob/master/src/brickd/red_rs485_extension.c

 

Die eigentliche Konfiguration der Schnittstelle findet in serial_interface_init statt (Zeile 224). Damit und mit libmodbus (http://libmodbus.org/) solltest du dir  einen "General Purpose Modbus Server" bauen können.

Link zu diesem Kommentar
Share on other sites

  • 11 months later...

habe eine verständnisfrage zu rs485/libmodbus !

 

ich möchte externe hardware ansteuern (sunsaver mppt) über libmodbus - oder es zumindest versuchen ;-)

 

DAZU möchte ich ein gestacktes rs485-bricklet am red verwenden um mir den umweg über einen externen rs232/rs485-konverter zu sparen

 

---

 

wenn der brickd-configurator-daemon am red aktiv ist, ist die uart-schnittstelle (WELCHE IST DAS EIGENTLICH ???) ja busy - oder ?

ich sehe auch keine möglichkeit im red-brick-setup die rs485 nicht zu konfigurieren ...

 

browsing im repository hat mich (schon alleine aufgrund der eingeschränkten suchmöglichkeiten) nicht wirklich weitergebracht ...

 

---

 

alternativ : wenn ich schon  nicht das rs485-bricklet verwenden kann, welche chancen bestehen denn mit einem rs232-bricklet (hab momentan noch keines für versuche ...) ? ist das dann als ttySx verfügbar ? mit allen IOCTLS die der libmodbus bzw. die adäquate config braucht ?

 

(hilfe ...)

Link zu diesem Kommentar
Share on other sites

Damit Brick Daemon auf dem RED Brick eine RS485 Extension nicht nutzt, musst du sie mit einem Master Brick und Brick Viewer auf Extension Type None konfigurieren.

 

Die RS485 Extension ist so angeschlossen, dass sie auf UART3 gemuxt werden kann. UART3 taucht als /dev/ttyS0 auf. Der TX Enable Pin des RS485 Transceivers kann auf RTS von UART3 gemuxt werden. Der RX Enable Pin an einem GPIO Pin angeschlossen.

 

Da Brick Daemon jetzt nichts mehr mit der RS485 Extension macht (wegen Extension Type None) musst du selbst das Pin Muxing richtig einstellen. Details kannst du dir im Brick Daemon Code (red_extenstion.c) ansehen.

 

Das kann mit libmodbus funktioniert, getestet hat das meines Wissens nach aber noch keiner.

 

Ein RS232 Bricklet taucht nicht als eine serielle Schnittstelle des Betriebssystems auf.

Link zu diesem Kommentar
Share on other sites

wenn ich das richtig verstehe - - -

 

d.h. folgender code muss nochmals laufen als "rs485 pseudoconfig da von brickd durch setzen auf 'extension type none' unterlassen ...")

 

-----------------------------

 

#include daemonlib/red_gpio.h

#include daemonlib/red_gpio.c // definiert gpio_init(), gpio_mux_configure(), gpio_output_set/clear()

 

#include brickd/red_extension.h

#include brickd/red_extension.c

 

#define EXTENSION_RS485_AS_NONE_HERE 0 // --> RS485EXTENSION HERE ... (0,1)

 

main()

{

gpio_init(); // setzt GPIOPort *_gpio_port

 

for (j = 0; j < extension_rs485_pin_config.num_configs; j++) {

red_extension_configure_pin(&extension_rs485_pin_config.config[j],

EXTENSION_RS485_AS_NONE_HERE );

}; }

};

 

-------------------

 

stimmt ? hab ich was missverstanden ?

ist hoffentlich alles, denn der code ist etwas - ähem - "bulky" ...

bis man sich auskennt bei den ganzen parametriesierungen kann man selber die dinger bauen ;-)

Link zu diesem Kommentar
Share on other sites

man verzeihe mir die ungeduld, aber ich brauche da bald eine "grundlage".

 

ich liebe tinkerforge von anfang an, und versuche es als sensorplattform einzusetzen wo immer es geht und es war im gegensatz zu arduino eine wohltat.

der red-brick ist genau das was zum bau effizienter hyperintelligenter steuerungen fehlt, ist aber vom support her gegenüber olimex bzw. raspberry mühsam, das müsste nicht sein, das hasse ich ein bisschen.

 

das tinkerforge-system ist da ein wenig intransparent und die lernkurve ist selbst für langjährige freaks wie mich, die vor nicht allzulanger zeit, als etwa arch-linux rauskam damit noch eigene kernel gebaut haben weil die gängigen nicht die anforderungen erfüllt haben.

 

was nutzt es, wenn die api-bindings zahlreich und auch gut dokumentiert sind, "the app" ist nicht alles - der kitt "nach aussen", der z.b. mit dem red-brick wirklich optimal erfüllbar wäre wird schon bröselig, wenn es z.b. gilt über rs232/485 devices anzusteuern wie man sieht.

 

ich wünsche mir wirklich da mehr "mitdenken" der tf-crew über das anbinden von industriellen schnittstellen. denn damit wird ein tf-stack erst zu dem gold das er wirklich sein kann....

 

der weg mit der "umwidmung" einer extension ist schon mal ein erster anfang, wär schön wenn man das in den brickd reinpatchen würde und es dann einen switch gäbe um dieses verhalten im code integriert auszuführen statt hier rumzufizzeln und nicht wirklich systemgerecht zu verstehen was man eigentlich tut (auf high-level ebene).

 

auch scheint mir die extension-politik von der anzahl und vom umfang her von anfang an schlecht durchdacht und ein stiefkind das da rumhängt und ich habe das gefühl, keiner hat so einen plan wie das weitergeht ...

und wenn ich nun "froh sein muss" dass ich eine vernetze wolke von rs485+master+stepdown mit einem red+brickd+rs485+ethernet nutzen "darf", dann frage ich mich, wie sollen die "restlichen" interconnects aussehen die man "üblicherweise" braucht um eine ernstzunehmende steuerung ohne verrenkungen zu bauen ...

 

lg

 

p.s.

bitte um positive bestätigung ob der code oben funktioniert und bitte eine antwort von den systemdesignern wie ihr euch sowas vorstellt mit den "restlichen" anbindungen an fremdsysteme, oder ob tf eben eine insel ist und punkt ...

 

danke

 

ich sage nochmals : ohne "richer

Link zu diesem Kommentar
Share on other sites

bitte um review !

danke

 

ich werde das dann ausprobieren (mit einem modbus-gerät), verifizieren & man kann das dann wenn es funktioniert in die dokus übernehmen

 

/*
* brickd
* Copyright (C) 2014 Olaf Lüke <olaf@tinkerforge.com>
* Copyright (C) 2014-2015 Matthias Bolte <matthias@tinkerforge.com>
*
* red_extension.c: Extension initialization for RED Brick
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <stdint.h>

typedef enum {
GPIO_PIN_0 = 0,
GPIO_PIN_1 = 1,
GPIO_PIN_2 = 2,
GPIO_PIN_3 = 3,
GPIO_PIN_4 = 4,
GPIO_PIN_5 = 5,
GPIO_PIN_6 = 6,
GPIO_PIN_7 = 7,
GPIO_PIN_8 = 8,
GPIO_PIN_9 = 9,
GPIO_PIN_10 = 10,
GPIO_PIN_11 = 11,
GPIO_PIN_12 = 12,
GPIO_PIN_13 = 13,
GPIO_PIN_14 = 14,
GPIO_PIN_15 = 15,
GPIO_PIN_16 = 16,
GPIO_PIN_17 = 17,
GPIO_PIN_18 = 18,
GPIO_PIN_19 = 19,
GPIO_PIN_20 = 20,
GPIO_PIN_21 = 21,
GPIO_PIN_22 = 22,
GPIO_PIN_23 = 23,
GPIO_PIN_24 = 24,
GPIO_PIN_25 = 25,
GPIO_PIN_26 = 26,
GPIO_PIN_27 = 27,
GPIO_PIN_28 = 28,
GPIO_PIN_29 = 29,
GPIO_PIN_30 = 30,
GPIO_PIN_31 = 31
} GPIOPinIndex;

typedef enum {
GPIO_PORT_A = 0,
GPIO_PORT_B = 1,
GPIO_PORT_C = 2,
GPIO_PORT_D = 3,
GPIO_PORT_E = 4,
GPIO_PORT_F = 5,
GPIO_PORT_G = 6,
GPIO_PORT_H = 7,
GPIO_PORT_I = 8,
} GPIOPortIndex;

typedef enum {
GPIO_INPUT_DEFAULT = 0,
GPIO_INPUT_PULLUP = 1,
GPIO_INPUT_PULLDOWN = 2
} GPIOInputConfig;

typedef enum {
GPIO_MUX_INPUT = 0,
GPIO_MUX_OUTPUT = 1,
GPIO_MUX_0 = 0,
GPIO_MUX_1 = 1,
GPIO_MUX_2 = 2,
GPIO_MUX_3 = 3,
GPIO_MUX_4 = 4,
GPIO_MUX_5 = 5,
GPIO_MUX_6 = 6,
} GPIOMux;

typedef struct {
uint32_t config[4];
uint32_t value;
uint32_t multi_drive[2];
uint32_t pull[2];
} GPIOPort;

typedef struct {
GPIOPortIndex port_index;
GPIOPinIndex pin_index;
} GPIOPin;

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define GPIO_BASE 0x01c20800

static volatile GPIOPort *_gpio_port;

int gpio_init(void) {
int fd;
uint32_t address_start;
uint32_t address_offset;
uint32_t page_size;
uint32_t page_mask;
void *mapped_base;

fd = open("/dev/mem", O_RDWR);

if (fd < 0) {
	return -1;
}

page_size = sysconf(_SC_PAGESIZE);
page_mask = ~(page_size - 1);
address_start = GPIO_BASE & page_mask;
address_offset = GPIO_BASE & ~page_mask;

// FIXME: add gpio_exit() to munmap?
mapped_base = mmap(0, page_size * 2, PROT_READ | PROT_WRITE, MAP_SHARED,
                   fd, address_start);

if (mapped_base == MAP_FAILED) {
	close(fd);
	return -1;
}

_gpio_port = mapped_base + address_offset;

close(fd);

return 0;
}

void gpio_mux_configure(const GPIOPin pin, const GPIOMux mux_config) {
uint32_t config_index = pin.pin_index >> 3;
uint32_t offset = (pin.pin_index & 0x7) << 2;
uint32_t config = _gpio_port[pin.port_index].config[config_index];

config &= ~(0xF << offset);
config |= mux_config << offset;

_gpio_port[pin.port_index].config[config_index] = config;
}

void gpio_output_set(const GPIOPin pin) {
_gpio_port[pin.port_index].value |= (1 << pin.pin_index);
}

void gpio_output_clear(const GPIOPin pin) {
_gpio_port[pin.port_index].value &= ~(1 << pin.pin_index);
}


#define EXTENSION_POS0_GPIO0  {GPIO_PORT_B, GPIO_PIN_13}
#define EXTENSION_POS0_GPIO1  {GPIO_PORT_B, GPIO_PIN_14}
#define EXTENSION_POS0_GPIO2  {GPIO_PORT_B, GPIO_PIN_19}
#define EXTENSION_POS0_SELECT {GPIO_PORT_G, GPIO_PIN_9}

#define EXTENSION_POS1_GPIO0  {GPIO_PORT_G, GPIO_PIN_2}
#define EXTENSION_POS1_GPIO1  {GPIO_PORT_G, GPIO_PIN_3}
#define EXTENSION_POS1_GPIO2  {GPIO_PORT_G, GPIO_PIN_4}
#define EXTENSION_POS1_SELECT {GPIO_PORT_G, GPIO_PIN_13}

#define EXTENSION_SPI_CLK     {GPIO_PORT_G, GPIO_PIN_10}
#define EXTENSION_SPI_MOSI    {GPIO_PORT_G, GPIO_PIN_11}
#define EXTENSION_SPI_MISO    {GPIO_PORT_G, GPIO_PIN_12}

#define EXTENSION_SER_TXD     {GPIO_PORT_C, GPIO_PIN_16}
#define EXTENSION_SER_RXD     {GPIO_PORT_C, GPIO_PIN_17}
#define EXTENSION_SER_RTS     {GPIO_PORT_C, GPIO_PIN_19}

typedef struct {
GPIOPin pin[2];
GPIOMux mux;
int value;   // If input: 0 = default, 1 = Pullup. If Output: 0 = low, 1 = high. Else ignored.
} ExtensionPinConfiguration;

typedef struct {
int num_configs;
ExtensionPinConfiguration config[];
} ExtensionPinConfigurationArray;

static ExtensionPinConfigurationArray extension_rs485_pin_config = {7, {
{{EXTENSION_POS0_GPIO0,  EXTENSION_POS1_GPIO0},  GPIO_MUX_OUTPUT, 0}, // RXE low = RX enable
{{EXTENSION_POS0_GPIO1,  EXTENSION_POS1_GPIO1},  GPIO_MUX_INPUT,  1}, // Unused
{{EXTENSION_POS0_GPIO2,  EXTENSION_POS1_GPIO2},  GPIO_MUX_INPUT,  1}, // Unused
{{EXTENSION_POS0_SELECT, EXTENSION_POS1_SELECT}, GPIO_MUX_OUTPUT, 0}, // Default = deselect eeprom
{{EXTENSION_SER_TXD,     EXTENSION_SER_TXD},     GPIO_MUX_4,      0}, // Mux to UART3_TX
{{EXTENSION_SER_RXD,     EXTENSION_SER_RXD},     GPIO_MUX_4,      0}, // Mux to UART3_RX
{{EXTENSION_SER_RTS,     EXTENSION_SER_RTS},     GPIO_MUX_4,      0}, // Mux to UART3_RTS
}};

static void red_extension_configure_pin(ExtensionPinConfiguration *config, int extension) {
gpio_mux_configure(config->pin[extension], config->mux);

if (config->value == 0) {
	gpio_output_clear(config->pin[extension]);
} else {
	gpio_output_set(config->pin[extension]); // This should enable pull-up in case of input
}
}

int red_extension_init(int i) {
for (j = 0; j < extension_rs485_pin_config.num_configs; j++) {
	red_extension_configure_pin(&extension_rs485_pin_config.config[j], i);
}

return 0;
}

// RX GPIO pin definitions
static GPIOPin _rx_pin; // Active low

/////////////////////////////////////////////////////////////////////////////////////////
// KISS : statt sscanf's auf argv[] wird die extension# (0|1) über den argc "übergeben" ...
main(int argc)
{
if(argc>1){argc=1};

gpio_init();
red_extension_init(argc);
switch (argc) {
case 0:
	_rx_pin.port_index = GPIO_PORT_B;
	_rx_pin.pin_index = GPIO_PIN_13;
	break;
case 1:
	_rx_pin.port_index = GPIO_PORT_G;
	_rx_pin.pin_index = GPIO_PIN_2;
	break;
}
gpio_mux_configure(_rx_pin, GPIO_MUX_OUTPUT);
gpio_output_clear(_rx_pin);
};

Link zu diesem Kommentar
Share on other sites

bump up

 

ich glaube es ist nicht zu viel verlangt ein bisschen "more usability" zu kriegen

es ist keine gnade von, sondern eine ehre für ein produkt denke ich.

 

es ist auch keine lösung, mal ein paar halbsätze rüberzureichen und dann machts euchs selber, sterbt oder lebt, uns wurscht, keine lust - - - hm ?

 

oder ist das alles eine zumutung für euch, die man nicht einmal mit ignoranz adelt ?

 

please enlighten me

Link zu diesem Kommentar
Share on other sites

Hallo piwo,

 

Photron ist bis Anfang nächsten Jahres im Urlaub, da kommt also so schnell keine Antwort.

 

Bin aktuell unterwegs und kann mit dem Handy den Code natürlich nicht testen. Auf den ersten Blick macht es aber einen guten Eindruck. Funktioniert es denn? Ein "Code Review" ist natürlich immer einfacher wenn man weiß was nicht funktioniert.

Link zu diesem Kommentar
Share on other sites

 

compiliert & liefert success ...

werde testen ob pymodbus auf einem morningstar sunsaver was runterholt & werde berichten ...

 


#include <stdlib.h>
#include <stdio.h>
void prx(char* msg) { fprintf(stderr,"%s\n",msg); };
void mex(char* msg) { prx(msg); exit(EXIT_FAILURE); };

/*
* brickd & daemonlib code from github/tinkerforge :
*
* Copyright (C) 2014 Olaf Lüke <olaf@tinkerforge.com>
* Copyright (C) 2014-2015 Matthias Bolte <matthias@tinkerforge.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

// ============================
// ==> daemonlib/red_gpio.h <==
// ============================

#include <stdint.h>

typedef enum {
GPIO_PIN_0 = 0,
GPIO_PIN_1 = 1,
GPIO_PIN_2 = 2,
GPIO_PIN_3 = 3,
GPIO_PIN_4 = 4,
GPIO_PIN_5 = 5,
GPIO_PIN_6 = 6,
GPIO_PIN_7 = 7,
GPIO_PIN_8 = 8,
GPIO_PIN_9 = 9,
GPIO_PIN_10 = 10,
GPIO_PIN_11 = 11,
GPIO_PIN_12 = 12,
GPIO_PIN_13 = 13,
GPIO_PIN_14 = 14,
GPIO_PIN_15 = 15,
GPIO_PIN_16 = 16,
GPIO_PIN_17 = 17,
GPIO_PIN_18 = 18,
GPIO_PIN_19 = 19,
GPIO_PIN_20 = 20,
GPIO_PIN_21 = 21,
GPIO_PIN_22 = 22,
GPIO_PIN_23 = 23,
GPIO_PIN_24 = 24,
GPIO_PIN_25 = 25,
GPIO_PIN_26 = 26,
GPIO_PIN_27 = 27,
GPIO_PIN_28 = 28,
GPIO_PIN_29 = 29,
GPIO_PIN_30 = 30,
GPIO_PIN_31 = 31
} GPIOPinIndex;

typedef enum {
GPIO_PORT_A = 0,
GPIO_PORT_B = 1,
GPIO_PORT_C = 2,
GPIO_PORT_D = 3,
GPIO_PORT_E = 4,
GPIO_PORT_F = 5,
GPIO_PORT_G = 6,
GPIO_PORT_H = 7,
GPIO_PORT_I = 8,
} GPIOPortIndex;

typedef enum {
GPIO_INPUT_DEFAULT = 0,
GPIO_INPUT_PULLUP = 1,
GPIO_INPUT_PULLDOWN = 2
} GPIOInputConfig;

typedef enum {
GPIO_MUX_INPUT = 0,
GPIO_MUX_OUTPUT = 1,
GPIO_MUX_0 = 0,
GPIO_MUX_1 = 1,
GPIO_MUX_2 = 2,
GPIO_MUX_3 = 3,
GPIO_MUX_4 = 4,
GPIO_MUX_5 = 5,
GPIO_MUX_6 = 6,
} GPIOMux;

typedef struct {
uint32_t config[4];
uint32_t value;
uint32_t multi_drive[2];
uint32_t pull[2];
} GPIOPort;

typedef struct {
GPIOPortIndex port_index;
GPIOPinIndex pin_index;
} GPIOPin;

// ============================
// ==> daemonlib/red_gpio.c <==
// ============================

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define GPIO_BASE 0x01c20800

static volatile GPIOPort *_gpio_port;

// ... THIS FUNCTIION :

void gpio_init__nolog(void) {
int fd;
uint32_t address_start;
uint32_t address_offset;
uint32_t page_size;
uint32_t page_mask;
void *mapped_base;

fd = open("/dev/mem", O_RDWR);

if (fd < 0) {
	mex("error: open /dev/mem failed");
}

page_size = sysconf(_SC_PAGESIZE);
page_mask = ~(page_size - 1);
address_start = GPIO_BASE & page_mask;
address_offset = GPIO_BASE & ~page_mask;

// FIXME: add gpio_exit() to munmap?
mapped_base = mmap(0, page_size * 2, PROT_READ | PROT_WRITE, MAP_SHARED,
                   fd, address_start);

if (mapped_base == MAP_FAILED) {
	close(fd);
	mex("error: mmap /dev/mem failed");
}

_gpio_port = mapped_base + address_offset;

close(fd);
}

void gpio_mux_configure(const GPIOPin pin, const GPIOMux mux_config) {
uint32_t config_index = pin.pin_index >> 3;
uint32_t offset = (pin.pin_index & 0x7) << 2;
uint32_t config = _gpio_port[pin.port_index].config[config_index];

config &= ~(0xF << offset);
config |= mux_config << offset;

_gpio_port[pin.port_index].config[config_index] = config;
}

void gpio_output_set(const GPIOPin pin) {
_gpio_port[pin.port_index].value |= (1 << pin.pin_index);
}

void gpio_output_clear(const GPIOPin pin) {
_gpio_port[pin.port_index].value &= ~(1 << pin.pin_index);
}

// ==============================
// ==> brickd/red_extension.c <==
// ==============================

#define EXTENSION_POS0_GPIO0  {GPIO_PORT_B, GPIO_PIN_13}
#define EXTENSION_POS0_GPIO1  {GPIO_PORT_B, GPIO_PIN_14}
#define EXTENSION_POS0_GPIO2  {GPIO_PORT_B, GPIO_PIN_19}
#define EXTENSION_POS0_SELECT {GPIO_PORT_G, GPIO_PIN_9}

#define EXTENSION_POS1_GPIO0  {GPIO_PORT_G, GPIO_PIN_2}
#define EXTENSION_POS1_GPIO1  {GPIO_PORT_G, GPIO_PIN_3}
#define EXTENSION_POS1_GPIO2  {GPIO_PORT_G, GPIO_PIN_4}
#define EXTENSION_POS1_SELECT {GPIO_PORT_G, GPIO_PIN_13}

#define EXTENSION_SPI_CLK     {GPIO_PORT_G, GPIO_PIN_10}
#define EXTENSION_SPI_MOSI    {GPIO_PORT_G, GPIO_PIN_11}
#define EXTENSION_SPI_MISO    {GPIO_PORT_G, GPIO_PIN_12}

#define EXTENSION_SER_TXD     {GPIO_PORT_C, GPIO_PIN_16}
#define EXTENSION_SER_RXD     {GPIO_PORT_C, GPIO_PIN_17}
#define EXTENSION_SER_RTS     {GPIO_PORT_C, GPIO_PIN_19}

typedef struct {
GPIOPin pin[2];
GPIOMux mux;
int value;   // If input: 0 = default, 1 = Pullup. If Output: 0 = low, 1 = high. Else ignored.
} ExtensionPinConfiguration;

typedef struct {
int num_configs;
ExtensionPinConfiguration config[];
} ExtensionPinConfigurationArray;

static ExtensionPinConfigurationArray extension_rs485_pin_config = {7, {
{{EXTENSION_POS0_GPIO0,  EXTENSION_POS1_GPIO0},  GPIO_MUX_OUTPUT, 0}, // RXE low = RX enable
{{EXTENSION_POS0_GPIO1,  EXTENSION_POS1_GPIO1},  GPIO_MUX_INPUT,  1}, // Unused
{{EXTENSION_POS0_GPIO2,  EXTENSION_POS1_GPIO2},  GPIO_MUX_INPUT,  1}, // Unused
{{EXTENSION_POS0_SELECT, EXTENSION_POS1_SELECT}, GPIO_MUX_OUTPUT, 0}, // Default = deselect eeprom
{{EXTENSION_SER_TXD,     EXTENSION_SER_TXD},     GPIO_MUX_4,      0}, // Mux to UART3_TX
{{EXTENSION_SER_RXD,     EXTENSION_SER_RXD},     GPIO_MUX_4,      0}, // Mux to UART3_RX
{{EXTENSION_SER_RTS,     EXTENSION_SER_RTS},     GPIO_MUX_4,      0}, // Mux to UART3_RTS
}};

// ...

static void red_extension_configure_pin(ExtensionPinConfiguration *config, int extension) {
gpio_mux_configure(config->pin[extension], config->mux);

if (config->value == 0) {
	gpio_output_clear(config->pin[extension]);
} else {
	gpio_output_set(config->pin[extension]); // This should enable pull-up in case of input
}
}

// ... THIS FUNCTIION :

int red_extension_init__excerpt(int i) {
int j;
for (j = 0; j < extension_rs485_pin_config.num_configs; j++) {
	red_extension_configure_pin(&extension_rs485_pin_config.config[j], i);
}

return 0;
}

// ====================================
// ==> brickd/red_rs485_extension.c <==
// ====================================

// ... 
//
// RX GPIO pin definitions
static GPIOPin _rx_pin; // Active low

// ... THIS FUNCTIION :

void init_rxe_pin_state__nolog(int extension)
{
switch (extension) {
case 0:
	_rx_pin.port_index = GPIO_PORT_B;
	_rx_pin.pin_index = GPIO_PIN_13;
	break;
case 1:
	_rx_pin.port_index = GPIO_PORT_G;
	_rx_pin.pin_index = GPIO_PIN_2;
	break;
}
gpio_mux_configure(_rx_pin, GPIO_MUX_OUTPUT);
gpio_output_clear(_rx_pin);
};

///////////////////////////////////////////////////////////////////////
//
int main(int argc, char** argv)
{
  int pos;
  if(argc!=2) {
    mex("usage: extension# not specified correctly as first an only commandline argument");
  };
  if(strcmp(argv[1],"0")==0) {
    pos=0; 
    prx("configuring rs485 extension #0 /w eeprom 'none' outside brickd :");
  } else {
    if(strcmp(argv[1],"1")==0) {
      pos=1; 
      prx("configuring rs485 extension #1 /w eeprom 'none' outside brickd :");
    } else {
      mex("usage: extension# not in range 0..1");
    };
  };

  gpio_init__nolog();
  red_extension_init__excerpt(pos);
  init_rxe_pin_state__nolog(pos);

  prx("success");
  exit(EXIT_SUCCESS);
};

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...