Čeština / English
Login

SVN Repository / Prohlížení

Aktuální adresář: FITkit / trunk / mcu / libfitkit /

uart.c

   1  /*******************************************************************************
   2     uart.c:
   3     Copyright (C) 2009 Brno University of Technology,
   4                        Faculty of Information Technology
   5  
   6     LICENSE TERMS
   7  
   8     Redistribution and use in source and binary forms, with or without
   9     modification, are permitted provided that the following conditions
  10     are met:
  11     1. Redistributions of source code must retain the above copyright
  12        notice, this list of conditions and the following disclaimer.
  13     2. Redistributions in binary form must reproduce the above copyright
  14        notice, this list of conditions and the following disclaimer in
  15        the documentation and/or other materials provided with the
  16        distribution.
  17     3. All advertising materials mentioning features or use of this software
  18        or firmware must display the following acknowledgement:
  19  
  20          This product includes software developed by the University of
  21          Technology, Faculty of Information Technology, Brno and its
  22          contributors.
  23  
  24     4. Neither the name of the Company nor the names of its contributors
  25        may be used to endorse or promote products derived from this
  26        software without specific prior written permission.
  27  
  28     This software or firmware is provided ``as is'', and any express or implied
  29     warranties, including, but not limited to, the implied warranties of
  30     merchantability and fitness for a particular purpose are disclaimed.
  31     In no event shall the company or contributors be liable for any
  32     direct, indirect, incidental, special, exemplary, or consequential
  33     damages (including, but not limited to, procurement of substitute
  34     goods or services; loss of use, data, or profits; or business
  35     interruption) however caused and on any theory of liability, whether
  36     in contract, strict liability, or tort (including negligence or
  37     otherwise) arising in any way out of the use of this software, even
  38     if advised of the possibility of such damage.
  39  
  40     $Id$
  41  
  42     Popis:
  43       UART0 drive.
  44  *******************************************************************************/
  45  
  46  
  47  #include <signal.h>
  48  #include "arch_specific.h"
  49  #include "define.h"
  50  #include "timer_b.h"
  51  #include "globfun.h"
  52  #include "uart.h"
  53  #include "isr_compat.h"
  54  
  55  
  56  
  57  
  58  volatile unsigned char TransmitNum;       ///< kolik bytu je v bufferu
  59  
  60  
  61  
  62  
  63  volatile unsigned int ReceiveNum;        ///< kolik bytu je v bufferu
  64  
  65  
  66  
  67  volatile unsigned char PomRS232;
  68  
  69  
  70  /**
  71   \brief Inicializace UART0.
  72  
  73   **/
  74  void serial_init(void) {
  75    // inicializace promennych
  76    TransmitIndex     = 0;
  77    TransmitIndexSend = 0;
  78    TransmitNum       = 0;
  79    ReceiveIndex      = 0;
  80    ReceiveIndexRec   = 0;
  81    ReceiveNum        = 0;
  82    BreakFlag         = 0;
  83    ErrorFlag         = 0;
  84  
  85    #if defined MSP_16X
  86      // nastaveni serioveho kanalu (FITkit 1.x)
  87      U0CTL |= SWRST;              // Reset USART1
  88      U0CTL  = SWRST | CHAR;       // 8-bit character, no parity, 1 stop bit
  89      U0TCTL = SSEL_2;             // BRCLK = SMCLK (7.3728MHz)
  90      U0RCTL = URXEIE;             // prijem vsech znaku i chybnych
  91      U0BR0  = UART_BR0;           //nastaveni rychlosti (viz arch_specific.h)
  92      U0BR1  = UART_BR1;
  93  
  94      U0MCTL = 0x00;                        // no modulation
  95      ME1   |= UTXE0 + URXE0;               // Enabled USART0 RXD a TXD
  96  
  97      P3SEL |= TXDATA + RXDATA;             // P3.4 a P3.5 UART0
  98      P3DIR |= TXDATA;                      // TXDATA vystup
  99      P3DIR &= ~RXDATA;                     // RXDATA vstup
 100  
 101      U0CTL &= ~SWRST;                      // Povoleni USART
 102      IE1   |= URXIE0;                      // povoleni preruseni pri prijmu
 103  
 104    #elif defined MSP_261X
 105      // nastaveni serioveho kanalu (FITkit 2.x)
 106  
 107      UCA0CTL1 |= UCSWRST;                   // Reset USCI A0
 108      UCA0CTL0 = UCMODE_0 ;                  // 8-bit character, no parity, 1 stop bit
 109      UCA0CTL1 = UCSWRST | UCSSEL_2;         // BRCLK = SMCLK (7.3728MHz)
 110      UCA0BR0 = UART_BR0;                    //nastaveni rychlosti (viz arch_specific.h)
 111      UCA0BR1 = UART_BR1;
 112      UCA0MCTL = 0x00;                       // bez modulace
 113  
 114      P3SEL |= TXDATA + RXDATA;               // P3.4,5 = USCI_A0 TXD/RXD
 115      P3DIR |= TXDATA;                        // TXDATA vystup
 116      P3DIR &= ~RXDATA;                      // RXDATA vstup
 117  
 118      UCA0CTL1 &= ~UCSWRST;
 119  
 120      IE2 |= UCA0RXIE;                       // povoleni preruseni pri prijmu
 121      IE2 &= ~UCA0TXIE;                      // zakaz preruseni pri vysilani
 122    #else
 123      #error "Can't initialize UART"
 124    #endif
 125  }
 126  
 127  /**
 128   \brief Deinicializace UART0.
 129   **/
 130  void serial_close(void) {
 131    #if defined MSP_16X
 132       IE1   &= ~(URXIE0 | UTXIE0);          // zakaz preruseni pri prijmu a vysilani
 133       ME1   &= ~(UTXE0 | URXE0);            // Disable USART0 RXD a TXD
 134       U0CTL |= SWRST;                       // Reset USART1
 135    #elif defined MSP_261X
 136       IE2 &= ~(UCA0RXIE | UCA0TXIE);         // zakaz preruseni pri prijmu/vysilani
 137       UCA0CTL1 |= UCSWRST;                   // Reset USCI A0
 138    #endif
 139  
 140    // inicializace promennych, vyprazdneni buffru
 141    TransmitIndex     = 0;
 142    TransmitIndexSend = 0;
 143    TransmitNum       = 0;
 144    ReceiveIndex      = 0;
 145    ReceiveIndexRec   = 0;
 146    ReceiveNum        = 0;
 147    BreakFlag         = 0;
 148  }
 149  
 150  
 151  /**
 152  
 153  
 154   **/
 155  void term_send_char(char Uchar) {
 156  
 157    while (TransmitNum >= LengthBuffers_Tx) WDG_reset();
 158  
 159    TransmitBuf[TransmitIndex] = Uchar;
 160    TransmitIndex++;
 161    if (TransmitIndex >= LengthBuffers_Tx)
 162       TransmitIndex = 0;
 163    TransmitNum++;
 164  
 165    UART_enable_tx_irq(); // povoleni preruseni na vysilani
 166  }
 167  
 168  
 169  /**
 170  
 171  
 172   **/
 173  void term_send_char_idle(unsigned char Uchar) {
 174    while (UART_TX_BUF_FULL) WDG_reset();
 175    UART_TX_BUF = Uchar;
 176  }
 177  
 178  
 179  /**
 180  
 181  
 182   **/
 183  void term_send_char_hex(unsigned char Uchar) {
 184    unsigned char buf[3];
 185  
 186    chr2hex((unsigned char *)&buf, Uchar);
 187  
 188    term_send_char(buf[0]);
 189    term_send_char(buf[1]);
 190  }
 191  
 192  
 193  /**
 194  
 195   **/
 196  /* -- makro
 197  void term_send_crlf(void) {
 198    term_send_char(CR);
 199    term_send_char(LF);
 200  }
 201  */
 202  
 203  /**
 204  
 205  
 206  
 207   **/
 208  void term_send_str(char *ptrStr) {
 209    unsigned char Index = 0;
 210  
 211    while (ptrStr[Index] != 0) {
 212  
 213      WDG_reset();                                // software watchdog
 214  
 215      term_send_char(ptrStr[Index]);
 216      Index++;
 217    }
 218  }
 219  
 220  /**
 221  
 222  
 223  
 224   **/
 225  /* -- makro
 226  void term__snd_str_CRLF(char *ptrStr) {
 227    term_send_str(ptrStr);
 228    term_send_crlf();
 229  }
 230  */
 231  
 232  /**
 233  
 234  
 235   **/
 236  void term_send_num(long int iNum) {
 237    unsigned char buf[20];
 238  
 239    long2str(iNum, (unsigned char *)&buf, 10);
 240    term_send_str((unsigned char *)&buf);
 241  }
 242  
 243  
 244  /**
 245  
 246  
 247  
 248   **/
 249  /* -- makro
 250  void term_snd_real(long intn, long desn) {
 251    term_send_num(intn);
 252    term_send_char('.');
 253    term_send_num(desn);
 254  }
 255  */
 256  
 257  
 258  /**
 259  
 260  
 261   **/
 262  void term_send_hex(long int iNum) {
 263    unsigned char buf[20];
 264  
 265    long2str(iNum, (unsigned char *)&buf, 16);
 266    term_send_str((unsigned char *)&buf);
 267  }
 268  
 269  
 270  /**
 271  
 272  
 273   **/
 274  unsigned char term_rcv_char(void) {
 275    unsigned char Uchar;
 276    Uchar = 0;
 277    if (ReceiveNum > 0) {
 278      Uchar = ReceiveBuf[ReceiveIndex];
 279      ReceiveIndex++;
 280      if (ReceiveIndex >= LengthBuffers_Rx)
 281        ReceiveIndex = 0;
 282      ReceiveNum--;
 283    }
 284    return Uchar;
 285  }
 286  
 287  
 288  /**
 289  
 290  
 291  
 292  
 293  
 294   **/
 295  signed int term_rcv_block(unsigned char *out, int count) {
 296    int used = 0;
 297    unsigned char err_cnt = 127;
 298    while ((used < count) && (err_cnt > 0)) {
 299      if (ReceiveNum == 0) {
 300  
 301        WDG_reset();
 302  
 303        delay_ms(1);
 304        err_cnt--;
 305      }
 306      else {
 307        err_cnt = 127;
 308        *(out + used++) = ReceiveBuf[ReceiveIndex];
 309        if (ReceiveIndex == LengthBuffers_Rx-1)
 310          ReceiveIndex = 0;
 311        else
 312          ReceiveIndex++;
 313        ReceiveNum--;
 314      }
 315    }
 316    if (err_cnt == 0)
 317      return -1;
 318    else
 319      return used;
 320  }
 321  
 322  /**
 323  
 324  
 325  
 326   **/
 327  /* -- makro
 328  unsigned char term_snd_flag(void) {
 329    if ((TXEPT & U0TCTL) != 0)
 330      return 0;
 331    else
 332      return 1;
 333    //return (TXEPT & U0TCTL) ? 0 : 1;
 334  }
 335  */
 336  
 337  /**
 338  
 339  
 340   **/
 341  /* -- makro
 342  unsigned int term_rcv_flag(void) {
 343    return ReceiveNum;
 344  }
 345  */
 346  
 347  /**
 348  
 349  
 350  
 351  
 352   **/
 353  int term_rcv_char_t(long int timeout) {
 354    unsigned char Flag;
 355  
 356    Flag = term_rcv_flag();           // pocet bytu ve vyrovnacim bufferu RS232
 357  
 358    // dokud neprijde znak, nebo nevyprsi timeout mezi dvema znaky, nebo neprijde break
 359    while (Flag == 0) {
 360      if (--timeout < 0)
 361        return (-1);                      // vyprsel timeout mezi dvema znaky.
 362  
 363      WDG_reset();                                        // SW watchdog
 364  
 365      delay_ms(1);                         // cekam 1ms
 366      Flag = term_rcv_flag();         // pocet bytu ve vyrovnacim bufferu RS232
 367    }
 368    return term_rcv_char();
 369  }
 370  
 371  /**
 372  
 373  
 374   **/
 375  /* -- makro
 376  unsigned char term_trnsmt_flag(void) {
 377    return (LengthBuffers_Tx - TransmitNum);
 378  }
 379  */
 380  
 381  
 382  /**
 383  
 384   **/
 385  /* -- makro
 386  void term_flush_rx_buf(void) {
 387    while (term_rcv_flag() != 0) {
 388      term_rcv_char();
 389    }
 390  }
 391  */
 392  
 393  /**
 394  
 395   **/
 396  /* -- makro
 397  void term_flush_tx_buf(void) {
 398    while ((TransmitNum != 0) || ((U0TCTL & TXEPT) == 0));
 399  }
 400  */
 401  
 402  /**
 403     \brief Detekce BREAKu.
 404     \return 0 - nenastal BREAK
 405          \n 1 - BREAK nastal
 406   **/
 407  /* -- makro
 408  unsigned char term_dtct_break(void) {
 409  
 410    //return (BreakFlag != 0)? 1:0;
 411  
 412    return (BreakFlag != 0);
 413  }
 414  */
 415  
 416  
 417  /**
 418  
 419   **/
 420  /* -- makro
 421  void term_rst_break_flag(void) {
 422    BreakFlag = 0;
 423  }
 424  */
 425  
 426  /**
 427     \brief Detekce ERROR.
 428     \return 0 - nenastal ERROR,
 429          \n 1 - nastal ERROR
 430   **/
 431  /* -- makro
 432  unsigned char term_dtct_error(void) {
 433    // tak tohle nechapu, asi jsem debil
 434    unsigned char Errf;
 435    if (ErrorFlag != 0) {
 436      ErrorFlag = 0;
 437      return Errf;
 438    }
 439    else
 440      return 0;
 441  }
 442  */
 443  
 444  /**
 445   \brief  Preruseni pro vysilani dat.
 446   **/
 447  #if defined MSP_16X
 448  ISR(USART0TX, TxintrRS232) {
 449  #elif defined MSP_261X
 450  ISR(USCIAB0TX, TxintrRS232) {
 451  #endif
 452    if (TransmitNum > 0) {
 453      UART_TX_BUF = TransmitBuf[TransmitIndexSend];   // vyslani bytu
 454      TransmitNum--;
 455      TransmitIndexSend++;
 456      if (TransmitIndexSend >= LengthBuffers_Tx)
 457        TransmitIndexSend = 0;
 458    }
 459    if (TransmitNum == 0)
 460       UART_disable_tx_irq();                      // je-li posledni byte, zakaz preruseni
 461  }
 462  
 463  /**
 464   \brief Preruseni pri prijmu dat.
 465   **/
 466  #if defined MSP_16X
 467  ISR(USART0RX, RxintrRS232) {
 468  #elif defined MSP_261X
 469  ISR(USCIAB0RX, RxintrRS232) {
 470  #endif
 471  #ifdef MSP_16X
 472    // detekce BREAKu, musi byt pred ctenim UART_RX_BUF
 473    BreakFlag = ((U0RCTL & 0x10) != 0);
 474    if ((U0RCTL & RXERR) != 0) {                   // prijem chybneho znaku
 475      ErrorFlag = U0RCTL & 0xF0;
 476      PomRS232 = UART_RX_BUF;
 477    }
 478    else {
 479  #endif
 480      if (ReceiveNum < LengthBuffers_Rx) {
 481        ReceiveBuf[ReceiveIndexRec] = UART_RX_BUF;  // zapis dat do buffru
 482        ReceiveIndexRec++;
 483        if (ReceiveIndexRec >= LengthBuffers_Rx)
 484          ReceiveIndexRec = 0;
 485        ReceiveNum++;
 486      }
 487  #ifdef MSP_16X
 488    }
 489  #endif
 490  }
 491  
Zobrazeno: 731754x Naposledy: 29.11.2022 05:57:47