BV513 Power Off
There is a system fitted to the BV523 whereby the power can be completely shut off. This means that the processor will consume zero power. The ability to switch itself off is useful in its own right but what makes it into a great feature is that it is linked to the RTC (M41T81 chip alarm feature so that it is possible to say switch on one a month to do some data logging.
The alarm is connected to RG9 which in turn is connected to the power off circuit. If RG9 is an input (high impedance) then the power off will be activated and no power will get to the board. This is the default situation. At power up, the boot loader will normally set RG9 to be an output and hold this line low, thus enabling power to the board.
At reset the boot loader will check 2 bytes of memory for a particular address, if they are set then the boot loader will not hold RG9 low. This is the action of 'poff' in rtc_alarm.bas. This is important because in the absence of this the, board will briefly reset and the boot loader will then hold RG9 low negating the action of power off. When the alarm is triggered it hold RG9 low via the OUT pin on the M41T81. This will remain low until cleared, the poff function does this before turning the power off.
The following code has the poff() function and also some alarm functions.
http://byvac.com/mBlib/flb/Tutorial/PIC32MX3_Family/90_Device/BV523/Power_off/rtc_alarm.bas
// Real time clock Alarm for the BV523. This has a RTC chip on board // that uses I2C. // The chip is a MT41T81 and is bit banged on RE5(SCL) and RE6(SDA) The // alarm output OUT is connected to RG9 // because this is part of theBV523 sytem there are two functions that will // give access to the bb rtc, these are: // value=rtcget(address) // rtcset(address,value) #option first on #include "http://byvac.com/mBlib/flb/Library/GPIO/gpio_reg.bas" #option first off constant POWER_MARKER 0xa0003000 // an agreed point somewhere in ram apploader 2-2 constant RG9 1 << 9 // ***************************************************************************** // bcd conversions needed for rtc // ***************************************************************************** function dec2bcd(dec) return ((dec/10) << 4) + (dec % 10) endf function bcd2dec(bcd) return ((bcd >> 4) * 10) + bcd % 16 endf // ***************************************************************************** // power off BV523 // The boot loader is keeping the BV523 on by holding RG9 low. It does this // because the power marker does not have 0x534a in that location. This sets // that bit of ram to 534a and then sets RG9 to an input. // 0x534a will stop the boot loader form pulling RG9 low and switching on the // device. Of course this will disapear when the power is off so if the alarm // pulls RG9 low it will come on as normal. // ***************************************************************************** function poff() rtcget(0x0f) // clear any previous alarms - important pokec(POWER_MARKER,0x53) pokec(POWER_MARKER+1,0xa4) poke(LATG+SET,RG9) poke(TRISG+SET,RG9) endf // ***************************************************************************** // returns alarm as a string // dom/month h:m:s // ***************************************************************************** function rtc_getAlarm$() dim rv$ rv$ = bcd2dec(rtcget(0x0b) & 0x3f) // dom rv$ = rv$ + "/"+ bcd2dec(rtcget(0x0a) & 0x1f) // month rv$ = rv$ + " "+ bcd2dec(rtcget(0x0c) & 0x3f) // hour rv$ = rv$ + ":"+ bcd2dec(rtcget(0x0d) & 0x7f) // min rv$ = rv$ + ":"+ bcd2dec(rtcget(0x0e) & 0x7f) // sec return rv$ endf // ***************************************************************************** // sets the alarm // ***************************************************************************** function rtc_setAlarm(dom,month,h,m,s) dim tmp rtcset(0x0b,dec2bcd(dom)) // dom // tmp is to preserve shared register bits tmp = rtcget(0x0a) & 0xe0 tmp = tmp | (month & 0x1f) rtcset(0x0a,dec2bcd(month)) tmp = rtcget(0x0c) & 0x40 tmp = tmp | (h & 0x3f) rtcset(0x0c,dec2bcd(h)) rtcset(0x0d,dec2bcd(m)) rtcset(0x0e,dec2bcd(s)) endf // ***************************************************************************** // turn on or off alarm // ***************************************************************************** function rtc_Alarm(onn) dim tmp if onn = 1 then tmp = rtcget(0x0a) tmp = tmp | 0xa0 // AFE+ABE tmp = tmp & 0xbf // SQWE rtcset(0x0a,tmp) else tmp = rtcget(0x0a) tmp = tmp & 0x1f //AFE+ABE+SQWE all low rtcset(0x0a,tmp) endif endf // ***************************************************************************** // the alarm flags need clearing after the event otherwise the alarm cannot // be triggered. // ***************************************************************************** function rtc_clear() rtcget(0x0f) endf // ***************************************************************************** // repeat flags // 1=seconds, 2=min, 3=hr, 4=day 5=month (>5)6=year // ***************************************************************************** function rtc_repeat(flag) dim r1,r2,r3,r4 r1 = rtcget(0xb) r2 = rtcget(0xc) r3 = rtcget(0xd) r3 = rtcget(0xe) // all off rtcset(0xb,r1 & 0x3f);rtcset(0xc,r2 & 0x7f) rtcset(0xd,r3 & 0x7f);rtcset(0xe,r4 & 0x7f) select(flag) case(1) rtcset(0xb,r1 | 0xc0) // 4,5 rtcset(0xc,r2 | 0c80) // 3 rtcset(0xd,r3 | 0x80) // 2 rtcset(0xe,r4 | 0x80) // 1 break case(2) rtcset(0xb,r1 | 0xc0) // 4,5 rtcset(0xc,r2 | 0c80) // 3 rtcset(0xd,r3 | 0x80) // 2 break case(3) rtcset(0xb,r1 | 0xc0) // 4,5 rtcset(0xc,r2 | 0c80) // 3 break case(4) rtcset(0xb,r1 | 0xc0) // 4,5 break case(5) rtcset(0xb,r1 | 0xa0) // 4,5 break endselect endf // ***************************************************************************** // usful utility to see all regitesrs of RTC // ***************************************************************************** function rtc_all() dim j for j = 0 to 0x13 print format$("\n Address %02x",j) print format$(" %02x",rtcget(j)) next endf