Add lss file for cpp_obj program
[avr_serial_lcd.git] / serial_lcd.c
index 1235c7ba0c527653ba7284c3a149a9c977940bd5..bef0e8c463f004adf5e54eed0adaaca9be901741 100644 (file)
 #include "serial_lcd.h"\r
 \r
 #if defined(__GNUC__)\r
-FUSES = {\r
-  .low = SUT1, \r
-  .high = (unsigned char) (DWEN & WDTON & RSTDISBL & BODLEVEL1 & BODLEVEL2),\r
-  .extended = EFUSE_DEFAULT,\r
-};\r
+//FUSES = {\r
+// .low = SUT1,\r
+    //  .high = (unsigned char) (DWEN & WDTON & RSTDISBL & BODLEVEL1 & BODLEVEL2),\r
+    //  .extended = EFUSE_DEFAULT,\r
+    //};\r
 #endif\r
-  \r
+\r
 // Number of PWM brightness levels supported\r
 #define LED_BRIGHTNESS_LEVELS 8\r
 \r
@@ -40,20 +40,20 @@ FUSES = {
 #define        LCD_ON  0x0C\r
 // Clear display command\r
 #define LCD_CLR 0x01\r
-// Set 4 data bits \r
-#define LCD_4_Bit 0x20 \r
-// Set 8 data bits \r
-#define LCD_8_Bit 0x30 \r
-// Set number of lines \r
-#define LCD_4_Line 0x08 \r
+// Set 4 data bits\r
+#define LCD_4_Bit 0x20\r
+// Set 8 data bits\r
+#define LCD_8_Bit 0x30\r
+// Set number of lines\r
+#define LCD_4_Line 0x08\r
 // Set 8 data bits\r
 #define        DATA_8  0x30\r
-// Set character font \r
-#define LCD_Font 0x04 \r
-// Turn the cursor on \r
-#define LCD_CURSOR_ON 0x02 \r
-// Turn on cursor blink \r
-#define LCD_CURSOR_BLINK 0x01 \r
+// Set character font\r
+#define LCD_Font 0x04\r
+// Turn the cursor on\r
+#define LCD_CURSOR_ON 0x02\r
+// Turn on cursor blink\r
+#define LCD_CURSOR_BLINK 0x01\r
 \r
 ////// Serial command codes ///////\r
 // ASCII control code to set brightness level\r
@@ -94,11 +94,6 @@ static FLASH_DECLARE(const unsigned char ledPwmPatterns[]) =
 #pragma global_register ledPwmCount:20 sUartRxHead:21 sUartRxTail:22 ledPwmCycling:23\r
 unsigned char ledPwmCount, sUartRxHead, sUartRxTail, ledPwmCycling;\r
 \r
-#elif defined(__CODEVISIONAVR__)\r
-#pragma regalloc-\r
-register unsigned char ledPwmCount, sUartRxHead, sUartRxTail, ledPwmCycling;\r
-#pragma regalloc+\r
-\r
 // Use avr_compat register variables\r
 #else\r
 REGISTER_VAR(unsigned char ledPwmCount, "r4", 15);\r
@@ -110,12 +105,12 @@ REGISTER_VAR(unsigned char ledPwmCycling, "r7", 12);
 #define ledPwmPattern GPIOR0\r
 #if defined(REGISTER_BIT)\r
 #define BIT_led_on REGISTER_BIT(GPIOR1,0)\r
-#define BACKLIGHT_STATUS() BIT_led_on\r
+#define IS_BACKLIGHT_ON() BIT_led_on\r
 #define BACKLIGHT_OFF() BIT_led_on = 0\r
 #define BACKLIGHT_ON() BIT_led_on = 1\r
 #else\r
-#define BACKLIGHT_STATUS() (GPIOR1 & 0x01)\r
-#define BACKLIGHT_OFF() GPIOR1 &=~ ~0x01\r
+#define IS_BACKLIGHT_ON() (GPIOR1 & 0x01)\r
+#define BACKLIGHT_OFF() GPIOR1 &= ~0x01\r
 #define BACKLIGHT_ON() GPIOR1 |= 0x01\r
 #endif\r
 \r
@@ -164,7 +159,7 @@ static inline void LedPwmSetBrightness (unsigned char brightness) {
   unsigned char ledPwmPos;\r
 \r
   if (brightness == 0) { // turn backlight off for 0 brightness\r
-    if (BACKLIGHT_STATUS()) {\r
+    if (IS_BACKLIGHT_ON()) {\r
       LedTimerStop();\r
       ledPwmPattern = 0;\r
       ledPwmCycling = 0;\r
@@ -183,12 +178,12 @@ static inline void LedPwmSetBrightness (unsigned char brightness) {
   ledPwmCycling = ledPwmPattern;\r
   if (ledPwmPos >= LED_BRIGHTNESS_LEVELS-1) { // maximum brightness\r
     // don't need PWM for continuously on\r
-    if (BACKLIGHT_STATUS()) {\r
+    if (IS_BACKLIGHT_ON()) {\r
       LedTimerStop();\r
       LED_PORT |= (1<<LED_PIN);\r
     }\r
   } else {\r
-    if (BACKLIGHT_STATUS()) {\r
+    if (IS_BACKLIGHT_ON()) {\r
       LedTimerStart();\r
     }\r
   }\r
@@ -263,17 +258,13 @@ static inline void UsartInit(void) {
 #endif\r
 }\r
 \r
-#if defined(__IMAGECRAFT__) || defined(__CODEVISIONAVR__)\r
+#if defined(__IMAGECRAFT__)\r
 // Clock cycle = 67nS @ 14.7456MHz\r
 // Delay resolution ~ 1uS @ 14.7456MHz\r
 // So this function is only accurate at near above frequency\r
 void _delay_us (unsigned int d) {\r
   while (d-- != 0);\r
-#if defined(__IMAGECRAFT__)\r
   asm("nop");\r
-#elif defined(__CODEVISIONAVR__)\r
-  #asm("nop")\r
-#endif\r
 }\r
 #endif\r
 \r
@@ -312,13 +303,15 @@ static inline void LcdInit (void) {
 MAIN_FUNC() {\r
   MCUSR = 0; // clear all reset flags\r
 \r
+  wdt_reset();\r
 #if defined(__CODEVISIONAVR__)\r
-      #asm("wdr");\r
-#else\r
-      wdt_reset();\r
+#pragma optsize-\r
 #endif\r
   WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)\r
   WDTCSR = (1<<WDE)|(1<<WDP3)|(1<<WDP0); // 1024K cycles, 8.0sec\r
+#if defined(__CODEVISIONAVR__) && defined(_OPTIMIZE_SIZE_)\r
+#pragma optsize+\r
+#endif\r
   MCUCR &= ~((1<<SM1)|(1<<SM0)); // use idle sleep mode\r
 \r
   LedPwmInit ();\r
@@ -327,11 +320,7 @@ MAIN_FUNC() {
   // Initialize the AVR USART\r
   UsartInit ();\r
 \r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("sei");\r
-#else\r
   sei();\r
-#endif\r
   while (1) {\r
     unsigned char tail = sUartRxTail; // explicitly set order of volatile access\r
     if (tail != sUartRxHead) { // Check if UART RX buffer has a character\r
@@ -354,50 +343,38 @@ MAIN_FUNC() {
     } else {\r
       // No characters waiting in RX buffer\r
 \r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("cli");\r
-#else\r
       cli();\r
-#endif\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("wdr");\r
-#else\r
       wdt_reset();\r
-#endif\r
       MCUSR &= ~(1<<WDRF); // clear any watchdog interrupt flags\r
+\r
+#if defined(__CODEVISIONAVR__)\r
+#pragma optsize-\r
+#endif\r
       WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)\r
       WDTCSR &= ~(1<<WDE); // watchdog timer off\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("sei");\r
-#else\r
-      sei();\r
+#if defined(__CODEVISIONAVR__) && defined(_OPTIMIZE_SIZE_)\r
+#pragma optsize+\r
 #endif\r
 \r
+      sei();\r
+\r
       sleep_enable();\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("sleep");\r
-#else\r
       sleep_cpu();\r
-#endif\r
       sleep_disable();\r
 \r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("cli");\r
-#else\r
       cli();\r
-#endif\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("wdr");\r
-#else\r
       wdt_reset();\r
+\r
+#if defined(__CODEVISIONAVR__)\r
+#pragma optsize-\r
 #endif\r
       WDTCSR |= (1<<WDCE)|(1<<WDE); // start timed sequence (keep old prescaler)\r
       WDTCSR &= ~(1<<WDCE);\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("sei");\r
-#else\r
-      sei();\r
+#if defined(__CODEVISIONAVR__) && defined(_OPTIMIZE_SIZE_)\r
+#pragma optsize+\r
 #endif\r
+\r
+      sei();\r
     }\r
   }\r
   MAIN_FUNC_LAST();\r
@@ -406,36 +383,11 @@ MAIN_FUNC() {
 void LcdWriteCmd (unsigned char Cmd) {\r
   LcdBusyWait();\r
   LCD_DATA_PORT = Cmd;  // BusyWait leaves RS low in "Register mode"\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("nop");\r
-#else\r
-   NOP();\r
-#endif\r
+  NOP();\r
   LCD_CONTROL_PORT |= (1<<LCD_E);\r
-#if defined(__CODEVISIONAVR__)\r
-  #if CONSERVATIVE_ENABLE_DURATION\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-  #else\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-  #endif\r
-#else\r
   ENABLE_WAIT();\r
-#endif\r
   LCD_CONTROL_PORT &= ~(1<<LCD_E);\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("nop");\r
-#else\r
-   NOP();\r
-#endif\r
+  NOP();\r
   LCD_CONTROL_PORT |= (1<<LCD_RS); // Set display to "Character mode"\r
 }\r
 \r
@@ -443,30 +395,9 @@ void LcdWriteData (unsigned char c) {
   LcdBusyWait();\r
   LCD_CONTROL_PORT |= (1<<LCD_RS); // Set display to "Character Mode"\r
   LCD_DATA_PORT = c;\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("nop");\r
-#else\r
-   NOP();\r
-#endif\r
+  NOP();\r
   LCD_CONTROL_PORT |= (1<<LCD_E);\r
-#if defined(__CODEVISIONAVR__)\r
-  #if CONSERVATIVE_ENABLE_DURATION\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-  #else\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-  #endif\r
-#else\r
   ENABLE_WAIT();\r
-#endif\r
   LCD_CONTROL_PORT &= ~(1<<LCD_E);\r
 }\r
 \r
@@ -475,36 +406,11 @@ unsigned char LcdBusyWait (void) {
   LCD_DATA_DIR = 0x00; // Set LCD data port to inputs\r
   LCD_CONTROL_PORT &= ~(1<<LCD_RS); // Set display to "Register mode"\r
   LCD_CONTROL_PORT |= (1<<LCD_RW); // Put the display in the read mode\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("nop");\r
-#else\r
-   NOP();\r
-#endif\r
+  NOP();\r
   do {\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("wdr");\r
-#else\r
-      wdt_reset();\r
-#endif\r
+    wdt_reset();\r
     LCD_CONTROL_PORT |= (1<<LCD_E);\r
-#if defined(__CODEVISIONAVR__)\r
-  #if CONSERVATIVE_ENABLE_DURATION\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-  #else\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-    #asm("nop")\r
-  #endif\r
-#else\r
-  ENABLE_WAIT();\r
-#endif\r
+    ENABLE_WAIT();\r
     LCDStatus = LCD_DATA_PIN_REG;\r
     LCD_CONTROL_PORT &= ~(1<<LCD_E);\r
   } while (LCDStatus & (1<<LCD_BUSY));\r
@@ -513,16 +419,24 @@ unsigned char LcdBusyWait (void) {
   return (LCDStatus);\r
 }\r
 \r
-#if defined(__IMAGECRAFT__)\r
-#pragma interrupt_handler usart_rx_handler:iv_USART0_RXC\r
-void usart_rx_handler(void)\r
-#else\r
-ISR(USART_RX_vect)\r
+INLINE_FUNC_DECLARE(static void UartStoreRx (uint8_t rx));\r
+static inline void UartStoreRx (uint8_t rx) {\r
+  unsigned char tmphead;\r
+\r
+  if (UCSRA & (1<<FE)) {\r
+    // framing error. Currrently, this is silently ignored\r
+    // real applications may wish to output information to LCD to indicate\r
+    // erroroneous byte received\r
+    return;\r
+  }\r
+#ifdef HANDLE_DATA_OVER_RUN_ERROR\r
+  if (UCSRA & (1<<DOR)) {\r
+    // some applications may benefit from addind error notification for serial port data overruns\r
+  }\r
 #endif\r
-{\r
-  unsigned char rx = UDR;\r
+\r
   // Calculate next buffer position.\r
-  unsigned char tmphead = sUartRxHead;\r
+  tmphead = sUartRxHead;\r
   if (tmphead == UART_RX_BUFFER_SIZE-1)\r
     tmphead = 0;\r
   else\r
@@ -548,27 +462,29 @@ ISR(USART_RX_vect)
 #endif\r
 }\r
 \r
+#if defined(__IMAGECRAFT__)\r
+#pragma interrupt_handler usart_rx_handler:iv_USART0_RXC\r
+void usart_rx_handler(void)\r
+#else\r
+ISR(USART_RX_vect)\r
+#endif\r
+{\r
+  UartStoreRx(UDR);\r
+}\r
+\r
 static unsigned char WaitRxChar (void) {\r
   // waits for next RX character, then return it\r
   unsigned char tail;\r
   do {\r
     tail = sUartRxTail; // explicitly set order of volatile variable access\r
-#if defined(__CODEVISIONAVR__)\r
-      #asm("wdr");\r
-#else\r
-      wdt_reset();\r
-#endif\r
+    wdt_reset();\r
   } while (sUartRxHead == tail); // while buffer is empty\r
 \r
 #if USE_CTS\r
   // turn off interrupts so that if UART char ready to be stored, then storage\r
   // will occur after CTS pin is set active. This allows UART ISR to set\r
-  //  CTS inactive if byte fills buffer after we remove current byte\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("cli");\r
-#else\r
+  // CTS inactive if byte fills buffer after we remove current byte\r
   cli();\r
-#endif\r
 #endif\r
 \r
   // increment tail position\r
@@ -579,11 +495,7 @@ static unsigned char WaitRxChar (void) {
 \r
 #if USE_CTS\r
   CTS_PORT |= (1<<CTS_PIN); // Ensure CTS is active since just removed a byte\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("sei");\r
-#else\r
   sei();   // Allow UART ISR to read character and change potentially change CTS\r
-#endif\r
 #endif\r
 \r
   return sUartRxBuf[sUartRxTail];\r
@@ -592,17 +504,11 @@ static unsigned char WaitRxChar (void) {
 #if defined(__IMAGECRAFT__)\r
 #pragma interrupt_handler timer0_compa_handler:iv_TIMER0_COMPA\r
 void timer0_compa_handler(void)\r
-#elif defined(__CODEVISIONAVR__)\r
-interrupt [TIM0_COMPA] void timer0_compa_handler(void)\r
 #else\r
   ISR(TIMER0_COMPA_vect)\r
 #endif\r
 {\r
-#if defined(__CODEVISIONAVR__)\r
-  #asm("sei");\r
-#else\r
   sei(); // Okay to allow USART interrupts while controlling LED PWM\r
-#endif\r
 \r
   // Set current LED state based on cycling variable\r
   if (ledPwmCycling & 0x01) {\r