OSDN Git Service

[Schematic] Add another type: Using plain AKC6955.
[openi2cradio/OpenI2CRadio.git] / main.c
diff --git a/main.c b/main.c
index 5397bd0..f1c2ab6 100644 (file)
--- a/main.c
+++ b/main.c
 /*
  * OpenI2CRADIO
  * Config & Main routine.
- * (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
- * License: GPL2
+ * Copyright (C) 2013-06-10 K.Ohta <whatisthis.sowhat ai gmail.com>
+ * License: GPL2+LE
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2,
+ *  or (at your option) any later version.
+ *  This library / program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *  See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this library; see the file COPYING. If not, write to the
+ *  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ *
+ *  As a special exception, if you link this(includeed from sdcc) library
+ *  with other files, some of which are compiled with SDCC,
+ *  to produce an executable, this library does not by itself cause
+ *  the resulting executable to be covered by the GNU General Public License.
+ *  This exception does not however invalidate any other reasons why
+ *  the executable file might be covered by the GNU General Public License.
  */
 
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+
+#if defined(__SDCC)
 #include <sdcc-lib.h>
 #include <pic18fregs.h> /* ONLY FOR PIC18x */
+#include <delay.h>
+#else
+#include <xc.h>
+#endif
+
+#include <signal.h>
 
 #include "iodef.h"
+#include "idle.h"
+#include "i2c_io.h"
+#include "akc6955.h"
+#include "lcd_acm1602.h"
+#include "ui.h"
+#include "eeprom.h"
+#include "ioports.h"
+#include "menu.h"
+#include "power.h"
+#include "adc_int.h"
+#include "i2c_eeprom.h"
+#include "backlight.h"
+#include "rencoder.h"
+#include "euart.h"
+#include "uart_termio.h"
+#include "shell_strutl.h"
+#include "term_shell.h"
 
 /*
  * Config words.
  */
-__at(__CONFIG1H) _config1h = _FOSC_INTIO67_1H;
-__at(__CONFIG2L) _config2l = _BORV_190_2L & _BOREN_ON_2L & _PWRTEN_ON_2L;
-__at(__CONFIG2H) _config2h = _WDTEN_ON_2H & _WDTPS_32768_2H;
-__at(__CONFIG3H) _config3h = _PBADEN_OFF_3H & _MCLRE_EXTMCLR_3H;
-__at(__CONFIG4L) _config4l = _STVREN_ON_4L & _LVP_OFF_4L & _XINST_ON_4L & _DEBUG_ON_4L;
-__at(__CONFIG5L) _config5l = _CP0_OFF_5L & _CP1_OFF_5L;
-__at(__CONFIG5H) _config5h = _CPB_OFF_5H & _CPD_OFF_5H;
-__at(__CONFIG6L) _config6l = _WRT0_OFF_6L & _WRT1_OFF_6L;
-__at(__CONFIG6H) _config6h = _WRTD_OFF_6H & _WRTB_OFF_6H & _WRTC_OFF_6H;
-__at(__CONFIG7L) _config7l = _EBTR0_OFF_7L & _EBTR1_OFF_7L;
-__at(__CONFIG7H) _config7h = _EBTRB_OFF_7H;
+#if defined(pic18f23k22) || defined(pic18f24k22) || defined(pic18f25k22) || defined(pic18f26k22)
+//#pragma stack 0x200 256 // Set stack size to 256bytes.
+#pragma config FOSC=INTIO67,BORV=190,BOREN=ON,PWRTEN=ON
+#pragma config WDTEN=ON,WDTPS=32768
+#pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF,DEBUG=ON,XINST=ON
+//#pragma config PBADEN=OFF,MCLRE=EXTMCLR,STVREN=ON,LVP=OFF//,XINST=ON
+#pragma config CP0=OFF,CP1=OFF,CPB=OFF,CPD=OFF
+#pragma config WRT0=OFF,WRT1=OFF,WRTB=OFF,WRTC=OFF,WRTD=OFF
+#pragma config EBTR0=OFF,EBTR1=OFF,EBTRB=OFF
+#endif
+// For 4xK20 or 2xK20 Series
+#if defined(pic18f43k20) || defined(pic18f44k20) || defined(pic18f45k20) || defined(pic18f46k20) || \
+    defined(pic18f23k20) || defined(pic18f24k20) || defined(pic18f25k20) || defined(pic18f26k20) || \
+    defined(_18F43K20)  || defined(_18F44K20)  || defined(_18F45K20)  || defined(_18F46K20)  || \
+    defined(_18F23K20)  || defined(_18F24K20)  || defined(_18F25K20)  || defined(_18F26K20) 
+
+#ifdef __SDCC
+#pragma stack 0x200 256
+#endif
 
+#pragma config FOSC=HS,FCMEN=ON,PWRT=ON,BOREN=NOSLP,BORV=27, \
+               WDTEN=ON,WDTPS=32768,PBADEN=OFF,HFOFST=OFF,LPT1OSC=OFF, \
+               MCLRE=ON,STVREN=ON,DEBUG=ON,LVP=OFF, \
+               XINST=OFF
+#endif
+
+
+/*
+ * Statuses
+  */
+unsigned char stereoflag;
+unsigned char tuneflag;
+unsigned char cnrlevel;
+int diffstat;
+unsigned int batlevel_6955;
+unsigned int battlevel;
+unsigned char ui_idlekey;
+unsigned char ui_idlepad;
 
+int recv_signal;
+unsigned char pollkeybuf[33];
+
+//#define _LCD_DEBUG 1
+#ifdef __XC
+void TMR0_handler(void)
+#else
+SIGHANDLER(TMR0_handler)
+#endif
+{
+
+   // Stop timer0
+   T0CONbits.TMR0ON = 0;
+
+   // Clear interrupt flag
+//   INTCONbits.TMR0IF = 0;
+   INTCONbits.TMR0IE = 0;;
+
+   return;
+}
 /*
- * 
+ * Interrupt wake up every 1ms.
  */
-int main(void) {
+#ifdef __XC
+void TMR1_Handler(void)
+#else
+SIGHANDLER(TMR1_Handler)
+#endif
+{
+//    rencoder_count();
+        rencoder_tmrhook();
+}
+
+#ifdef __XC
+void TMR3_Handler(void)
+#else
+SIGHANDLER(TMR3_Handler)
+#endif
+{
+   PIR2bits.TMR3IF = 0;
+   PIE2bits.TMR3IE = 0;
+   IPR2bits.TMR3IP = 0;
+}
+
+#ifdef __XC
+void EXINT_Handler(void)
+#else
+SIGHANDLER(EXINT_Handler)
+#endif
+{
+    INTCONbits.INT0IE = 0;
+    INTCONbits.INT0IF = 0;
+    INTCON3bits.INT1IF = 0;
+    INTCON3bits.INT2IF = 0;
+    INTCON3bits.INT1IE = 0;
+    INTCON3bits.INT2IE = 0;
+
+}
+#ifdef __XC
+void RBIF_handler(void)
+#else
+SIGHANDLER(RBIF_handler)
+#endif
+{
+    if(IOCBbits.IOCB4 != 0) {
+        power_on_inthook();
+    } else {
+        rencoder_inthook();
+    }
+}
+#ifdef __XC
+void  EEPROM_handler(void)
+#else
+SIGHANDLER(EEPROM_handler)
+#endif
+{
+    PIR2bits.EEIF = 0;
+    EECON1bits.WREN = 0;
+//    if(chk_powerbutton(0, 0) != 0) { // If pressed on
+//      power_off(1); //
+//    }
+}
 
+#ifdef __XC
+void INADC_handler(void)
+#else
+SIGHANDLER(INADC_handler)
+#endif
+{
+//    unsigned int a;
+//    a = polladc();
+//    if(a != 0xffff) {
+//        battlevel = adc_rawtobatt(a);
+//    }
+    PIR1bits.ADIF = 0;
+}
+#ifdef __XC
+void I2C_handler(void)
+#else
+SIGHANDLER(I2C_handler)
+#endif
+{
+    PIR1bits.SSPIF = 0;
+}
+#ifdef __XC
+void I2CBus_handler(void)
+#else
+SIGHANDLER(I2CBus_handler)
+#endif
+{
+    PIR2bits.BCLIF = 0;
+}
+
+#ifdef __XC
+void UART_R_Handler(void)
+#else
+SIGHANDLER(UART_R_Handler)
+#endif
+{
+    uart_inthdr_rx();
+}
+
+
+#ifdef __SDCC
+DEF_INTLOW(intlow_handler)
+  DEF_HANDLER(SIG_TMR0, TMR0_handler)
+  DEF_HANDLER(SIG_INT0, EXINT_Handler)
+//  DEF_HANDLER(SIG_TMR3, TMR3_Handler)
+END_DEF
+
+DEF_INTHIGH(inthigh_handler)
+ DEF_HANDLER(SIG_RBIF, RBIF_handler)
+ DEF_HANDLER(SIG_RCIF, UART_R_handler)
+// DEF_HANDLER(SIG_TMR1, TMR1_Handler)
+// DEF_HANDLER(SIG_INT1, EXINT_Handler)
+ DEF_HANDLER(SIG_INT2, EXINT_Handler)
+ DEF_HANDLER(SIG_AD, INADC_handler)
+  //DEF_HANDLER(SIG_SSP, I2C_handler)
+  //DEF_HANDLER(SIG_BCOL, I2CBus_handler)
+END_DEF
+#else
+void interrupt low_priority intlow_handler(void)
+{
+    if(INTCONbits.TMR0IF) TMR0_handler();
+    if(INTCONbits.INT0IF) EXINT_Handler();
+//    if(PIR1bits.TMR1IF) TMR1_Handler();
+}
+
+void interrupt high_priority inthigh_handler(void)
+{
+    if(INTCONbits.RBIF) RBIF_handler();
+    if(PIR1bits.TMR1IF) TMR1_Handler();
+    if(PIR1bits.RC1IF)   UART_R_Handler();
+//    if(PIR2bits.TMR3IF) TMR3_Handler();
+//    if(INTCON3bits.INT1IF) EXINT_Handler();
+//    if(INTCON3bits.INT2IF) EXINT_Handler();
+    if(PIR1bits.ADIF) INADC_handler();
+
+//    if(PIR1bits.SSPIF)    I2C_handler();
+}
+
+#ifdef __XC
+
+
+#endif
+#endif
+
+
+void lowbatt(void)
+{
+//    _CLS();
+//    idle_time_ms(100);
+    printhelp_2lines("Low battery X)", "Press key to suspend");
+    shutdown(1);
+}
+
+
+int main(void)
+{
+    unsigned char c;
+    unsigned char pbutton;
+    unsigned char reset_status;
+    unsigned char p;
+    unsigned char lvcount = 0;
+    unsigned char dispf = 0xff;
+    unsigned char i;
+    unsigned int step;
+
+    OSCCON =  (0x80 & 0b11111100) | 0b00111000;
+//    OSCCON =  (0x80 & 0b11111100) | 0b00110010; // 8MHz 
+    idle_init();
     keyin_init();
     keyin_ioinit();
-    
+    i2c1_init();
+    reset_status = chk_reset();
+    idle_time_ms(300); // Wait for setup.
+    WDTCONbits.SWDTEN = 0; // WDT OFF.
+    switch(reset_status){
+        case RESET_MCLR:
+        case RESET_BOR:
+            shutdown(0); // Save and halt on BOR.
+            break;
+        case RESET_SOFTWARE: //
+            RCONbits.RI = 0;
+           pbutton = chk_powerbutton();
+            if(pbutton == 0) shutdown(0); // Not-Pressed power-button -> shutdown( not save).
+            break;
+        case RESET_POR:
+        case RESET_WDT:  // Workaround random reset.
+ //           shutdown(0);
+            break;
+        default:
+            break;
+    }
+    WDTCONbits.SWDTEN = 1; // WDT ON.
+    power_on(1);
+    //intadc_init();
+    valinit();
+    acm1602_init(LCD_I2CADDR, 1); //Init LCD
+    lcd_setbacklight(0xff, 255);
+    /* Check EEPROM */
+    check_eeprom();
+  /* Push default parameters to AKC6955*/
+    setup_akc6955();
+    _CLS();
+    uart_init();
+    //_LOCATE(0,0);
+    _PUTCHAR(' ');
+    update_status();
+    update_display();
+    ClrWdt();
+   ui_idlekey = setup.ui_idlecount / 92;
+   ui_idlepad = setup.ui_idlecount % 23;
+   rencoder_init();
+   rencoder_start();
+   do {
+
+        if(battlevel < 340) { // 3.4V
+                lvcount++;
+                if(lvcount > 4) {
+                    if(dispf == 0) {
+                        acm1602_resume(LCD_I2CADDR);
+                        dispf = 0xff;
+                     }
+                    lowbatt(); //Zap 4Times on LowVoltage.
+                }
+            } else {
+                lvcount = 0;
+            }
+        /* Main routine*/
 
+        term_shell(0); // Steel Shell
+       for(i = 0; i < 4; i++) {
+           c = pollkey_single_timeout(ui_idlekey, 1); // 23*41 = 943ms
+           p = 0;
+            if(c != charcode_null) {
+                ClrWdt();
+                if(dispf == 0) {
+                    acm1602_resume(LCD_I2CADDR);
+                    dispf = 0xff;
+                }
+               setfreq_updown(c);
+               update_status();
+                update_display();
+               rencoder_start();
+            }
+            ClrWdt();
+        }
+         dispf = setfreq_renc_updown(dispf);
+         update_status();
+         dispf = backlight_dec(dispf); 
+         if(dispf != 0)  update_display();
+         if(ui_idlepad != 0) idle_time_ms(ui_idlepad);
+         ClrWdt();
+    } while(1);
 }