Subversion Repositories pentevo

Rev

Go to most recent revision | 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. //Registers for 16550 emulation:
  17.  
  18. //Divisor Latch LSB
  19. static UBYTE rs232_DLL;
  20. //Divisor Latch MSB
  21. static UBYTE rs232_DLM;
  22. //Interrupt Enable
  23. static UBYTE rs232_IER;
  24. //Interrupt Identification
  25. static UBYTE rs232_ISR;
  26. //FIFO Control
  27. static UBYTE rs232_FCR;
  28. //Line Control
  29. static UBYTE rs232_LCR;
  30. //Modem Control
  31. static UBYTE rs232_MCR;
  32. //Line Status
  33. static UBYTE rs232_LSR;
  34. //Modem Status
  35. static UBYTE rs232_MSR;
  36. //Scratch Pad
  37. static UBYTE rs232_SCR;
  38. //Fifo In
  39. static UBYTE rs232_FI[16];
  40. static UBYTE rs232_FI_start;
  41. static UBYTE rs232_FI_end;
  42. //Fifo Out
  43. static UBYTE rs232_FO[16];
  44. static UBYTE rs232_FO_start;
  45. static UBYTE rs232_FO_end;
  46.  
  47. void rs232_init(void)
  48. {
  49.         // Set baud rate
  50.         UBRR1H = (UBYTE)(UBRR115200>>8);
  51.         UBRR1L = (UBYTE)UBRR115200;
  52.         // Clear reg
  53.         UCSR1A = 0;
  54.         // Enable receiver and transmitter
  55.         UCSR1B = _BV(RXEN)|_BV(TXEN);
  56.         // Set frame format: 8data, 1stop bit
  57.         UCSR1C = _BV(USBS)|_BV(UCSZ0)|_BV(UCSZ1);
  58.  
  59.         //Set default values:
  60.         rs232_DLM = 0;
  61.         rs232_DLL = 0x01;
  62.         rs232_IER = 0;
  63.         rs232_FCR = 0x01; //FIFO always enable
  64.         rs232_ISR = 0x01;
  65.         rs232_LCR = 0;
  66.         rs232_MCR = 0;
  67.         rs232_LSR = 0x60;
  68.         rs232_MSR = 0xA0; //DSR=CD=1, RI=0
  69.         rs232_SCR = 0xFF;
  70.         rs232_FI_start = rs232_FI_end = 0;
  71.         rs232_FO_start = rs232_FO_end = 0;
  72. }
  73.  
  74. void rs232_transmit( UBYTE data )
  75. {
  76.         // Wait for empty transmit buffer
  77.         while ( !( UCSR1A & (1<<UDRE)) );
  78.         // Put data into buffer, sends the data
  79.         UDR1 = data;
  80. }
  81.  
  82. //#ifdef LOGENABLE
  83. void to_log(char* ptr)
  84. {
  85.         while( (*ptr)!=0 )
  86.         {
  87.                 rs232_transmit(*ptr);
  88.                 ptr++;
  89.         }
  90. }
  91. //#endif
  92.  
  93.  
  94. //after DLL or DLM changing
  95. void rs232_set_baud(void)
  96. {
  97.         if ( rs232_DLM | rs232_DLL )
  98.         {
  99.                 if( (rs232_DLM&0x80)!=0 )
  100.                 {
  101.                         //AVR mode - direct load UBRR
  102.                         UBRR1H = 0x7F&rs232_DLM;
  103.                         UBRR1L = rs232_DLL;
  104.                 }
  105.                 else
  106.                 {
  107.                         //default mode - like 16550
  108.                         ULONG i = BAUD115200/ ((((UWORD)rs232_DLM)<<8) + rs232_DLL);
  109.                         UWORD rate = ((F_CPU/16)/i)-1;
  110.                         // Set baud rate
  111.                         UBRR1H = (UBYTE)(rate>>8);
  112.                         UBRR1L = (UBYTE)rate;
  113.                 }
  114.         }
  115.         else
  116.         {
  117.                 // If( ( rs232_DLM==0 ) && ( rs232_DLL==0 ) )
  118.                 // set rate to 256000 baud
  119.                 UBRR1H = (UBYTE)(UBRR256000>>8);
  120.                 UBRR1L = (UBYTE)UBRR256000;
  121.         }
  122. }
  123.  
  124. //after LCR changing
  125. void rs232_set_format(void)
  126. {
  127.         //set word length and stopbits
  128.         UBYTE format = ((rs232_LCR&0x07)<<1);
  129.  
  130.         //set parity (only "No parity","Odd","Even" supported)
  131.         switch( rs232_LCR&0x38 )
  132.         {
  133.                 case 0x08:
  134.                         //odd parity
  135.                         format |= _BV(UPM0)|_BV(UPM1);
  136.                         break;
  137.                 case 0x18:
  138.                         //even parity
  139.                         format |= _BV(UPM1);
  140.                         break;
  141.                 //default - parity not used
  142.         }
  143.  
  144.         UCSR1C = format;
  145. }
  146.  
  147. void rs232_zx_write(UBYTE index, UBYTE data)
  148. {
  149. #ifdef LOGENABLE
  150.         char log_write[] = "A..D..W\r\n";
  151.         log_write[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
  152.         log_write[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
  153.         log_write[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
  154.         log_write[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
  155.         to_log(log_write);
  156. #endif
  157.         switch( index )
  158.         {
  159.         case 0:
  160.                 if ( rs232_LCR & 0x80 )
  161.                 {
  162.                         rs232_DLL = data;
  163.                         rs232_set_baud();
  164.                 }
  165.                 else
  166.                 {
  167.                         //place byte to fifo out
  168.                         if ( ( rs232_FO_end != rs232_FO_start ) ||
  169.                              ( rs232_LSR&0x20 ) )
  170.                         {
  171.                                 rs232_FO[rs232_FO_end] = data;
  172.                                 rs232_FO_end = (rs232_FO_end + 1) & 0x0F;
  173.  
  174.                                 //clear fifo empty flag
  175.                                 rs232_LSR &= ~(0x60);
  176.                         }
  177.                         else
  178.                         {
  179.                                 //fifo overload
  180.                         }
  181.                 }
  182.                 break;
  183.  
  184.         case 1:
  185.                 if ( rs232_LCR & 0x80 )
  186.                 {
  187.                         //write to DLM
  188.                         rs232_DLM = data;
  189.                         rs232_set_baud();
  190.                 }
  191.                 else
  192.                 {
  193.                         //bit 7-4 not used and set to '0'
  194.                         rs232_IER = data & 0x0F;
  195.                 }
  196.                 break;
  197.  
  198.         case 2:
  199.                 if( data&1 )
  200.                 {
  201.                         //FIFO always enable
  202.                         if( data&(1<<1) )
  203.                         {
  204.                                 //receive FIFO reset
  205.                                 rs232_FI_start = rs232_FI_end = 0;
  206.                                 //set empty FIFO flag and clear overrun flag
  207.                                 rs232_LSR &= ~(0x03);
  208.                         }
  209.                         if( data&(1<<2) )
  210.                         {
  211.                                 //tramsmit FIFO reset
  212.                                 rs232_FO_start = rs232_FO_end = 0;
  213.                                 //set fifo is empty flag
  214.                                 rs232_LSR |= 0x60;
  215.                         }
  216.                         rs232_FCR = data&0xC9;
  217.                 }
  218.                 break;
  219.  
  220.         case 3:
  221.                 rs232_LCR = data;
  222.                 rs232_set_format();
  223.                 break;
  224.  
  225.         case 4:
  226.                 //bit 7-5 not used and set to '0'
  227.                 rs232_MCR = data & 0x1F;
  228.                 if ( data&(1<<1) )
  229.                 {
  230.                         //clear RTS
  231.                         RS232RTS_PORT &= ~(_BV(RS232RTS));
  232.                 }
  233.                 else
  234.                 {
  235.                         //set RTS
  236.                         RS232RTS_PORT |= _BV(RS232RTS);
  237.                 }
  238.                 break;
  239.  
  240.         case 5:
  241.                 //rs232_LSR = data;
  242.                 break;
  243.  
  244.         case 6:
  245.                 //rs232_MSR = data;
  246.                 break;
  247.  
  248.         case 7:
  249.                 rs232_SCR = data;
  250.                 break;
  251.         }
  252. }
  253.  
  254. UBYTE rs232_zx_read(UBYTE index)
  255. {
  256.         UBYTE data = 0;
  257.         switch( index )
  258.         {
  259.         case 0:
  260.                 if ( rs232_LCR & 0x80 )
  261.                 {
  262.                         data = rs232_DLL;
  263.                 }
  264.                 else
  265.                 {
  266.                         //get byte from fifo in
  267.                         if ( rs232_LSR&0x01 )
  268.                         {
  269.                                 data = rs232_FI[rs232_FI_start];
  270.                                 rs232_FI_start = ( rs232_FI_start + 1 ) & 0x0F;
  271.  
  272.                                 if( rs232_FI_start == rs232_FI_end )
  273.                                 {
  274.                                         //set empty FIFO flag
  275.                                         rs232_LSR &= ~(0x01);
  276.                                 }
  277.                         }
  278.                 }
  279.                 break;
  280.  
  281.         case 1:
  282.                 if ( rs232_LCR & 0x80 )
  283.                 {
  284.                         data = rs232_DLM;
  285.                 }
  286.                 else
  287.                 {
  288.                         data = rs232_IER;
  289.                 }
  290.                 break;
  291.  
  292.         case 2:
  293.                 data = rs232_ISR;
  294.                 break;
  295.  
  296.         case 3:
  297.                 data = rs232_LCR;
  298.                 break;
  299.  
  300.         case 4:
  301.                 data = rs232_MCR;
  302.                 break;
  303.  
  304.         case 5:
  305.                 data = rs232_LSR;
  306.                 break;
  307.  
  308.         case 6:
  309.                 //DSR=CD=1
  310.                 data = rs232_MSR;
  311.                 //clear flags
  312.                 rs232_MSR &= 0xF0;
  313.                 break;
  314.  
  315.         case 7:
  316.                 data = rs232_SCR;
  317.                 break;
  318.         }
  319. #ifdef LOGENABLE
  320.         static UBYTE last = 0;
  321.         if ( last!=index )
  322.         {
  323.                 char log_read[] = "A..D..R\r\n";
  324.                 log_read[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
  325.                 log_read[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
  326.                 log_read[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
  327.                 log_read[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
  328.                 to_log(log_read);
  329.                 last = index;
  330.         }
  331. #endif
  332.         return data;
  333. }
  334.  
  335. void rs232_task(void)
  336. {
  337.         //send data
  338.         if( (rs232_LSR&0x20)==0 )
  339.         {
  340.                 if ( UCSR1A&_BV(UDRE) )
  341.                 {
  342.                         UDR1 = rs232_FO[rs232_FO_start];
  343.                         rs232_FO_start = (rs232_FO_start+1)&0x0F;
  344.  
  345.                         if( rs232_FO_start == rs232_FO_end )
  346.                         {
  347.                                 //set fifo is empty flag
  348.                                 rs232_LSR |= 0x60;
  349.                         }
  350.                 }
  351.         }
  352.  
  353.         //receive data
  354.         if( UCSR1A&_BV(RXC) )
  355.         {
  356.                 BYTE b = UDR1;
  357.                 if( (rs232_FI_end == rs232_FI_start) &&
  358.                     (rs232_LSR&0x01) )
  359.                 {
  360.                         //set overrun flag
  361.                         rs232_LSR|=0x02;
  362.                 }
  363.                 else
  364.                 {
  365.                         //receive data
  366.                         rs232_FI[rs232_FI_end] = b;
  367.                         rs232_FI_end = (rs232_FI_end+1)&0x0F;
  368.                         //set data received flag
  369.                         rs232_LSR |= 0x01;
  370.                 }
  371.         }
  372.  
  373.         //statuses
  374.         if( UCSR1A&_BV(FE) )
  375.         {
  376.                 //frame error
  377.                 rs232_LSR |= 0x08;
  378.         }
  379.         else
  380.         {
  381.                 rs232_LSR &= ~(0x08);
  382.         }
  383.  
  384.         if( UCSR1A&_BV(UPE) )
  385.         {
  386.                 //parity error
  387.                 rs232_LSR |= 0x04;
  388.         }
  389.         else
  390.         {
  391.                 rs232_LSR &= ~(0x04);
  392.         }
  393.  
  394.         if( RS232CTS_PIN&_BV(RS232CTS) )
  395.         {
  396.                 //CTS clear
  397.                 if( (rs232_MSR&0x10)!=0 )
  398.                 {
  399. #ifdef LOGENABLE
  400.                         to_log("CTS\r\n");
  401. #endif
  402.                         //CTS changed - set flag
  403.                         rs232_MSR |= 0x01;
  404.                 }
  405.                 rs232_MSR &= ~(0x10);
  406.         }
  407.         else
  408.         {
  409.                 //CTS set
  410.                 if( (rs232_MSR&0x10)==0 )
  411.                 {
  412. #ifdef LOGENABLE
  413.                         to_log("CTS\r\n");
  414. #endif
  415.                         //CTS changed - set flag
  416.                         rs232_MSR |= 0x01;
  417.                 }
  418.                 rs232_MSR |= 0x10;
  419.         }
  420. }
  421.