logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

UART Problem, ZDM-A1281-A2/B0 - FTDI 232RL

pszewczyk 30 Lis 2009 14:59 3909 4
  • #1 7327479
    pszewczyk
    Poziom 10  
    Witam,

    Mam problem z połączeniem mojego modułu Meshnetics poprzez UART z PC. Mówiąc dokładnie, mój układ nic nie wysyła do terminala PC. Poniżej przedstawiam schemat mojego połączenia:

    UART Problem, ZDM-A1281-A2/B0 - FTDI 232RL

    Wiem, że od razu zasugerujecie, że PIN-y RXD i TXD powinny być ze sobą połączone. W module Meshnetics-a są jeszcze połączenia wewnętrzne z siedzącym w układzie procesorem Atmega 1281 i zgodnie z dokumentacją modułu, tak właśnie należy podłączać piny (TXD - TXD i RXD - RXD).

    Hyper terminal (bo jego używam do połączenia z układem), łączy się z moim układem na porcie COM3 i nic więcej. Dla sprawdzenia połączyłem PIN-y TXD i RXD w FTDI i to co wysłałem z terminalu otrzymałem na nim. Wynika z tego, że PIN RXD modułu MEshnetics nie wykazuje kompletnie żadnej aktywności. Oto kod jaki napisąłem do obsługi UART dla tego modułu:

    
    
    static uint8_t usartTxBuffer[8] = "burak287";
    
    
    HAL_UsartDescriptor_t appUsartDescriptor = {
    
    .tty = USART_CHANNEL_1, 
    .mode = USART_MODE_ASYNC,
    .baudrate = USART_BAUDRATE_38400,
    .dataLength = USART_DATA8,
    .parity = USART_PARITY_NONE,
    .stopbits = USART_STOPBIT_1,
    .rxBuffer        = NULL,
    .rxBufferLength  = 0,
    .txBuffer = usartTxBuffer,                                    
    .txBufferLength  = 8,
    .rxCallback      = NULL,
    .txCallback      = NULL,
    .flowControl     = USART_FLOW_CONTROL_NONE,
    };
    
    /***************************************
             TIMER DEFINITION
    ***************************************/
    
    void SensorTimerFired(void)
    {
          appState = APP_I2C_TASK;
    
                   if (test==7)
                  {
                   GPIO_8_make_out();
                    
                   GPIO_8_set();
                  } else {
    
                   GPIO_8_clr();
                  }
             
                HAL_OpenUsart(&appUsartDescriptor);    
                test = HAL_WriteUsart(&appUsartDescriptor, usartTxBuffer, 8);
                HAL_CloseUsart(&appUsartDescriptor);
     
       SYS_PostTask(APL_TASK_ID);
    
    } 
    


    Polecenia otwierania portu i wysyłania danych wykonywane są w funkcji obsługi timera. Wiem, że ta funkcja się wykonuje bo zapala diodę w takich odstępach czasu w jakich powinna. Funkcja HAL_WriteUsart zwraca wartość 7, choć teoretycznie powinna 8 (funkcja zwraca wartości: -1 jeśli błąd, <0 ilość poprawnie wysłanych bajtów). Mam również 2-gi moduł ale sytuacja jest ta sama. Może ktoś z Was miał taki problem i wie co może być przyczyną? Bo ja już wyczerpałem pomysły:)

    Pozdrawiam
  • Pomocny post
    #2 7327706
    piti___
    Poziom 23  
    Wysyłanie realizuje nie wykorzystując stosu:

    
    static int uart_putchar(char c, FILE *stream);
    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE);
    
    
    
    #define DEBUG
    
    static int uart_putchar(char c, FILE *stream)
    {
    	stream = stream;	
    #ifdef DEBUG
        loop_until_bit_is_set(UCSR1A, UDRE1);
        UDR1 = c;
    #endif
        return 0;
    }
    


    W kodzie umieść jeszcze
    stdout = &mystdout;

    Funkcje stosu dla UARTa gubiły mi pojedyncze bajty. UART wykorzystuje tylko do debugowania. Teraz możesz pisać zwykłym printf'em.

    Na module ZigBit TXD oznacza wyjście, RXD wejście. Dopasuj to do konfiguracji FTDi.

    moja inicjalizacja UARTu:

    
    void appInitUARTManager()
    {
    	HAL_CloseUart(&appUartDescriptor);
      appUartDescriptor.tty        = UART_CHANNEL_1;       // UART channel
      appUartDescriptor.mode       = ASYNC;              // UART synchronization mode
      appUartDescriptor.baudrate     = UART_BAUDRATE_38400;    // UART baud rate
      appUartDescriptor.dataLength     = UART_DATA8;             // UART data length
      appUartDescriptor.parity       = UART_PARITY_NONE;       // UART parity mode. 
      appUartDescriptor.stopbits     = UART_STOPBIT_1;         // UART stop bit
      appUartDescriptor.flowControl    = UART_FLOW_CONTROL_NONE; // Flow control
      appUartDescriptor.rxBuffer       = NULL;      
      appUartDescriptor.rxBufferLength = 0;
      appUartDescriptor.txBuffer       = NULL;
      appUartDescriptor.txBufferLength = 0;
      appUartDescriptor.txCallback     = NULL;//appUartWriteConfirm;  // Callback function, confirming data writing
      //void(*  rxCallback )(uint8_t) 
      
      HAL_OpenUart(&appUartDescriptor); // Open UART using specified parameters
    
    }
    
  • #3 8289105
    Indios Bravos
    Poziom 11  
    Jak wygląda twoja funkcja do odbierania danych?
    Mam problem w bitcloud 1.9.0 dla avr raven, nie mogę odebrać bajtu, debugger pokazuje że UART dostał bajt, ale wydaje mi się że nie wchodzi funkcja rxCallback.

    
    void startUsartManager(void)
    {
      usartDescriptor.tty            = USART_CHANNEL_0;
      usartDescriptor.mode           = USART_MODE_ASYNC;
      usartDescriptor.flowControl    = USART_FLOW_CONTROL_NONE;
      usartDescriptor.baudrate       = USART_BAUDRATE_38400;
      usartDescriptor.dataLength     = USART_DATA8;
      usartDescriptor.parity         = USART_PARITY_NONE;
      usartDescriptor.stopbits       = USART_STOPBIT_1;
      usartDescriptor.rxBuffer       = &usartRxBuffer;
      usartDescriptor.rxBufferLength = sizeof(usartRxBuffer);
      usartDescriptor.txBuffer       = NULL;
      usartDescriptor.txBufferLength = 0;
      usartDescriptor.rxCallback     = rxCallback;
      usartDescriptor.txCallback     = txCallback;
      usartDescriptor.flowControl = USART_FLOW_CONTROL_NONE;
    
      OPEN_USART(&usartDescriptor);
    
    }
    
    static void txCallback (void) {
    	return;
    }
    
    static void rxCallback (uint16_t readByteLen) {
    	readByteLen = readByteLen;
    	if (READ_USART (&usartDescriptor, &usartRxBuffer, 1) == 0)
    		return;
    	else {
    		if (usartRxBuffer == 0xF0){
    		    appState = APP_STARTING_NETWORK_STATE;
              	appPostGlobalTask();
    			return;
    		}
    		else if (usartRxBuffer == 0xF1){
    			
    			appState = APP_LEAVING_NETWORK_STATE;
    			sendMessage (0xF1);
              	appPostGlobalTask();
    			return;
    			
    		}
    	}
    }
    
    


    EDIT:
    Wysyłanie zmieniłem na takie jak u Ciebie i chodzi bez problemów, więc deskryptor jest OK.
  • #4 8294062
    piti___
    Poziom 23  
    Witam,

    
    #include "types.h"
    #include "usart.h"
    #include "lowpower.h"
    #include "analize_msg.h"
    
    static uint8_t		RxBuf[50];
    volatile uint8_t	in_buf[50];
    
    volatile HAL_UsartDescriptor_t appUartDescriptor_rs1,appUartDescriptor_rs0;
    
    
    void Uart0RXByte(uint16_t rx_data);
    extern volatile AppState_t   appState;
    
    
    	 
    void appInitUARTManager()
    {
    	HAL_CloseUsart((HAL_UsartDescriptor_t*)&appUartDescriptor_rs1);
     	appUartDescriptor_rs1.tty        	= USART_CHANNEL_1;       // UART channel
      	appUartDescriptor_rs1.mode       	= USART_MODE_ASYNC;              // UART synchronization mode
      	appUartDescriptor_rs1.baudrate     	= USART_BAUDRATE_115200;    // UART baud rate
      	appUartDescriptor_rs1.dataLength    = USART_DATA8;             // UART data length
      	appUartDescriptor_rs1.parity       	= USART_PARITY_NONE;       // UART parity mode. 
      	appUartDescriptor_rs1.stopbits     	= USART_STOPBIT_1;         // UART stop bit
      	appUartDescriptor_rs1.flowControl   = USART_FLOW_CONTROL_NONE; // Flow control
      	appUartDescriptor_rs1.rxBuffer      = NULL;      
      	appUartDescriptor_rs1.rxBufferLength= 0;
      	appUartDescriptor_rs1.txBuffer      = NULL;
      	appUartDescriptor_rs1.txBufferLength= 0;
      	appUartDescriptor_rs1.txCallback    = NULL;//appUartWriteConfirm;  // Callback function, confirming data writing
    	appUartDescriptor_rs1.rxCallback	= NULL;
      	//void(*  rxCallback )(uint8_t) 
      
      	HAL_OpenUsart((HAL_UsartDescriptor_t*)&appUartDescriptor_rs1); // Open UART using specified parameters
    	
    	HAL_CloseUsart((HAL_UsartDescriptor_t*)&appUartDescriptor_rs0);
     	appUartDescriptor_rs0.tty        	= USART_CHANNEL_0;       // UART channel
      	appUartDescriptor_rs0.mode       	= USART_MODE_ASYNC;              // UART synchronization mode
    
    //  	appUartDescriptor_rs0.baudrate     	= UART_BAUDRATE_38400;    // UART baud rate
    
      	appUartDescriptor_rs0.baudrate     	= USART_BAUDRATE_115200;    // UART baud rate
      	appUartDescriptor_rs0.dataLength    = USART_DATA8;             // UART data length
      	appUartDescriptor_rs0.parity       	= USART_PARITY_NONE;       // UART parity mode. 
      	appUartDescriptor_rs0.stopbits     	= USART_STOPBIT_1;         // UART stop bit
      	appUartDescriptor_rs0.flowControl   = USART_FLOW_CONTROL_NONE; // Flow control
      	appUartDescriptor_rs0.rxBuffer      = RxBuf;      
      	appUartDescriptor_rs0.rxBufferLength= 47;
      	appUartDescriptor_rs0.txBuffer      = NULL;
      	appUartDescriptor_rs0.txBufferLength= 0;
      	appUartDescriptor_rs0.txCallback    = NULL;//appUartWriteConfirm;  // Callback function, confirming data writing
    	appUartDescriptor_rs0.rxCallback	= Uart0RXByte;
      
      	HAL_OpenUsart((HAL_UsartDescriptor_t*)&appUartDescriptor_rs0); // Open UART using specified parameters
    }
    
    void Uart0RXByte(uint16_t rx_data)
    {
    	// dodac timeout !!!
    
    	if(appState == APP_IN_NETWORK_STATE)
    		if(rx_data == 46)
    		{
    			HAL_ReadUsart((HAL_UsartDescriptor_t*)&appUartDescriptor_rs0,(uint8_t*)&in_buf,rx_data);
    			appState = APP_PROCESS_PC_MSG;
    			SYS_PostTask(APL_TASK_ID);
    		}
    }
    
    //eof uartManager.c 
    


    Osobiście zrezygnuje ze stosu. Jeśli nie korzystasz z routingu to najlepiej napisać własne oprogramowanie obsługi transceiverów. Przykładowy soft to chibi ze strony freaklabs. 3-4kB kodu i masz wysyłanie pod konkretny adres i odbieranie.

    Udało mi się przystosować stos Chibi do modułu ZigBit. Chodzi idealnie, uśpienie transceivera i procesora daje 6uA.

    Pozdrawiam
  • #5 8361677
    Indios Bravos
    Poziom 11  
    Dzieki za pomoc, przepraszam że nie odpisałem wcześniej ale nie zauważyłem Twojej odpowiedzi, a do rozwiązania doszedłem sam:)

    Problemem u mnie był za mały bufor RX, wysyłam komendy 1-znakowe więc myślałem że nie będzie problemu jak zostanie 1 bajt, ale okazało się że trzeba dać więcej (dałem 5 znaków).

    Właśnie korzystam z routingu, gdyż robię sieć rozproszoną, ale sugestia o własnym stosie do połączeń typu star jak najbardziej słuszna. Sam naskrobałem coś takiego bazując na bibliotekach Atmela z http://atmel.com/forms/avr_raven_download.asp...dl_AVR2017_RZRAVEN_Firmware.zip&family_id=676
    Też spoko działało, ale prądu nie zmierzyłem bo nie były mi potrzebne baterie.
REKLAMA