Subversion Repositories pentevo

Rev

Rev 898 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3.  
  4. #include "mytypes.h"
  5. #include "rs232.h"
  6. #include "pins.h"
  7.  
  8. //if want Log than comment next string
  9. #undef LOGENABLE
  10.  
  11. #define BAUD115200 115200
  12. #define BAUD256000 256000
  13. #define UBRR115200 (((F_CPU/16)/BAUD115200)-1)
  14. #define UBRR256000 (((F_CPU/16)/BAUD256000)-1)
  15.  
  16. //LINE STATUS REGISTER (LSR) bits (16550 chip emulation):
  17. //--------------------------------------------------------
  18. /** The receiver Data Ready (DR) indicator. */
  19. #define LSR_DR     0
  20. /** The Overrun Error (OE) indicator. */
  21. #define LSR_OE     1
  22. /** The Parity Error (PE) indicator. */
  23. #define LSR_PE     2  
  24. /** The Framing Error (FE) indicator. */
  25. #define LSR_FE     3
  26. /** The Break Interrupt (BI) indicator. */
  27. #define LSR_BI     4
  28. /** The Transmitter Holding Register Empty (THRE) indicator. */
  29. #define LSR_THRE   5
  30. /** The Transmitter Empty (TEMT) indicator. */
  31. #define LSR_TEMT   6
  32. /** The FIFO Half-Full indicator (custom flag: on ZX EVO only). */
  33. #define LSR_HF     7    
  34.  
  35. //LINE CONTROL REGISTER (LCR) bits (16550 chip emulation):
  36. //---------------------------------------------------------
  37. /**
  38.     These two bits specify the number of bits in each transmitted or received serial character.
  39.     Bit 1 Bit 0 Character Length
  40.     0     0     5 Bits
  41.     0     1     6 Bits
  42.     1     0     7 Bits
  43.     1     1     8 Bits
  44. */
  45. #define LCR_WLS0   0
  46. #define LCR_WLS1   1
  47. /** This bit specifies the number of Stop bits transmitted and received in each serial character. */
  48. #define LCR_STB    2
  49. /** This bit is the Parity Enable bit. */
  50. #define LCR_PEN    3
  51. /** This bit is the Even Parity Select bit. */
  52. #define LCR_EPS    4
  53. /** This bit is the Stick Parity bit. */
  54. #define LCR_SP     5
  55. /** This bit is the Break Control bit. */
  56. #define LCR_BC     6
  57. /** This bit is the Divisor Latch Access Bit (DLAB). */
  58. #define LCR_DLAB   7
  59.  
  60. //FIFO buffers size ((FIFO_SIZE-1) value used like mask - must be power of 2 and <= 256)
  61. #define FIFO_SIZE  16
  62.  
  63. //Registers for 16550 emulation:
  64.  
  65. //Divisor Latch LSB
  66. static UBYTE rs232_DLL;
  67. //Divisor Latch MSB
  68. static UBYTE rs232_DLM;
  69. //Interrupt Enable
  70. static UBYTE rs232_IER;
  71. //Interrupt Identification
  72. static UBYTE rs232_ISR;
  73. //FIFO Control
  74. static UBYTE rs232_FCR;
  75. //Line Control
  76. static UBYTE rs232_LCR;
  77. //Modem Control
  78. static UBYTE rs232_MCR;
  79. //Line Status
  80. static UBYTE rs232_LSR;
  81. //Modem Status
  82. static UBYTE rs232_MSR;
  83. //Scratch Pad
  84. static UBYTE rs232_SCR;
  85. //Fifo In
  86. static UBYTE rs232_FI[FIFO_SIZE];
  87. static UBYTE rs232_FI_start;
  88. static UBYTE rs232_FI_end;
  89. //Fifo Out
  90. static UBYTE rs232_FO[FIFO_SIZE];
  91. static UBYTE rs232_FO_start;
  92. static UBYTE rs232_FO_end;
  93.  
  94. void rs232_init(void)
  95. {
  96.         // Set baud rate
  97.         UBRR1H = (UBYTE)(UBRR115200>>8);
  98.         UBRR1L = (UBYTE)UBRR115200;
  99.         // Clear reg
  100.         UCSR1A = 0;
  101.         // Enable receiver and transmitter
  102.         UCSR1B = _BV(RXEN)|_BV(TXEN);
  103.         // Set frame format: 8data, 1stop bit
  104.         UCSR1C = _BV(USBS)|_BV(UCSZ0)|_BV(UCSZ1);
  105.  
  106.         //Set default values:
  107.         rs232_DLM = 0;
  108.         rs232_DLL = 0x01;
  109.         rs232_IER = 0;
  110.         rs232_FCR = 0x01; //FIFO always enable
  111.         rs232_ISR = 0x01;
  112.         rs232_LCR = 0;
  113.         rs232_MCR = 0;
  114.         rs232_LSR = _BV(LSR_THRE)|_BV(LSR_TEMT); //transmitter empty on start
  115.         rs232_MSR = 0xA0; //DSR=CD=1, RI=0
  116.         rs232_SCR = 0xFF;
  117.         rs232_FI_start = rs232_FI_end = 0;
  118.         rs232_FO_start = rs232_FO_end = 0;
  119. }
  120.  
  121. void rs232_transmit( UBYTE data )
  122. {
  123.         // Wait for empty transmit buffer
  124.         while ( !( UCSR1A & (1<<UDRE)) );
  125.         // Put data into buffer, sends the data
  126.         UDR1 = data;
  127. }
  128.  
  129. //#ifdef LOGENABLE
  130. void to_log(char* ptr)
  131. {
  132.         while( (*ptr)!=0 )
  133.         {
  134.                 rs232_transmit(*ptr);
  135.                 ptr++;
  136.         }
  137. }
  138. //#endif
  139.  
  140.  
  141. //after DLL or DLM changing
  142. void rs232_set_baud(void)
  143. {
  144.         if ( rs232_DLM|rs232_DLL )
  145.         {
  146.                 if ( (rs232_DLM&0x80) != 0 )
  147.                 {
  148.                         //AVR mode - direct load UBRR
  149.                         UBRR1H = 0x7F&rs232_DLM;
  150.                         UBRR1L = rs232_DLL;
  151.                 }
  152.                 else
  153.                 {
  154.                         //default mode - like 16550
  155.                         ULONG i = BAUD115200/ ((((UWORD)rs232_DLM)<<8) + rs232_DLL);
  156.                         UWORD rate = ((F_CPU/16)/i)-1;
  157.                         // Set baud rate
  158.                         UBRR1H = (UBYTE)(rate>>8);
  159.                         UBRR1L = (UBYTE)rate;
  160.                 }
  161.         }
  162.         else
  163.         {
  164.                 // If( ( rs232_DLM==0 ) && ( rs232_DLL==0 ) )
  165.                 // set rate to 256000 baud
  166.                 UBRR1H = (UBYTE)(UBRR256000>>8);
  167.                 UBRR1L = (UBYTE)UBRR256000;
  168.         }
  169. }
  170.  
  171. //after LCR changing
  172. void rs232_set_format(void)
  173. {
  174.         //set word length and stopbits
  175.         UBYTE format = ((rs232_LCR&(_BV(LCR_WLS0)|_BV(LCR_WLS1)|_BV(LCR_STB)))<<1);
  176.  
  177.         //set parity (only "No parity","Odd","Even" supported)
  178.         switch( rs232_LCR&(_BV(LCR_PEN)|_BV(LCR_EPS)|_BV(LCR_SP)) )
  179.         {
  180.                 case _BV(LCR_PEN):
  181.                         //odd parity
  182.                         format |= _BV(UPM0)|_BV(UPM1);
  183.                         break;
  184.                 case _BV(LCR_PEN)|_BV(LCR_EPS):
  185.                         //even parity
  186.                         format |= _BV(UPM1);
  187.                         break;
  188.                 //default - parity not used
  189.         }
  190.  
  191.         UCSR1C = format;
  192. }
  193.  
  194. void rs232_zx_write(UBYTE index, UBYTE data)
  195. {
  196. #ifdef LOGENABLE
  197.         char log_write[] = "A..D..W\r\n";
  198.         log_write[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
  199.         log_write[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
  200.         log_write[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
  201.         log_write[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
  202.         to_log(log_write);
  203. #endif
  204.         switch( index )
  205.         {
  206.         case 0:
  207.                 if ( rs232_LCR&_BV(LCR_DLAB) )
  208.                 {
  209.                         rs232_DLL = data;
  210.                         rs232_set_baud();
  211.                 }
  212.                 else
  213.                 {
  214.                         //place byte to transmitter's fifo
  215.                         if ( ( rs232_FO_end != rs232_FO_start ) ||
  216.                              ( rs232_LSR&_BV(LSR_THRE) ) )
  217.                         {
  218.                                 rs232_FO[rs232_FO_end] = data;
  219.                                 rs232_FO_end = (rs232_FO_end+1)&(FIFO_SIZE-1);
  220.  
  221.                                 //clear fifo empty flag
  222.                                 rs232_LSR &= ~(_BV(LSR_THRE)|_BV(LSR_TEMT));
  223.                         }
  224.                         else
  225.                         {
  226.                                 //fifo overload
  227.                         }
  228.                 }
  229.                 break;
  230.  
  231.         case 1:
  232.                 if ( rs232_LCR&_BV(LCR_DLAB) )
  233.                 {
  234.                         //write to DLM
  235.                         rs232_DLM = data;
  236.                         rs232_set_baud();
  237.                 }
  238.                 else
  239.                 {
  240.                         //bit 7-4 not used and set to '0'
  241.                         rs232_IER = data&0x0F;
  242.                 }
  243.                 break;
  244.  
  245.         case 2:
  246.                 if ( data&1 )
  247.                 {
  248.                         //FIFO always enable
  249.                         if ( data&(1<<1) )
  250.                         {
  251.                                 //receiver FIFO reset
  252.                                 rs232_FI_start = rs232_FI_end = 0;
  253.                                 //set empty FIFO flag and clear overrun flag
  254.                                 rs232_LSR &= ~(_BV(LSR_OE)|_BV(LSR_DR)|_BV(LSR_HF));
  255.                         }
  256.                        
  257.                         if ( data&(1<<2) )
  258.                         {
  259.                                 //tramsmitter FIFO reset
  260.                                 rs232_FO_start = rs232_FO_end = 0;
  261.                                 //set fifo is empty flag
  262.                                 rs232_LSR |= _BV(LSR_THRE)|_BV(LSR_TEMT);
  263.                         }
  264.                        
  265.                         rs232_FCR = data&0xC9;
  266.                 }
  267.                 break;
  268.  
  269.         case 3:
  270.                 rs232_LCR = data;
  271.                 rs232_set_format();
  272.                 break;
  273.  
  274.         case 4:
  275.                 //bit 7-5 not used and set to '0'
  276.                 rs232_MCR = data & 0x1F;
  277.                
  278.                 if ( data&(1<<1) )
  279.                 {
  280.                         //clear RTS
  281.                         RS232RTS_PORT &= ~_BV(RS232RTS);
  282.                 }
  283.                 else
  284.                 {
  285.                         //set RTS
  286.                         RS232RTS_PORT |= _BV(RS232RTS);
  287.                 }
  288.                 break;
  289.  
  290.         case 5:
  291.                 //rs232_LSR = data;
  292.                 break;
  293.  
  294.         case 6:
  295.                 //rs232_MSR = data;
  296.                 break;
  297.  
  298.         case 7:
  299.                 rs232_SCR = data;
  300.                 break;
  301.         }
  302. }
  303.  
  304. UBYTE rs232_zx_read(UBYTE index)
  305. {
  306.         UBYTE data = 0;
  307.         switch( index )
  308.         {
  309.         case 0:
  310.                 if ( rs232_LCR&_BV(LCR_DLAB) )
  311.                 {
  312.                         data = rs232_DLL;
  313.                 }
  314.                 else
  315.                 {
  316.                         //get byte from fifo in
  317.                         if ( rs232_LSR&_BV(LSR_DR) )
  318.                         {
  319.                                 data = rs232_FI[rs232_FI_start];
  320.                                 //to next fifo's byte
  321.                                 rs232_FI_start = (rs232_FI_start+1)&(FIFO_SIZE-1);
  322.  
  323.                                 if ( rs232_FI_start == rs232_FI_end )
  324.                                 {
  325.                                         //set empty FIFO flag
  326.                                         rs232_LSR &= ~(_BV(LSR_DR));
  327.                                 }
  328.                                
  329.                                 //check to clear half-full flag
  330.                             if ( ((rs232_FI_end-rs232_FI_start)&(FIFO_SIZE-1)) < (FIFO_SIZE/2) )
  331.                                 {
  332.                                         rs232_LSR &= ~(_BV(LSR_HF));
  333.                                 }
  334.                         }
  335.                 }
  336.                 break;
  337.  
  338.         case 1:
  339.                 if ( rs232_LCR&_BV(LCR_DLAB) )
  340.                 {
  341.                         data = rs232_DLM;
  342.                 }
  343.                 else
  344.                 {
  345.                         data = rs232_IER;
  346.                 }
  347.                 break;
  348.  
  349.         case 2:
  350.                 data = rs232_ISR;
  351.                 break;
  352.  
  353.         case 3:
  354.                 data = rs232_LCR;
  355.                 break;
  356.  
  357.         case 4:
  358.                 data = rs232_MCR;
  359.                 break;
  360.  
  361.         case 5:
  362.                 data = rs232_LSR;
  363.                 break;
  364.  
  365.         case 6:
  366.                 //DSR=CD=1
  367.                 data = rs232_MSR;
  368.                 //clear flags
  369.                 rs232_MSR &= 0xF0;
  370.                 break;
  371.  
  372.         case 7:
  373.                 data = rs232_SCR;
  374.                 break;
  375.         }
  376. #ifdef LOGENABLE
  377.         static UBYTE last = 0;
  378.         if ( last!=index )
  379.         {
  380.                 char log_read[] = "A..D..R\r\n";
  381.                 log_read[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
  382.                 log_read[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
  383.                 log_read[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
  384.                 log_read[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
  385.                 to_log(log_read);
  386.                 last = index;
  387.         }
  388. #endif
  389.         return data;
  390. }
  391.  
  392. void rs232_task(void)
  393. {
  394.         //send data
  395.         if( (rs232_LSR&_BV(LSR_THRE)) == 0 )
  396.         {
  397.                 if ( UCSR1A&_BV(UDRE) )
  398.                 {
  399.                         UDR1 = rs232_FO[rs232_FO_start];
  400.                         //to next fifo's byte
  401.                         rs232_FO_start = (rs232_FO_start+1)&(FIFO_SIZE-1);
  402.  
  403.                         if ( rs232_FO_start == rs232_FO_end )
  404.                         {
  405.                                 //set fifo is empty flag
  406.                                 rs232_LSR |= _BV(LSR_THRE)|_BV(LSR_TEMT);
  407.                         }
  408.                 }
  409.         }
  410.  
  411.         //receive data
  412.         if( UCSR1A&_BV(RXC) )
  413.         {
  414.                 BYTE b = UDR1;
  415.                 if ( (rs232_FI_end == rs232_FI_start) &&
  416.                      (rs232_LSR&_BV(LSR_DR)) )
  417.                 {
  418.                         //set overrun flag
  419.                         rs232_LSR |= _BV(LSR_OE);
  420.                 }
  421.                 else
  422.                 {
  423.                         //receive data
  424.                         rs232_FI[rs232_FI_end] = b;
  425.                         //to next fifo's byte
  426.                         rs232_FI_end = (rs232_FI_end+1)&(FIFO_SIZE-1);
  427.                         //set data received flag
  428.                         rs232_LSR |= _BV(LSR_DR);
  429.                        
  430.                         //check to set half-full flag
  431.                         if ( (rs232_FI_end == rs232_FI_start) ||
  432.                              (((rs232_FI_end-rs232_FI_start)&(FIFO_SIZE-1)) >= (FIFO_SIZE/2)) )
  433.                         {      
  434.                                 rs232_LSR |= _BV(LSR_HF);
  435.                         }
  436.                 }
  437.         }
  438.  
  439.         //statuses
  440.         if( UCSR1A&_BV(FE) )
  441.         {
  442.                 //frame error
  443.                 rs232_LSR |= _BV(LSR_FE);
  444.         }
  445.         else
  446.         {
  447.                 rs232_LSR &= ~_BV(LSR_FE);
  448.         }
  449.  
  450.         if( UCSR1A&_BV(UPE) )
  451.         {
  452.                 //parity error
  453.                 rs232_LSR |= _BV(LSR_PE);
  454.         }
  455.         else
  456.         {
  457.                 rs232_LSR &= ~_BV(LSR_PE);
  458.         }
  459.  
  460.         if( RS232CTS_PIN&_BV(RS232CTS) )
  461.         {
  462.                 //CTS clear
  463.                 if( (rs232_MSR&0x10) != 0 )
  464.                 {
  465. #ifdef LOGENABLE
  466.                         to_log("CTS\r\n");
  467. #endif
  468.                         //CTS changed - set flag
  469.                         rs232_MSR |= 0x01;
  470.                 }
  471.                
  472.                 rs232_MSR &= ~(0x10);
  473.         }
  474.         else
  475.         {
  476.                 //CTS set
  477.                 if( (rs232_MSR&0x10) == 0 )
  478.                 {
  479. #ifdef LOGENABLE
  480.                         to_log("CTS\r\n");
  481. #endif
  482.                         //CTS changed - set flag
  483.                         rs232_MSR |= 0x01;
  484.                 }
  485.                
  486.                 rs232_MSR |= 0x10;
  487.         }
  488. }
  489.