3 Replies Latest reply on May 15, 2019 5:51 PM by MoTa_728816

    UART interrupt triggered by '0' byte from MIDI keyboard

    simac_4074571

      Hello everyone,

       

      For A uni project I have to read MIDI uart output, but because the signal goes trough a optocoupler the interrupt is always triggerd by a '0' byte, and this poses an issue because I only need the data when its actually being sent. MIDI always sends 3 bytes, 1 for command, 1 for note and 1 for velocity.

       

      This is the main, interrupt routine sets a flag when triggered:

       

      int main()

      {

         

          UART_1_Start();

         

          isr_1_StartEx(isr_1_Interrupt);

          UART_2_Start();

         

          IDAC_1_Start();

          IDAC_1_SetValue(0);

         

          CyGlobalIntEnable;

          while(1){

              //other code to be executed

          }

       

          if(rx_intr==1){          //the flag from the interrupt         

              rx_intr=0;

              count++;

          uint32 byte;

          uint8 byte1;

          uint8 byte2;

          uint8 byte3;

          uint8 byte4;

         

          if (count==1){

              byte1 = UART_1_UartGetChar();

              UART_2_UartPutChar(byte1);

              UART_2_UartPutChar(UART_1_SpiUartGetRxBufferSize());

          }

          else if (count==2){

              byte2 = UART_1_UartGetChar();

              UART_2_UartPutChar(byte2);

          }

          else if (count==3){

              byte3 = UART_1_UartGetChar();

              UART_2_UartPutChar(byte3);

              checkValue(byte1, byte2, byte3); //stuff to do with the read bytes

              tel =count;

          }

             

              UART_1_SpiUartClearRxBuffer();

             

              UART_1_ClearRxInterruptSource(UART_1_GetRxInterruptSourceMasked());

         

         // setvbuf(stdin, NULL,_IONBF, 0);   

         

         

         

         

      }

      }

        • 1. Re: UART interrupt triggered by '0' byte from MIDI keyboard
          AH_96

          Hello

           

          Could you please confirm the following for us?

          1. An optocoupler is only for isolation. How is data mismatch occurring because of that?

          2. Please confirm the data sent out by the MIDI device, if possible send the waveforms so that we can  confirm the data sent is correct.

          3. The Rx code is present in main outside the infinite while loop. It wont be executed. Please clarify on this. It should be present inside the infinite while loop.

          4. Please share the project so that we can debug faster and provide a resolution. What is the code inside the ISR? Is it checking for RxFIFO not empty condition?

          5. The interrupt has to be cleared and the data has to be read within the ISR. Otherwise, it might result in the ISR getting triggered continuously. Please confirm that the interrupt is cleared inside the ISR. The last two lines of the code seems redundant.

           

          Hoping to hear back from you.

           

          Thanks and regards

          Harigovind

          • 2. Re: UART interrupt triggered by '0' byte from MIDI keyboard
            simac_4074571

            Hi,

             

            While I was typing my question I accidentally pressed enter so I didn't

            check for any mistakes nor included the project, but this actually wasn't

            the original working project.

            In the project that you can download here <https://we.tl/t-HKasNcpjvu> the

            code to be executed is written directly in the ISR and this worked when

            tested. The signal from the keyboard has been measured and tested multiple

            times. The PSoC can actually detect the right bytes but the issue is (I

            think) that it's being triggered all the time, even when no key is pressed,

            so it never stops executing the interrupt routine. The optocoupler doesn't

            pose a problem, the data is read fine by the psoc.

             

            And yes the ISR is checking for RX FIFO NOT EMPTY and interrupt is being

            cleared inside the ISR.

             

            I should have posted this code from the beginning, my apologies for this.

            Kind regards and thanks in advance!

             

            Simon

             

            Here is the main followed by the ISR executed code:

             

            int main()

            {

             

                CyGlobalIntEnable;

             

                isr_1_StartEx(isr_1_Interrupt);

             

                isr_1_Enable();

            UART_1_Start();

                UART_2_Start();

             

                IDAC_1_Start();

                IDAC_1_SetValue(0);

             

                while(1){

             

                }

             

               // setvbuf(stdin, NULL,_IONBF, 0);

             

             

             

             

            }

            //ISR_1

            int tel = 0;

            void checkValue(uint8 command, uint8 note, uint8 speed);

            CY_ISR(isr_1_Interrupt)

            {

                #ifdef isr_1_INTERRUPT_INTERRUPT_CALLBACK

                    isr_1_Interrupt_InterruptCallback();

                #endif /* isr_1_INTERRUPT_INTERRUPT_CALLBACK */

             

                /*  Place your Interrupt code here. */

                /* `#START isr_1_Interrupt` */

             

                tel++;

             

             

                uint32 byte;

                uint8 byte1;

                uint8 byte2;

                uint8 byte3;

                uint8 byte4;

             

             

             

             

                if (tel==1){

                    byte1 = UART_1_UartGetChar();

                    UART_2_UartPutChar(byte1);

                    UART_2_UartPutChar(UART_1_SpiUartGetRxBufferSize());

                }

                else if (tel==2){

                    byte2 = UART_1_UartGetChar();

                    UART_2_UartPutChar(byte2);

                }

                else if (tel==3){

                    byte3 = UART_1_UartGetChar();

                    UART_2_UartPutChar(byte3);

                    checkValue(byte1, byte2, byte3);

                    tel =0;

                }

             

                    UART_1_SpiUartClearRxBuffer();

             

                    UART_1_ClearRxInterruptSource(UART_1_INTR_RX_NOT_EMPTY);

             

             

             

             

                /* `#END` */

            }

             

            void checkValue(uint8 command, uint8 note, uint8 speed){

                if (note == 60u){

                    IDAC_1_SetValue(255);

                }

                else if (note == 61u){

                    IDAC_1_SetValue(0);

                }

                else if (note == 62u){

                    IDAC_1_SetValue(255);

                }

                else if (note == 63u){

                    IDAC_1_SetValue(0);

                }

                else if (note == 64u){

                    IDAC_1_SetValue(255);

                }

                else if (note == 65u){

                    IDAC_1_SetValue(0);

                }

             

            }

             

             

             

             

            Op wo 15 mei 2019 om 09:35 schreef AH_96 <community-manager@cypress.com>:

             

            <http://www.cypress.com>

            Cypress Developer Community

            <https://community.cypress.com/?et=watches.email.thread>

            UART interrupt triggered by '0' byte from MIDI keyboard

             

            reply from AH_96

            <https://community.cypress.com/people/AH_96?et=watches.email.thread> in *PSoC

            4 MCU Community* - View the full discussion

            <https://community.cypress.com/message/196029?et=watches.email.thread#196029>

             

            • 3. Re: UART interrupt triggered by '0' byte from MIDI keyboard
              MoTa_728816

              Hi,

               

              I'm also interested in MIDI, but have not studied it yet.

               

              For the isr, may be you need to add isr_1_ClearPending() ;

               

              Meantime, may be because I'm not too flexible,

              but I don't feel comfortable having UART_2_UartPutChar()s in the isr routine.

               

              Also calling UART_1_SpiUartClearRxBuffer() may discard 2nd, 3rd data when receiving the first data.

               

              So if I were you I would modify the code  something like below.

               

              in isr_1.c

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

              CY_ISR(isr_1_Interrupt)

              {

                  #ifdef isr_1_INTERRUPT_INTERRUPT_CALLBACK

                      isr_1_Interrupt_InterruptCallback();

                  #endif /* isr_1_INTERRUPT_INTERRUPT_CALLBACK */

               

               

                  /*  Place your Interrupt code here. */

                  /* `#START isr_1_Interrupt` */

               

                  extern int packet_index ;

                  extern int packet_received ;

                  extern uint8_t packet[] ;

                  extern uint8_t packet_size ;

               

                  if (UART_1_SpiUartGetRxBufferSize()) { /* if we have any data */

                      packet[packet_index++] = UART_1_UartGetChar() ;

                      if (packet_index >= PACKET_SIZE) {

                          packet_index = 0 ;

                          packet_received = 1 ;

                      }

                  }

               

                  UART_1_ClearRxInterruptSource(UART_1_INTR_RX_NOT_EMPTY) ;

                  isr_1_ClearPending() ;

               

                  /* `#END` */

              }

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

               

              in main.c

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

              #include "common.h"

              #include "bas.h"

              #include "project.h"

              #include "isr_1.h"

              #include "stdio.h"

               

              char str[32] ; /* print buffer */

               

              int         packet_index = 0 ;

              uint8_t  packet_size ;

              int         packet_received = 0 ;

              uint8_t  packet[3] ;

               

              void checkValue(uint8_t command, uint8_t note, uint8_t speed)

              {

                  sprintf(str, "%02X %02X %02X\r\n", command, note, speed) ;

                  UART_2_UartPutString(str) ;

               

                  if (note == 60u){

                      IDAC_1_SetValue(255);

                  }

                  else if (note == 61u){

                      IDAC_1_SetValue(0);

                  }

                  else if (note == 62u){

                      IDAC_1_SetValue(255);

                  }

                  else if (note == 63u){

                      IDAC_1_SetValue(0);

                  }

                  else if (note == 64u){

                      IDAC_1_SetValue(255);

                  }

                  else if (note == 65u){

                      IDAC_1_SetValue(0);

                  }

              }

               

               

              int main()

              {

                  CyGlobalIntEnable;

               

                  UART_1_SpiUartClearRxBuffer() ;

                  UART_1_ClearRxInterruptSource(UART_1_INTR_RX_NOT_EMPTY) ;

               

                  isr_1_ClearPending() ;

                  isr_1_StartEx(isr_1_Interrupt);

               

                  UART_1_Start();

                  UART_2_Start();

               

                  IDAC_1_Start();

                  IDAC_1_SetValue(0);

               

                  while(1){

                      if (packet_received) {

                          checkValue(packet[0], packet[1], packet[2]) ;

                          packet_received = 0 ;

                      }

                  }

               

                 // setvbuf(stdin, NULL,_IONBF, 0);     

              }

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

               

              Note: In case this does not work, I'm very sorry for that.

               

              moto