Realtime GPIO Connection

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
hida_4040201
Level 1
Level 1
First like given

Hey,

I am new with PSOC so please bare with me. I tried to find an answer by myself but so far I am not able to. I come from embedded C and ARM Cortex-M background with extensive experience.

I was exploring PSOC for a new project, what I want to do is to control the route of some digital signals. The board will have 2 connectors, and I want to route signals from one connector to the other based on user's configuration. The user will connect signals to some GPIO pins, using PSOC I want to re-route these signals to other GPIO pins. Prior to user configuration I do not know which Pin will be connected to which and whether the signal is input or output. To rephrase, there is a data bus connected to some pins; using the PSOC I want to reroute these signals to other pins. The problem is I cannot make this decision while using the PSOC creator, it needs to be done in the field.

Example:

In the field the user will decide to connect J1.1 to J2.3, later he will decide to connect J1.1 to J2.4 etc... The user can be asked to select if the signal is input or output in the field.

  1. Is it possible to control the hardware blocks using the C code instead of the PSOC creator schematic ? e.g connect P0[3] to P0[5] using C instead of schematic design
  2. Is there a way to implement the above using control registers and other blocks?

I tried to use back to back mux with bidirectional pins but at build time I get the below errors.

pastedImage_5.png

Thank you for any help

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

This was a fun problem to challenge, following is the result of my half day trial.

Although basically it seems to be working, I have NOT fully tested nor confirmed so please proceed with caution.

Meantime, because of the nature of application, we could easily destroy the device,

so in case you connect something to the pin please use  appropriate resistor(s) to protect the device.

I only tested the case J1.1 is input and J2.1 is output, and it seemed to be working.

schematic

003-Schematic.JPG

main.c

=======================

#include "project.h"

#include <stdio.h>

#define TAB '\t'

#define SPACE ' '

#define CR '\r'

#define LF '\n'

#define STR_LEN 128

char str[STR_LEN+1] ; /* print buffer */

volatile char rx_buf[STR_LEN+1] ; /* buffer for UART_RX */

volatile int rx_index = 0 ;

volatile int str_received = 0 ;

int is_delimiter(uint8_t c)

{

    int result = 0 ;

    switch(c) {

    case TAB:

    case SPACE:

    case CR:

    case LF:

        result = 1 ;

        break ;

    }

    return( result ) ;

}

CY_ISR(uart_rx_isr)

{

    uint8_t c ;

//    UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY) ; /* for PSoC 4 */

    if (UART_GetRxBufferSize()) {

        c = UART_GetByte() ;

        if ((rx_index >= STR_LEN) || is_delimiter(c)) {

            rx_buf[rx_index] = (char)0 ;

            str_received = 1 ;

            rx_index = 0 ;

        } else {

            rx_buf[rx_index++] = c ;

        }

    }

}

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    UART_Start() ;

    isr_uart_rx_StartEx(uart_rx_isr) ;

}

void get_string(char *str)

{

    uint8_t int_flag ;

   

    while(1) {

        if (str_received) {

            int_flag = CyEnterCriticalSection() ;

            strcpy(str, (char *)rx_buf) ;

            str_received = 0 ;

            CyExitCriticalSection(int_flag) ;

            break ;

        }

    }

}

void help(void)

{

    print("=== commands ===\n") ;

    print("reset     : reset and clear all connections\n") ;

    print("list      : list current connections\n") ;

    print("Jx.x Jy.y : connect input Jy.y to output Jx.x\n") ;

    print("            Example  J1.1 J2.1 (J1.1 <= J2.1)\n") ;

    print("=================\n") ;

}

void splash(void)

{

    sprintf(str, "IO MUX Test (%s %s)\n\r", __DATE__, __TIME__) ;

    print(str) ;

    help() ;

}

void prompt(void)

{

    print("> ") ;

}

void do_reset(void)

{

    OE_Write(0x00) ; /* stop all output enables */

    J1_IN_Write(0x00) ;

    J2_IN_Write(0x00) ;

}

int get_con_pin(char *name, int *con, int *pin)

{

    int result = 0 ;

    switch(name[1]) {

    case '1': *con = 1 ; break ;

    case '2': *con = 2 ; break ;

    default:

        sprintf(str, "Invalid Connector Name [ %s ]\n", name) ;

        print(str) ;

        result++ ;

        break ;

    }

    switch(name[3]) {

    case '1': *pin = 1 ; break ;

    case '2': *pin = 2 ; break ;

    case '3': *pin = 3 ; break ;

    case '4': *pin = 4 ; break ;

    default:

        sprintf(str, "Invalid Connector Name [ %s ]\n", name) ;

        print(str) ;

        result++ ;

        break ;

    }

    return( result ) ;

}

void list_regs(void)

{

    int i, dst_con, dst_pin, src_con, src_pin ;

    uint8_t oe_value, sel1_value, sel2_value ;

    oe_value = OE_Read() ;

    sprintf(str, "OE: 0x%02X ", oe_value ) ;

    print(str) ;

    sel1_value = J1_IN_Read() ;

    sprintf(str, "J1: 0x%02X ", sel1_value ) ;

    print(str) ;

    sel2_value = J2_IN_Read() ;

    sprintf(str, "J2: 0x%02X\n", sel2_value) ;

    print(str) ;  

    for (i = 0 ; i < 8 ; i++ ) {

        if (oe_value & (0x01 << i)) {

            dst_con = (i / 4) + 1 ;

            dst_pin = (i % 4) + 1 ;

            if (dst_con == 1) {

                src_con = 2 ;

                src_pin = ((sel1_value >> ((dst_pin - 1) * 2)) & 0x03) + 1 ;

            } else {

                src_con = 1 ;

                src_pin = ((sel2_value >> ((dst_pin - 1) * 2)) & 0x03) + 1 ;

            }

            sprintf(str, "J%d.%d <= J%d.%d\n", dst_con, dst_pin, src_con, src_pin ) ;

            print(str) ;

        }

    }           

}

int connect_wire(int dst_con, int dst_pin, int src_con, int src_pin)

{

    uint8_t oe_value, sel_value ;

    uint8_t bit ;

    int result = 0 ;

   

    if (dst_con == src_con) {

        print("Can not connect same connectors\n") ;

        result = 1 ;

    }

   

    // select input for destination IN_SEL

    bit = 2 * (dst_pin - 1) ; /* lsb for sel */

    if (dst_con == 1) {

        sel_value = J1_IN_Read() ;

        sel_value &= ~(0x03 << bit) ; /* clear 2bit for sel */

        sel_value |= ((src_pin - 1) & 0x03) << bit ;

        J1_IN_Write(sel_value) ;

    } else if (dst_con == 2) {

        sel_value = J2_IN_Read() ;

        sel_value &= ~(0x03 << bit) ; /* clear 2bit for sel */

        sel_value |= ((src_pin - 1) & 0x03) << bit ;

        J2_IN_Write(sel_value) ;

    }

   

    // set source to be input

    oe_value = OE_Read() ;

    bit = 4 * (src_con - 1) + (src_pin - 1) ;

    oe_value &= ~(0x01 << bit) ; /* clear OE for the source pin */

    // set destintion to be output

    bit = 4 * (dst_con - 1) + (dst_pin -1) ;

    oe_value |= (0x01 << bit) ; /* set OE for the destination pin */

    OE_Write(oe_value) ;

   

    return( result ) ;

}

void do_command(char *command)

{

    char source[32] ;

    int src_con, src_pin, dst_con, dst_pin ;

   

    if (strcmp(command, "reset") == 0) {

        print("Connection Reset!\n") ;

        do_reset() ;

    } else if (strcmp(command, "list") == 0) {

        list_regs() ;

    } else if ((*command == 'j')||(*command == 'J')) { /* J1.1 etc */

        if (get_con_pin(command, &dst_con, &dst_pin) == 0) {

            get_string(source) ;

            if (get_con_pin(source, &src_con, &src_pin) == 0) {

                connect_wire(dst_con, dst_pin, src_con, src_pin) ;

                sprintf(str, "J%d.%d <= J%d.%d\n", dst_con, dst_pin, src_con, src_pin) ;

                print(str) ;

            }

        }

    } else {

        help() ;

    }

}

int main(void)

{

    char command[32] ;

   

    init_hardware() ;

   

    splash() ;

   

    for(;;) {

        prompt() ;

        get_string(command) ;

        do_command(command) ;

    }

}

=======================

TeraTerm log

002-TeraTerm-log.JPG

moto

View solution in original post

4 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

This was a fun problem to challenge, following is the result of my half day trial.

Although basically it seems to be working, I have NOT fully tested nor confirmed so please proceed with caution.

Meantime, because of the nature of application, we could easily destroy the device,

so in case you connect something to the pin please use  appropriate resistor(s) to protect the device.

I only tested the case J1.1 is input and J2.1 is output, and it seemed to be working.

schematic

003-Schematic.JPG

main.c

=======================

#include "project.h"

#include <stdio.h>

#define TAB '\t'

#define SPACE ' '

#define CR '\r'

#define LF '\n'

#define STR_LEN 128

char str[STR_LEN+1] ; /* print buffer */

volatile char rx_buf[STR_LEN+1] ; /* buffer for UART_RX */

volatile int rx_index = 0 ;

volatile int str_received = 0 ;

int is_delimiter(uint8_t c)

{

    int result = 0 ;

    switch(c) {

    case TAB:

    case SPACE:

    case CR:

    case LF:

        result = 1 ;

        break ;

    }

    return( result ) ;

}

CY_ISR(uart_rx_isr)

{

    uint8_t c ;

//    UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY) ; /* for PSoC 4 */

    if (UART_GetRxBufferSize()) {

        c = UART_GetByte() ;

        if ((rx_index >= STR_LEN) || is_delimiter(c)) {

            rx_buf[rx_index] = (char)0 ;

            str_received = 1 ;

            rx_index = 0 ;

        } else {

            rx_buf[rx_index++] = c ;

        }

    }

}

void print(char *str)

{

    UART_PutString(str) ;

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */   

    UART_Start() ;

    isr_uart_rx_StartEx(uart_rx_isr) ;

}

void get_string(char *str)

{

    uint8_t int_flag ;

   

    while(1) {

        if (str_received) {

            int_flag = CyEnterCriticalSection() ;

            strcpy(str, (char *)rx_buf) ;

            str_received = 0 ;

            CyExitCriticalSection(int_flag) ;

            break ;

        }

    }

}

void help(void)

{

    print("=== commands ===\n") ;

    print("reset     : reset and clear all connections\n") ;

    print("list      : list current connections\n") ;

    print("Jx.x Jy.y : connect input Jy.y to output Jx.x\n") ;

    print("            Example  J1.1 J2.1 (J1.1 <= J2.1)\n") ;

    print("=================\n") ;

}

void splash(void)

{

    sprintf(str, "IO MUX Test (%s %s)\n\r", __DATE__, __TIME__) ;

    print(str) ;

    help() ;

}

void prompt(void)

{

    print("> ") ;

}

void do_reset(void)

{

    OE_Write(0x00) ; /* stop all output enables */

    J1_IN_Write(0x00) ;

    J2_IN_Write(0x00) ;

}

int get_con_pin(char *name, int *con, int *pin)

{

    int result = 0 ;

    switch(name[1]) {

    case '1': *con = 1 ; break ;

    case '2': *con = 2 ; break ;

    default:

        sprintf(str, "Invalid Connector Name [ %s ]\n", name) ;

        print(str) ;

        result++ ;

        break ;

    }

    switch(name[3]) {

    case '1': *pin = 1 ; break ;

    case '2': *pin = 2 ; break ;

    case '3': *pin = 3 ; break ;

    case '4': *pin = 4 ; break ;

    default:

        sprintf(str, "Invalid Connector Name [ %s ]\n", name) ;

        print(str) ;

        result++ ;

        break ;

    }

    return( result ) ;

}

void list_regs(void)

{

    int i, dst_con, dst_pin, src_con, src_pin ;

    uint8_t oe_value, sel1_value, sel2_value ;

    oe_value = OE_Read() ;

    sprintf(str, "OE: 0x%02X ", oe_value ) ;

    print(str) ;

    sel1_value = J1_IN_Read() ;

    sprintf(str, "J1: 0x%02X ", sel1_value ) ;

    print(str) ;

    sel2_value = J2_IN_Read() ;

    sprintf(str, "J2: 0x%02X\n", sel2_value) ;

    print(str) ;  

    for (i = 0 ; i < 8 ; i++ ) {

        if (oe_value & (0x01 << i)) {

            dst_con = (i / 4) + 1 ;

            dst_pin = (i % 4) + 1 ;

            if (dst_con == 1) {

                src_con = 2 ;

                src_pin = ((sel1_value >> ((dst_pin - 1) * 2)) & 0x03) + 1 ;

            } else {

                src_con = 1 ;

                src_pin = ((sel2_value >> ((dst_pin - 1) * 2)) & 0x03) + 1 ;

            }

            sprintf(str, "J%d.%d <= J%d.%d\n", dst_con, dst_pin, src_con, src_pin ) ;

            print(str) ;

        }

    }           

}

int connect_wire(int dst_con, int dst_pin, int src_con, int src_pin)

{

    uint8_t oe_value, sel_value ;

    uint8_t bit ;

    int result = 0 ;

   

    if (dst_con == src_con) {

        print("Can not connect same connectors\n") ;

        result = 1 ;

    }

   

    // select input for destination IN_SEL

    bit = 2 * (dst_pin - 1) ; /* lsb for sel */

    if (dst_con == 1) {

        sel_value = J1_IN_Read() ;

        sel_value &= ~(0x03 << bit) ; /* clear 2bit for sel */

        sel_value |= ((src_pin - 1) & 0x03) << bit ;

        J1_IN_Write(sel_value) ;

    } else if (dst_con == 2) {

        sel_value = J2_IN_Read() ;

        sel_value &= ~(0x03 << bit) ; /* clear 2bit for sel */

        sel_value |= ((src_pin - 1) & 0x03) << bit ;

        J2_IN_Write(sel_value) ;

    }

   

    // set source to be input

    oe_value = OE_Read() ;

    bit = 4 * (src_con - 1) + (src_pin - 1) ;

    oe_value &= ~(0x01 << bit) ; /* clear OE for the source pin */

    // set destintion to be output

    bit = 4 * (dst_con - 1) + (dst_pin -1) ;

    oe_value |= (0x01 << bit) ; /* set OE for the destination pin */

    OE_Write(oe_value) ;

   

    return( result ) ;

}

void do_command(char *command)

{

    char source[32] ;

    int src_con, src_pin, dst_con, dst_pin ;

   

    if (strcmp(command, "reset") == 0) {

        print("Connection Reset!\n") ;

        do_reset() ;

    } else if (strcmp(command, "list") == 0) {

        list_regs() ;

    } else if ((*command == 'j')||(*command == 'J')) { /* J1.1 etc */

        if (get_con_pin(command, &dst_con, &dst_pin) == 0) {

            get_string(source) ;

            if (get_con_pin(source, &src_con, &src_pin) == 0) {

                connect_wire(dst_con, dst_pin, src_con, src_pin) ;

                sprintf(str, "J%d.%d <= J%d.%d\n", dst_con, dst_pin, src_con, src_pin) ;

                print(str) ;

            }

        }

    } else {

        help() ;

    }

}

int main(void)

{

    char command[32] ;

   

    init_hardware() ;

   

    splash() ;

   

    for(;;) {

        prompt() ;

        get_string(command) ;

        do_command(command) ;

    }

}

=======================

TeraTerm log

002-TeraTerm-log.JPG

moto

Oh woow thanks a lot for this extensive answer motootanaka_1799631, I really appreciate it

0 Likes
LinglingG_46
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 10 questions asked
  1. Is it possible to control the hardware blocks using the C code instead of the PSOC creator schematic ? e.g connect P0[3] to P0[5] using C instead of schematic design

    

      Yes, it is Ok to use the C code to control hardware block, you can control all hardware part by register.

      The easy way to understand it is that when you configure the pins by creator schematic, then compile it, check the generate codes.

      You can write the codes which the IDE does.

  1. Is there a way to implement the above using control registers and other blocks?

   If you don't use the M1 and S1 connected to y, use other pins which don't been used by the Multiplexer, then it will no error. As error report explains that we don't support internal three -state signals.

I tried to use back to back mux with bidirectional pins but at build time I get the below error.

Please don't use the M1 and S1 as the Tri-state buffer y-inout.

0 Likes
  1. Is it possible to control the hardware blocks using the C code instead of the PSOC creator schematic ? e.g connect P0[3] to P0[5] using C instead of schematic design

   

      Yes, it is Ok to use the C code to control hardware block, you can control all hardware part by register.

      The easy way to understand it is that when you configure the pins by creator schematic, then compile it, check the generate codes.

      You can write the codes which the IDE does.

Is there any documentation on this ? I couldn't find any. Also when I check the generated code (for the pins for example) it only shows the API that I can use (set, clear ...) it doesn't show the hardware connection code. Can you point me to the C file that contains the hardware connections ?

0 Likes