4 channel Uart ISR

Beta Testing discussion on mikroPascal PRO for AVR.
Post Reply
Author
Message
jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

4 channel Uart ISR

#1 Post by jpc » 24 Apr 2009 08:19

with the new release some nice features are available amongst which the WITH statement , on the AVR1280 we have 4 Uart's , here some simple code to make better use of them

Code: Select all

unit irq_usart;
{ @jpc 2009 mp PRO for AVR v 1.30
  cpu : ATMEGA1280
  provides 4 simple interrupt driven uart-receivers with simple circular buffers
 }
  
procedure init_4_irq_uarts;
function getchar(channel : byte):byte;
function datareceived(channel: byte) : boolean;

implementation

const rx_bufsize      = 80;
      brate1          = 57600;
      brate2          = 57600;
      brate3          = 57600;
      brate4          = 57600;
      
type uart_type    =  record
                       rxbuffer : array[rx_bufsize] of byte;
                       head,
                       tail,
                       parity_error,
                       frame_error,
                       overrun_error : byte;
                     end;

var uarts         : array[4] of uart_type;

procedure uart1_isr; org IVT_ADDR_USART0__RX;
var err,dummy : byte;
begin
  with uarts[0] do
  begin
    err := UCSR0A and %00011100;
    if err = 0 then
    begin
      rxbuffer[head] := UDR0;
      if inc(head) = rx_bufsize then head := 0;
    end else
    begin
      dummy := UDR0; // flush the byte
      if err and %00010000 then inc(frame_error);
      if err and %00001000 then inc(overrun_error);
      if err and %00000100 then inc(parity_error);
    end;
  end;
end;

procedure uart2_isr; org IVT_ADDR_USART1__RX;
var err,dummy : byte;
begin
  with uarts[1] do
  begin
    err := UCSR1A and %00011100;
    if err = 0 then
    begin
      rxbuffer[head] := UDR1;
      if inc(head) = rx_bufsize then head := 0;
    end else
    begin
      dummy := UDR1; // flush the byte
      if err and %00010000 then inc(frame_error);
      if err and %00001000 then inc(overrun_error);
      if err and %00000100 then inc(parity_error);
    end;
  end;
end;

procedure uart3_isr;  org  IVT_ADDR_USART2__RX;
var err,dummy : byte;
begin
  with uarts[2] do
  begin
    err := UCSR2A and %00011100;
    if err = 0 then
    begin
      rxbuffer[head] := UDR2;
      if inc(head) = rx_bufsize then head := 0;
    end else
    begin
      dummy := UDR2; // flush the byte
      if err and %00010000 then inc(frame_error);
      if err and %00001000 then inc(overrun_error);
      if err and %00000100 then inc(parity_error);
    end;
  end;
end;

procedure uart4_isr; org IVT_ADDR_USART3__RX ;
var err,dummy : byte;
begin
  with uarts[3] do
  begin
    err := UCSR3A and %00011100;
    if err = 0 then
    begin
      rxbuffer[head] := UDR3;
      if inc(head) = rx_bufsize then head := 0;
    end else
    begin
      dummy := UDR3; // flush the byte
      if err and %00010000 then inc(frame_error);
      if err and %00001000 then inc(overrun_error);
      if err and %00000100 then inc(parity_error);
    end;
  end;
end;

function datareceived(channel:byte) : boolean;
begin
  with uarts[channel] do
  begin
    if head <> tail then datareceived := true else datareceived := false;
  end;
end;

function getchar(channel : byte):byte;
var tmp : byte;
begin
 with uarts[channel] do
  begin
    if(head <> tail) then
    begin
      result := rxbuffer[tail];
      if inc(tail) = rx_bufsize then tail := 0;
    end else getchar := 0;
  end;
end;


procedure init_4_irq_uarts;
begin
 // initialize uart Interrupt's and buffers
  memset(word(@uarts),0,sizeof(uarts));  // clear buffers
  UART1_Init(brate1);
  UART2_Init(brate2);
  UART3_Init(brate3);
  UART4_Init(brate4);
  UCSR0b := %10011000;  // enable RX Interrupt , enable rx and tx uart
  UCSR1b := %10011000;
  UCSR2b := %10011000;
  UCSR3b := %10011000;
end;
end.
test-program :

Code: Select all

program irq_4uart_test;
 { demo 4 channel Uart ISR for BigAVR with ATMEGA1280
   @jpc 2009, mikroPascal PRO for AVR  V1.30
   
  this little demo outputs ALL data received by 4 uart-channels to UART1
  connect terminal program on RS232-port , jumper the 4 uart_RX lines together on the headers
  
  any character send to the RSS232 will be received simultanously by the 4 ISR's
  }
var channel : byte;
procedure init_all;
begin
  init_4_irq_uarts;
  SREG.7 := 1; // global interrupt enable
  uart1_write_text('Demo 4 channel Uart');
  uart1_write(10);
  uart1_write(13);
end;

begin
  init_all;
  while true do
  begin
    for channel :=0 to 3 do
    begin
      if datareceived(channel) = true then
      begin
        uart1_write(getchar(channel));
      end;
    end;
  end;
end.
Au royaume des aveugles, les borgnes sont rois.

Post Reply

Return to “mikroPascal PRO for AVR Beta Testing”