Subversion Repositories pentevo

Rev

Rev 374 | Rev 478 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.                 ULONG i = BAUD115200/ ((((UWORD)rs232_DLM)<<8) + rs232_DLL);
  100.                 UWORD rate = ((F_CPU/16)/i)-1;
  101.                 // Set baud rate
  102.                 UBRR1H = (UBYTE)(rate>>8);
  103.                 UBRR1L = (UBYTE)rate;
  104.         }
  105.         else
  106.         {
  107.                 // If( ( rs232_DLM==0 ) && ( rs232_DLL==0 ) )
  108.                 // set rate to 256000 baud
  109.                 UBRR1H = (UBYTE)(UBRR256000>>8);
  110.                 UBRR1L = (UBYTE)UBRR256000;
  111.         }
  112. }
  113.  
  114. //after LCR changing
  115. void rs232_set_format(void)
  116. {
  117.         //set word length and stopbits
  118.         UBYTE format = ((rs232_LCR&0x07)<<1);
  119.  
  120.         //set parity (only "No parity","Odd","Even" supported)
  121.         switch( rs232_LCR&0x38 )
  122.         {
  123.                 case 0x08:
  124.                         //odd parity
  125.                         format |= _BV(UPM0)|_BV(UPM1);
  126.                         break;
  127.                 case 0x18:
  128.                         //even parity
  129.                         format |= _BV(UPM1);
  130.                         break;
  131.                 //default - parity not used
  132.         }
  133.  
  134.         UCSR1C = format;
  135. }
  136.  
  137. void rs232_zx_write(UBYTE index, UBYTE data)
  138. {
  139. #ifdef LOGENABLE
  140.         char log_write[] = "A..D..W\r\n";
  141.         log_write[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
  142.         log_write[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
  143.         log_write[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
  144.         log_write[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
  145.         to_log(log_write);
  146. #endif
  147.         switch( index )
  148.         {
  149.         case 0:
  150.                 if ( rs232_LCR & 0x80 )
  151.                 {
  152.                         rs232_DLL = data;
  153.                         rs232_set_baud();
  154.                 }
  155.                 else
  156.                 {
  157.                         //place byte to fifo out
  158.                         if ( ( rs232_FO_end != rs232_FO_start ) ||
  159.                              ( rs232_LSR&0x20 ) )
  160.                         {
  161.                                 rs232_FO[rs232_FO_end] = data;
  162.                                 rs232_FO_end = (rs232_FO_end + 1) & 0x0F;
  163.  
  164.                                 //clear fifo empty flag
  165.                                 rs232_LSR &= ~(0x60);
  166.                         }
  167.                         else
  168.                         {
  169.                                 //fifo overload
  170.                         }
  171.                 }
  172.                 break;
  173.  
  174.         case 1:
  175.                 if ( rs232_LCR & 0x80 )
  176.                 {
  177.                         //write to DLM
  178.                         rs232_DLM = data;
  179.                         rs232_set_baud();
  180.                 }
  181.                 else
  182.                 {
  183.                         //bit 7-4 not used and set to '0'
  184.                         rs232_IER = data & 0x0F;
  185.                 }
  186.                 break;
  187.  
  188.         case 2:
  189.                 if( data&1 )
  190.                 {
  191.                         //FIFO always enable
  192.                         if( data&(1<<1) )
  193.                         {
  194.                                 //receive FIFO reset
  195.                                 rs232_FI_start = rs232_FI_end = 0;
  196.                                 //set empty FIFO flag
  197.                                 rs232_LSR &= ~(0x01);
  198.                         }
  199.                         if( data&(1<<2) )
  200.                         {
  201.                                 //tramsmit FIFO reset
  202.                                 rs232_FO_start = rs232_FO_end = 0;
  203.                                 //set fifo is empty flag
  204.                                 rs232_LSR |= 0x60;
  205.                         }
  206.                         rs232_FCR = data&0xC9;
  207.                 }
  208.                 break;
  209.  
  210.         case 3:
  211.                 rs232_LCR = data;
  212.                 rs232_set_format();
  213.                 break;
  214.  
  215.         case 4:
  216.                 //bit 7-5 not used and set to '0'
  217.                 rs232_MCR = data & 0x1F;
  218.                 if ( data&(1<<1) )
  219.                 {
  220.                         //clear RTS
  221.                         RS232RTS_PORT |= _BV(RS232RTS);
  222.                 }
  223.                 else
  224.                 {
  225.                         //set RTS
  226.                         RS232RTS_PORT &= ~(_BV(RS232RTS));
  227.                 }
  228.                 break;
  229.  
  230.         case 5:
  231.                 //rs232_LSR = data;
  232.                 break;
  233.  
  234.         case 6:
  235.                 //rs232_MSR = data;
  236.                 break;
  237.  
  238.         case 7:
  239.                 rs232_SCR = data;
  240.                 break;
  241.         }
  242. }
  243.  
  244. UBYTE rs232_zx_read(UBYTE index)
  245. {
  246.         UBYTE data = 0;
  247.         switch( index )
  248.         {
  249.         case 0:
  250.                 if ( rs232_LCR & 0x80 )
  251.                 {
  252.                         data = rs232_DLL;
  253.                 }
  254.                 else
  255.                 {
  256.                         //get byte from fifo in
  257.                         if ( rs232_LSR&0x01 )
  258.                         {
  259.                                 data = rs232_FI[rs232_FI_start];
  260.                                 rs232_FI_start = ( rs232_FI_start + 1 ) & 0x0F;
  261.  
  262.                                 if( rs232_FI_start == rs232_FI_end )
  263.                                 {
  264.                                         //set empty FIFO flag
  265.                                         rs232_LSR &= ~(0x01);
  266.                                 }
  267.                         }
  268.                 }
  269.                 break;
  270.  
  271.         case 1:
  272.                 if ( rs232_LCR & 0x80 )
  273.                 {
  274.                         data = rs232_DLM;
  275.                 }
  276.                 else
  277.                 {
  278.                         data = rs232_IER;
  279.                 }
  280.                 break;
  281.  
  282.         case 2:
  283.                 data = rs232_ISR;
  284.                 break;
  285.  
  286.         case 3:
  287.                 data = rs232_LCR;
  288.                 break;
  289.  
  290.         case 4:
  291.                 data = rs232_MCR;
  292.                 break;
  293.  
  294.         case 5:
  295.                 data = rs232_LSR;
  296.                 break;
  297.  
  298.         case 6:
  299.                 //DSR=CD=1
  300.                 data = rs232_MSR;
  301.                 //clear flags
  302.                 rs232_MSR &= 0xF0;
  303.                 break;
  304.  
  305.         case 7:
  306.                 data = rs232_SCR;
  307.                 break;
  308.         }
  309. #ifdef LOGENABLE
  310.         static UBYTE last = 0;
  311.         if ( last!=index )
  312.         {
  313.                 char log_read[] = "A..D..R\r\n";
  314.                 log_read[1] = ((index >> 4) <= 9 )?'0'+(index >> 4):'A'+((index >> 4)-10);
  315.                 log_read[2] = ((index & 0x0F) <= 9 )?'0'+(index & 0x0F):'A'+(index & 0x0F)-10;
  316.                 log_read[4] = ((data >> 4) <= 9 )?'0'+(data >> 4):'A'+((data >> 4)-10);
  317.                 log_read[5] = ((data & 0x0F) <= 9 )?'0'+(data & 0x0F):'A'+((data & 0x0F)-10);
  318.                 to_log(log_read);
  319.                 last = index;
  320.         }
  321. #endif
  322.         return data;
  323. }
  324.  
  325. void rs232_task(void)
  326. {
  327.         //send data
  328.         if( (rs232_LSR&0x20)==0 )
  329.         {
  330.                 if ( UCSR1A&_BV(UDRE) )
  331.                 {
  332.                         UDR1 = rs232_FO[rs232_FO_start];
  333.                         rs232_FO_start = (rs232_FO_start+1)&0x0F;
  334.  
  335.                         if( rs232_FO_start == rs232_FO_end )
  336.                         {
  337.                                 //set fifo is empty flag
  338.                                 rs232_LSR |= 0x60;
  339.                         }
  340.                 }
  341.         }
  342.  
  343.         //receive data
  344.         if( UCSR1A&_BV(RXC) )
  345.         {
  346.                 BYTE b = UDR1;
  347.                 if( (rs232_FI_end == rs232_FI_start) &&
  348.                     (rs232_LSR&0x01) )
  349.                 {
  350.                         //set overrun flag
  351.                         rs232_LSR|=0x02;
  352.                 }
  353.                 else
  354.                 {
  355.                         //receive data
  356.                         rs232_FI[rs232_FI_end] = b;
  357.                         rs232_FI_end = (rs232_FI_end+1)&0x0F;
  358.                         //set data received flag
  359.                         rs232_LSR |= 0x01;
  360.                 }
  361.         }
  362.  
  363.         //statuses
  364.         if( UCSR1A&_BV(FE) )
  365.         {
  366.                 //frame error
  367.                 rs232_LSR |= 0x08;
  368.         }
  369.         else
  370.         {
  371.                 rs232_LSR &= ~(0x08);
  372.         }
  373.  
  374.         if( UCSR1A&_BV(UPE) )
  375.         {
  376.                 //parity error
  377.                 rs232_LSR |= 0x04;
  378.         }
  379.         else
  380.         {
  381.                 rs232_LSR &= ~(0x04);
  382.         }
  383.  
  384.         if( RS232CTS_PIN&_BV(RS232CTS) )
  385.         {
  386.                 //CTS clear
  387.                 if( (rs232_MSR&0x10)!=0 )
  388.                 {
  389. #ifdef LOGENABLE
  390.                         to_log("CTS\r\n");
  391. #endif
  392.                         //CTS changed - set flag
  393.                         rs232_MSR |= 0x01;
  394.                 }
  395.                 rs232_MSR &= ~(0x10);
  396.         }
  397.         else
  398.         {
  399.                 //CTS set
  400.                 if( (rs232_MSR&0x10)==0 )
  401.                 {
  402. #ifdef LOGENABLE
  403.                         to_log("CTS\r\n");
  404. #endif
  405.                         //CTS changed - set flag
  406.                         rs232_MSR |= 0x01;
  407.                 }
  408.                 rs232_MSR |= 0x10;
  409.         }
  410. }
  411.