![]() |
Forum Index : Microcontroller and PC projects : Using internal RTCC on MM-28 chip.
Author | Message | ||||
jwaldha Newbie ![]() Joined: 14/01/2016 Location: HungaryPosts: 10 |
I think the MM is very powerful tool. For practice, I decided to making a battery-operated data logger. Because the data logger operates from battery, must minimize the power consumption between the two measurements. I want to store a measured datas together a timestamp. Unfortunately in the SLEEP mode, the built-in clock is not working. But, the microcontroller contains an RTCC periphery. I think this would solve the exact timing. (I know, it could be used an external RTCC circuit/module, but there is no challenge in that.) The SOSC provide the 32.768KHz clock source for the internal RTCC using a "watch" crystal. This crystal must connect to the chip 11, 12 pins. Unfortunately, the 11, 12 pins already used by of the console connection. This prevents that the uses of internal RTCC. I carefully studied the controller data sheets and documentation of MM, and I think I found a solution. The trick PPS capability of the controller. PPS broadly means that an internal peripheries of MCU has not fixed assignment to a dedicated pin, but also in some peripheries can assign to member of a group of IC pins. (DataSheet 11.3). The console uses the UART1. The UART1 must be to use 2 pins of IC. (transmit & receive). In the case of UART1 transmit, the following PPS assignments are available: IC pin --- MM function --- MM firmware can overwrite 2 --- DIGITAL | ANALOG --- no 7 --- COM1: ENABLE | DIGITAL | ANALOG --- yes 11 --- CONSOLE Tx (DATA OUT) --- yes (reset) 16 --- DIGITAL | 5V | COUNT | WAKEUP | IR --- yes 26 --- ANALOG | DIGITAL | PWM 2A --- yes For the receive: IC pin --- MM function --- MM firmware can overwrite 6 --- PWM 1C | DIGITAL | ANALOG --- yes 9 --- COM2: TRANSMIT | DIGITAL --- no 12 --- CONSOLE Rx (DATA IN) --- yes (reset) 15 --- DIGITAL | 5V | COUNT --- yes 24 --- ANALOG | DIGITAL | PWM 2B --- yes When uses the UART1 transmit and receive other than defaults pins, then freed up the 11,12 pins, which is essential for using the SOSC! I studied Geoff's the source code and revealed that the PPS feature is used in several places in the firmware. Therefore, care must be taken not to use some MM commands after the remapped the UART1 pins, which overwriting it. Otherwise, easy to exclude ourselves from the chip! Potential conflicts: PIN --- dangrous BASIC command 2 none 6 PWM 1,.... 7 OPEN "COM1:....., DE...." 9 none 11 CPU RESTART, WATCHDOG... 12 CPU RESTART, WATCHDOG... 15 SETPIN 16, FIN|PIN|CIN 16 SETPIN 16, FIN|PIN|CIN 24 PWM 2,.... 26 PWM 2,... This does not mean that these pin can not be used only to proceed with caution! The RTCC registers ( and the OSCCON) are protected against overwriting. Only after a special sequence UNLOCK possible to write. The specific tasks: 1. To free up the first 11,12 IC pins. 2. To solve to write the RTCC registers. 3. To write a function to initialize the RTCC. I wrote CFUNTIONS to solve this three steps. The CFUNCTIONs are only the most necessary to solve. eg.: On the BASIC level must produce the correct format of the number, that should be written in the RTC registers. Since the every time when MCU resets the firmware set to the default value of PPS mappings, it is appropriate to place the own PPS mappings in the MM.STARTUP subroutine. So after each reset will return to their own setting. CFunctions: CFunction remapConsoleRX 00000000 8C820000 24030006 1443000B 8C840004 5480000A 24030009 3C02BF81 8C43FA50 24040004 7C831804 AC43FA50 24040001 10000032 00002821 24030009 5443000A 2403000C 54800008 2403000C 3C02BF81 8C43FA50 7C031804 AC43FA50 24040001 10000026 00002821 5443000B 2403000F 54800009 2403000F 3C02BF81 8C43FA50 24040002 7C831804 AC43FA50 24040001 1000001A 00002821 5443000B 24030018 54800009 24030018 3C02BF81 8C43FA50 24040001 7C831804 AC43FA50 24040001 1000000E 00002821 5443000B 00002021 54800009 00002021 3C02BF81 8C43FA50 24040003 7C831804 AC43FA50 24040001 10000002 00002821 00002821 00801021 03E00008 00A01821 End CFunction ' CFunction remapConsoleTX 00000000 8C820000 24030002 1443000B 8C840004 5480000A 24030007 3C02BF81 8C43FB00 24040001 7C831804 AC43FB00 24040001 10000033 00002821 24030007 5443000B 2403000B 54800009 2403000B 3C02BF81 8C43FB38 24040001 7C831804 AC43FB38 24040001 10000026 00002821 5443000B 24030010 54800009 24030010 3C02BF81 8C43FB3C 24040001 7C831804 AC43FB3C 24040001 1000001A 00002821 5443000B 2403001A 54800009 2403001A 3C02BF81 8C43FB48 24040001 7C831804 AC43FB48 24040001 1000000E 00002821 5443000B 00002021 54800009 00002021 3C02BF81 8C43FB68 24040001 7C831804 AC43FB68 24040001 10000002 00002821 00002821 00801021 03E00008 00A01821 End CFunction ' CSub startRTC 00000000 3C03BF81 3C02AA99 24426655 AC62F230 3C025566 344299AA AC62F230 3C02BF81 8C44F000 24050001 7CA40844 AC44F000 3C02BF80 8C440200 7CA418C4 AC440200 340580C8 3C04BF80 AC850200 8C440200 7C0418C4 AC440200 3C023333 24423333 AC62F230 03E00008 00000000 End CSub ' CSub setRTCTime 00000000 3C03BF81 3C02AA99 24426655 AC62F230 3C025566 344299AA AC62F230 3C02BF80 8C450200 24060001 7CC518C4 AC450200 8C850000 3C04BF80 AC850220 8C440200 7C0418C4 AC440200 3C023333 24423333 AC62F230 03E00008 00000000 End CSub ' CSub setRTCDate 00000000 3C03BF81 3C02AA99 24426655 AC62F230 3C025566 344299AA AC62F230 3C02BF80 8C450200 24060001 7CC518C4 AC450200 8C850000 3C04BF80 AC850230 8C440200 7C0418C4 AC440200 3C023333 24423333 AC62F230 03E00008 00000000 End CSub ' CFunction getRTCTime 00000000 3C03BF80 8C620220 8C640220 1444FFFD 00000000 03E00008 00001821 End CFunction ' CFunction getRTCDate 00000000 3C03BF80 8C620230 8C640230 1444FFFD 00000000 03E00008 00001821 End CFunction BASIC interface: Sub init startRTC() End Sub Sub gettime Local integer d, t Local string s$ Local string year$, month$, day$, hour$, minute$, second$ s$ = Hex$(getRTCDate(), 8) year$ = Left$(s$, 2) month$ = Mid$(s$, 3, 2) day$ = Mid$(s$, 5, 2) Date$=day$ + "-" + month$ + "-20" + year$ s$ = Hex$(getRTCTime(), 8) hour$ = Left$(s$, 2) minute$ = Mid$(s$, 3, 2) second$ = Mid$(s$, 5, 2) Time$ = hour$ + ":" + minute$ + ":" + second$ End Sub Sub settime(year%, month%, day%, hour%, minute%, second%) Local string s$ Local integer dtmp, ttmp s$ = Right$(Str$(year%, 4, 0, "0"),2) s$ = s$ + Right$(Str$(month%, 2, 0, "0"), 2) s$ = s$ + Right$(Str$(day%, 2, 0, "0"), 2) dtmp = 0 For i=1 To Len(s$) dtmp = dtmp << 4 dtmp = dtmp + Val(Mid$(s$, i, 1)) Next i dtmp = dtmp << 8 s$ = Right$(Str$(hour%, 2, 0, "0"), 2) s$ = s$ + Right$(Str$(minute%, 2, 0, "0"), 2) s$ = s$ + Right$(Str$(second%, 2, 0, "0"), 2) ttmp = 0 For i=1 To Len(s$) ttmp = ttmp << 4 ttmp = ttmp + Val(Mid$(s, i, 1)) Next i ttmp = ttmp << 8 setRTCTime(ttmp) setRTCDate(dtmp) End Sub Sub mm.startup if remapConsoleTX(7) = 0 then ' Unsuccessfull mapping. Restart MCU watchdog 1 endif if remapConsoleRX(6) = 0 then ' Unsuccessfull mapping. Restart MCU watchdog 1 endif Print "MM started with remapped console." Print " ConsoleRx - 6" Print " ConsoleTx - 7" End Sub BASIC example: MM started with remapped console: RX -> pin 6 TX -> pin 7 > init > settime 2016,3,30,17,56,25 > gettime : ? date$, time$ 30-03-2016 17:56:34 > ? time$ : cpu sleep 3 : ? time$ : gettime : ? time$ 17:56:55 17:56:55 17:56:58 > C source code: #define _SUPPRESS_PLIB_WARNING #include <plib.h> #include "CFunctions.h" /* U1TX: 2 RPA0 PPSOutput(1, RPA0, U1TX); DIGITAL | ANALOG 7 RPB3 PPSOutput(1, RPB3, U1TX); COM1: ENABLE | DIGITAL | ANALOG 11 RPB4 PPSOutput(1, RPB4, U1TX); CONSOLE Tx (DATA OUT) 16 RPB7 PPSOutput(1, RPB7, U1TX); DIGITAL | 5V | COUNT | WAKEUP | IR 26 RPB15 PPSOutput(1, RPB15, U1TX); ANALOG | DIGITAL | PWM 2A U1RX: 6 RPB2 PPSInput(3, U1RX, RPB2); PWM 1C | DIGITAL | ANALOG 9 RPA2 PPSInput(3, U1RX, RPA2); COM2: TRANSMIT | DIGITAL 12 RPA4 PPSInput(3, U1RX, RPA4); CONSOLE Rx (DATA IN) 15 RPB6 PPSInput(3, U1RX, RPB6); DIGITAL | 5V | COUNT 24 RPB13 PPSInput(3, U1RX, RPB13); ANALOG | DIGITAL | PWM 2B */ long long remapConsoleRX(long long *pin) { if (*pin == 6) { PPSInput(3, U1RX, RPB2); // PWM 1C | DIGITAL | ANALOG // interfere with PWM 1,.... return 1; } if (*pin == 9) { PPSInput(3, U1RX, RPA2); // COM2: TRANSMIT | DIGITAL return 1; } if (*pin == 12) { PPSInput(3, U1RX, RPA4); // CONSOLE Rx (DATA IN) // The default Console pin return 1; } if (*pin == 15) { PPSInput(3, U1RX, RPB6); // DIGITAL | 5V | COUNT // interfere with SETPIN 16, FIN|PIN|CIN return 1; } if (*pin == 24) { PPSInput(3, U1RX, RPB13); // ANALOG | DIGITAL | PWM 2B // interfere with PWM 2,.... return 1; } return 0; } long long remapConsoleTX(long long *pin) { if (*pin == 2) { PPSOutput(1, RPA0, U1TX); // DIGITAL | ANALOG return 1; } if (*pin == 7) { PPSOutput(1, RPB3, U1TX); // COM1: ENABLE | DIGITAL | ANALOG // interfere with OPEN "COM1:....., DE...." return 1; } if (*pin == 11) { PPSOutput(1, RPB4, U1TX); // CONSOLE Tx (DATA OUT) // The default Console pin. return 1; } if (*pin == 16) { PPSOutput(1, RPB7, U1TX); // DIGITAL | 5V | COUNT | WAKEUP | IR // interfere with SETPIN 16, FIN|PIN|CIN return 1; } if (*pin == 26) { PPSOutput(1, RPB15, U1TX); // ANALOG | DIGITAL | PWM 2A // interfere with PWM 2,... return 1; } return 0; } void startRTC(void) { SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; OSCCONbits.SOSCEN = 1; // Start SOSC RTCCONbits.RTCWREN = 1; // Enable RTC registers write RTCCON = 0x80C8; RTCCONbits.RTCWREN = 0; // Disable RTC registers write SYSKEY = 0x33333333; } void setRTCTime(long long *param) { SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; RTCCONbits.RTCWREN = 1; RTCTIME = *param; RTCCONbits.RTCWREN = 0; SYSKEY = 0x33333333; } void setRTCDate(long long *param) { SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; RTCCONbits.RTCWREN = 1; RTCDATE = *param; RTCCONbits.RTCWREN = 0; SYSKEY = 0x33333333; } long long getRTCTime(void) { unsigned int t1, t2; do { t1 = RTCTIME; t2 = RTCTIME; } while (t1 != t2); return t1; } long long getRTCDate(void) { unsigned int d1, d2; do { d1 = RTCDATE; d2 = RTCDATE; } while (d1 != d2); return d1; } void main(void) {} Ps.: I apologize for any errors in the language! --- JWaldha |
||||
drkl![]() Senior Member ![]() Joined: 18/10/2015 Location: HungaryPosts: 102 |
Hello János, Congratulate, good works. I'll test it... drkl |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3281 |
Wow, that is an amazingly complete solution. Welcome to the forum and what a debut!! I considered using the internal PIC32 RTC in MMBasic but I figured that it was simpler for most people to use an external RTC. However, it would be nice for users to still have the option of using the internal RTC and this does exactly that. Congratulations. You have obviously mastered CFunctions which is not easy... congratulations again. Geoff Geoff Graham - http://geoffg.net |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |