changeset 203:84746acd2e0e main

Add support for the atmega64m1 (pretty much the same as the 16m1).
author Bob Cook <bob@bobcookdev.com>
date Sat, 22 Mar 2014 09:51:26 -0700
parents e283b09c8a17
children ab1ed6470357
files main/packages/avr/device/adc.cpp main/packages/avr/device/hwdefs.h main/packages/avr/device/int_helpers.cpp main/packages/avr/device/simavr_helpers.inl main/packages/avr/device/uart.cpp
diffstat 5 files changed, 112 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/main/packages/avr/device/adc.cpp	Sat Mar 22 09:50:54 2014 -0700
+++ b/main/packages/avr/device/adc.cpp	Sat Mar 22 09:51:26 2014 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides a basic Analog to Digitial Conversion (ADC) library.
 //
-//  Copyright (C) 2007 Bob Cook
+//  Copyright (C) 2007-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
--- a/main/packages/avr/device/hwdefs.h	Sat Mar 22 09:50:54 2014 -0700
+++ b/main/packages/avr/device/hwdefs.h	Sat Mar 22 09:51:26 2014 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides abstracted definitions for the underlying AVR hardware.
 //
-//  Copyright (C) 2010 Bob Cook
+//  Copyright (C) 2010-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -44,7 +44,8 @@
     && !defined( __AVR_ATmega168__ ) \
     && !defined( __AVR_ATmega328P__ ) \
     && !defined( __AVR_ATmega128__ ) \
-    && !defined( __AVR_ATmega16M1__ )
+    && !defined( __AVR_ATmega16M1__ ) \
+    && !defined( __AVR_ATmega64M1__ )
 #error Unsupported Hardware
 #endif
 
@@ -146,6 +147,16 @@
 #define     HW_FLASH_SIZE               (16 * 1024)
 #define     HW_EEPROM_SIZE              512
 
+#elif defined( __AVR_ATmega64M1__ )
+
+#define     HW_HAS_PORTB
+#define     HW_HAS_PORTC
+#define     HW_HAS_PORTD
+
+#define     HW_RAM_SIZE                 (4 * 1024)
+#define     HW_FLASH_SIZE               (64 * 1024)
+#define     HW_EEPROM_SIZE              (2 * 1024)
+
 #endif
 
 // ----------------------------------------------------------------------------------------
@@ -223,7 +234,7 @@
 #define     HW_SPI_MOSI_PIN             PB2
 #define     HW_SPI_SS_PIN               PB0
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
 #define     HW_HAS_SPI
 
@@ -315,7 +326,7 @@
 #define     HW_UART1_RX_PIN             PD2
 #define     HW_UART1_TX_PIN             PD3
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
 #define     HW_HAS_UART0
 
@@ -392,7 +403,7 @@
 #define     HW_TWI_SDA_PIN              PD1
 #define     HW_TWI_SCL_PIN              PD0
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
 // no TWI h/w for this chip
 
@@ -485,7 +496,7 @@
 
 #define     HW_ADC_REG_ADMUX            ADMUX
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
 #define     HW_HAS_ADC
 // this chip has an odd arrangement of ADC pins; see datasheet
--- a/main/packages/avr/device/int_helpers.cpp	Sat Mar 22 09:50:54 2014 -0700
+++ b/main/packages/avr/device/int_helpers.cpp	Sat Mar 22 09:51:26 2014 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides support routines for dealing with interrupts.
 //
-//  Copyright (C) 2008 Bob Cook
+//  Copyright (C) 2008-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -68,7 +68,7 @@
     TIMSK  = 0;
     ETIMSK = 0;
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
     TIMSK0 = 0;
     TIMSK1 = 0;
--- a/main/packages/avr/device/simavr_helpers.inl	Sat Mar 22 09:50:54 2014 -0700
+++ b/main/packages/avr/device/simavr_helpers.inl	Sat Mar 22 09:51:26 2014 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides support routines for working with the "simavr" simulator.
 //
-//  Copyright (C) 2011 Bob Cook
+//  Copyright (C) 2011-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -50,6 +50,8 @@
 #define SIMAVR_PROCESSOR_NAME "atmega128"
 #elif defined( __AVR_ATmega16M1__ )
 #define SIMAVR_PROCESSOR_NAME "atmega16m1"
+#elif defined( __AVR_ATmega64M1__ )
+#define SIMAVR_PROCESSOR_NAME "atmega64m1"
 #error Unsupported Hardware
 #endif
 
--- a/main/packages/avr/device/uart.cpp	Sat Mar 22 09:50:54 2014 -0700
+++ b/main/packages/avr/device/uart.cpp	Sat Mar 22 09:51:26 2014 -0700
@@ -7,7 +7,7 @@
 //    
 //  This file provides the implementation for the UART library.
 //
-//  Copyright (C) 2010 Bob Cook
+//  Copyright (C) 2010-2014 Bob Cook
 //
 //  Permission is hereby granted, free of charge, to any person obtaining a copy
 //  of this software and associated documentation files (the "Software"), to deal
@@ -34,6 +34,7 @@
 #include <avr/interrupt.h>
 
 #include "hwdefs.h"
+#include "int_helpers.h"
 #include "project_defs.h"
 
 #include "packages/common/util/cbuffer.h"
@@ -101,14 +102,11 @@
     && !defined( __AVR_ATmega168__ ) \
     && !defined( __AVR_ATmega328P__ ) \
     && !defined( __AVR_ATmega128__ ) \
-    && !defined( __AVR_ATmega16M1__ )
+    && !defined( __AVR_ATmega16M1__ ) \
+    && !defined( __AVR_ATmega64M1__ )
 #error Unsupported Hardware
 #endif
 
-#if defined( PRJ_UART0_USE_INTERRUPT_MODE ) && defined( __AVR_ATmega16M1__ )
-#error UART0 interrupt mode not supported for ATmega16M1!
-#endif
-
 // ----------------------------------------------------------------------------------------
 
 #if defined( PRJ_UART0_USE_INTERRUPT_MODE ) || defined( PRJ_UART0_USE_POLLED_MODE )
@@ -124,7 +122,7 @@
 
 // ----------------------------------------------------------------------------------------
 
-#if defined( PRJ_UART0_USE_INTERRUPT_MODE )
+#if defined( PRJ_UART0_USE_INTERRUPT_MODE ) && !defined( __AVR_ATmega16M1__ ) && !defined( __AVR_ATmega64M1__ )
 
 #if defined( __AVR_ATmega8__ ) || defined( __AVR_ATmega16__ )
 
@@ -154,6 +152,10 @@
 
     uint8_t data = UDR0;
 
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
+
+    uint8_t data = LINDAT;
+
 #endif
 
     // TODO: error checking in the USRC register, after reading UDR
@@ -174,7 +176,7 @@
 
 // ----------------------------------------------------------------------------------------
 
-#if defined( PRJ_UART0_USE_INTERRUPT_MODE )
+#if defined( PRJ_UART0_USE_INTERRUPT_MODE ) && !defined( __AVR_ATmega16M1__ ) && !defined( __AVR_ATmega64M1__ )
 
 #if defined( __AVR_ATmega8__ ) || defined( __AVR_ATmega16__ )
 
@@ -233,6 +235,43 @@
 
 // ----------------------------------------------------------------------------------------
 
+#if defined( PRJ_UART0_USE_INTERRUPT_MODE ) && ( defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ ) )
+
+ISR( LIN_TC_vect )
+{
+PORTB |= ( 1 << PB2 );
+
+    if ( LINSIR & ( 1 << LRXOK ) )
+    {
+        if ( uart0_rx_buffer.is_full() )
+        {
+            // overflow error
+
+            // TODO
+        }
+        else
+        {
+            uart0_rx_buffer.push( static_cast< uint8_t >( LINDAT ) );
+        }
+    }
+
+    if ( LINSIR & ( 1 << LTXOK ) )
+    {
+        if ( ! uart0_tx_buffer.is_empty() )
+        {
+            LINDAT = uart0_tx_buffer.pop();
+        }
+        else
+        {
+            LINENIR &= ~( 1 << LENTXOK ); // tx buffer empty, disable the interrupt
+        }
+    }
+}
+
+#endif
+
+// ----------------------------------------------------------------------------------------
+
 void uart0_init()
 {
 
@@ -356,7 +395,7 @@
         
     //-------------------------------------------------------------------------------------
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
     // reset the LIN/UART module
 
@@ -374,6 +413,24 @@
 
     LINCR |= ( 1 << LCMD1 ) | ( 1 << LCMD0 );   // tx & rx output enable
 
+    LINENIR = 0
+
+#if defined( PRJ_UART0_USE_INTERRUPT_MODE )
+
+           | ( 0 << LENERR )                    // no error handler interrupts
+           | ( 0 << LENTXOK )                   // no transmit complete interrupts
+           | ( 1 << LENRXOK )                   // enable receive complete interrupts
+           ;
+
+#else // defined( PRJ_UART0_USE_POLLED_MODE )
+
+           | ( 0 << LENERR )                    // no interrupts
+           | ( 0 << LENTXOK )
+           | ( 0 << LENRXOK )
+           ;
+
+#endif
+
 #endif  // #if defined( ...processor selection... )
 
     //-------------------------------------------------------------------------------------
@@ -406,7 +463,7 @@
     UBRR0H = highbyte;  // the caller is required to mask off the top bits
     UBRR0L = lowbyte;
     
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
     // the original computation (for non-M1 devices) uses a divsor of 16 rather than 32,
     // so divide the input value by 2
@@ -441,7 +498,7 @@
 
     return ( UCSR0A & ( 1 << RXC0 ) ) != 0;
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
     return ( LINSIR & ( 1 << LRXOK ) ) != 0;
 
@@ -475,7 +532,7 @@
     while ( ! ( UCSR0A & ( 1 << RXC0 ) ) ) ;
     return UDR0;
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
     while ( ! ( LINSIR & ( 1 << LRXOK ) ) ) ;
     return LINDAT;
@@ -506,7 +563,7 @@
 void uart0_write( uint8_t data )
 {
 
-#if defined( PRJ_UART0_USE_INTERRUPT_MODE )
+#if defined( PRJ_UART0_USE_INTERRUPT_MODE ) && !defined( __AVR_ATmega16M1__ ) && !defined( __AVR_ATmega64M1__ )
 
     //--    Wait for space in the buffer.
 
@@ -525,7 +582,23 @@
 
     UCSR0B |= ( 1 << UDRIE0 );
 
-#endif
+#endif // non-16M1 transmission
+
+#elif defined( PRJ_UART0_USE_INTERRUPT_MODE ) && ( defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ ) )
+
+    //--    If transmission is already in progress, all we need to do is add the
+    //      new data to the TX buffer. Otherwise we have to write the data directly.
+
+    if ( LINSIR & ( ( 1 << LBUSY ) | ( 1 << LTXOK ) ) )
+    {
+        uart0_tx_buffer.wait_and_push( data );
+    }
+    else
+    {
+        LINENIR |= ( 1 << LENTXOK );
+        while ( ( LINSIR & ( 1 << LBUSY ) ) ) ;
+        LINDAT = data;
+    }
 
 #else   // defined( PRJ_UART0_USE_POLLED_MODE )
 
@@ -542,11 +615,11 @@
     while ( ! ( UCSR0A & ( 1 << UDRE0 ) ) ) ;
     UDR0 = data;
 
-#elif defined( __AVR_ATmega16M1__ )
+#elif defined( __AVR_ATmega16M1__ ) || defined( __AVR_ATmega64M1__ )
 
     while ( ( LINSIR & ( 1 << LBUSY ) ) ) ;
-    //while ( ! ( LINSIR & ( 1 << LTXOK ) ) ) ;
     LINDAT = data;
+    //while ( LINSIR & ( 1 << LTXOK ) ) ;
 
 #endif