program to interface bbc microbit to a MCP79410 RTCC module

Dependencies:   microbit

Fork of microbit-hello-world by micro:bit

This program uses the BBC microbit to display a clock. The program scrolls the time across the microbit 25 led display. The user can set the hours with button A and minutes with button B. The seconds can also be displayed but cannot be set on this version of the program.

Committer:
euxton
Date:
Thu Jan 11 21:55:57 2018 +0000
Revision:
2:92208e3aae5a
Parent:
1:75322449b2fd
1st commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LancasterUniversity 0:0041f35b0c4c 1 /*
LancasterUniversity 0:0041f35b0c4c 2 The MIT License (MIT)
LancasterUniversity 0:0041f35b0c4c 3
LancasterUniversity 0:0041f35b0c4c 4 Copyright (c) 2016 British Broadcasting Corporation.
LancasterUniversity 0:0041f35b0c4c 5 This software is provided by Lancaster University by arrangement with the BBC.
LancasterUniversity 0:0041f35b0c4c 6
LancasterUniversity 0:0041f35b0c4c 7 Permission is hereby granted, free of charge, to any person obtaining a
LancasterUniversity 0:0041f35b0c4c 8 copy of this software and associated documentation files (the "Software"),
LancasterUniversity 0:0041f35b0c4c 9 to deal in the Software without restriction, including without limitation
LancasterUniversity 0:0041f35b0c4c 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
LancasterUniversity 0:0041f35b0c4c 11 and/or sell copies of the Software, and to permit persons to whom the
LancasterUniversity 0:0041f35b0c4c 12 Software is furnished to do so, subject to the following conditions:
LancasterUniversity 0:0041f35b0c4c 13
LancasterUniversity 0:0041f35b0c4c 14 The above copyright notice and this permission notice shall be included in
LancasterUniversity 0:0041f35b0c4c 15 all copies or substantial portions of the Software.
LancasterUniversity 0:0041f35b0c4c 16
LancasterUniversity 0:0041f35b0c4c 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
LancasterUniversity 0:0041f35b0c4c 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
LancasterUniversity 0:0041f35b0c4c 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
LancasterUniversity 0:0041f35b0c4c 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LancasterUniversity 0:0041f35b0c4c 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
LancasterUniversity 0:0041f35b0c4c 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
LancasterUniversity 0:0041f35b0c4c 23 DEALINGS IN THE SOFTWARE.
LancasterUniversity 0:0041f35b0c4c 24 */
euxton 1:75322449b2fd 25 /* This Microbit program for RTCC MCP7941X demonstrates use of:
euxton 1:75322449b2fd 26 the I2C interface,
euxton 1:75322449b2fd 27 button events to set the clock,
euxton 1:75322449b2fd 28 scrolling to display the time,
euxton 1:75322449b2fd 29 author phil.holifield@gmail.com
euxton 1:75322449b2fd 30 any comments welcome
euxton 1:75322449b2fd 31 */
LancasterUniversity 0:0041f35b0c4c 32
LancasterUniversity 0:0041f35b0c4c 33 #include "MicroBit.h"
LancasterUniversity 0:0041f35b0c4c 34
LancasterUniversity 0:0041f35b0c4c 35 MicroBit uBit;
LancasterUniversity 0:0041f35b0c4c 36
euxton 1:75322449b2fd 37 // for MCP7941X I2C control byte – 0xDE for RTCC
euxton 1:75322449b2fd 38 const int addr = 0xDE; // 8 bit addressing
euxton 1:75322449b2fd 39 char config_t[10];
euxton 1:75322449b2fd 40 char tim_read[8];
euxton 1:75322449b2fd 41 char disp_time[8];
euxton 1:75322449b2fd 42 char MSN, LSN, ch_hrs, ch_mins;
euxton 1:75322449b2fd 43 int secs, mins, hrs;
euxton 1:75322449b2fd 44 int inc_hr, inc_mins;
euxton 1:75322449b2fd 45
euxton 1:75322449b2fd 46 MicroBitI2C i2c(I2C_SDA0, I2C_SCL0);
euxton 1:75322449b2fd 47
euxton 1:75322449b2fd 48 void onButton(MicroBitEvent e)
euxton 1:75322449b2fd 49 {
euxton 1:75322449b2fd 50 if ((e.source == MICROBIT_ID_BUTTON_A) and (e.value == MICROBIT_BUTTON_EVT_DOWN)) {
euxton 1:75322449b2fd 51 inc_hr = inc_hr + 1; //increment by 1 for each press - hours
euxton 1:75322449b2fd 52 }
euxton 1:75322449b2fd 53 if ((e.source == MICROBIT_ID_BUTTON_B) and (e.value == MICROBIT_BUTTON_EVT_DOWN)) {
euxton 1:75322449b2fd 54 inc_mins = inc_mins + 1; //increment by 1 for each press - mins
euxton 1:75322449b2fd 55 }
euxton 1:75322449b2fd 56 }
euxton 1:75322449b2fd 57
euxton 1:75322449b2fd 58 // helper functions to manipulate BCD and binary to integers
euxton 1:75322449b2fd 59 int bcd2dec(char r_char)
euxton 1:75322449b2fd 60 {
euxton 1:75322449b2fd 61 MSN = (r_char & 0xF0)/16;
euxton 1:75322449b2fd 62 LSN = r_char & 0x0F;
euxton 1:75322449b2fd 63 return(10*MSN + LSN);
euxton 1:75322449b2fd 64 }
euxton 1:75322449b2fd 65 char msn(char tim)
euxton 1:75322449b2fd 66 {
euxton 1:75322449b2fd 67 return (tim & 0xF0)/16;
euxton 1:75322449b2fd 68 }
euxton 1:75322449b2fd 69 char lsn(char tim)
euxton 1:75322449b2fd 70 {
euxton 1:75322449b2fd 71 return (tim & 0x0F);
euxton 1:75322449b2fd 72 }
euxton 1:75322449b2fd 73
euxton 1:75322449b2fd 74 // Ensure RTCC is counting using the internal clk with ext xtal
euxton 1:75322449b2fd 75 void setConfig(void)
euxton 1:75322449b2fd 76 {
euxton 1:75322449b2fd 77 config_t[0] = 0x00;
euxton 1:75322449b2fd 78 config_t[1] = tim_read[0] | 0x80; // bitwise OR sets Start osc bit = 1
euxton 1:75322449b2fd 79 config_t[2] = tim_read[1];
euxton 1:75322449b2fd 80 config_t[3] = tim_read[2];
euxton 1:75322449b2fd 81 config_t[4] = tim_read[3];
euxton 1:75322449b2fd 82 config_t[5] = tim_read[4];
euxton 1:75322449b2fd 83 config_t[6] = tim_read[5];
euxton 1:75322449b2fd 84 config_t[7] = tim_read[6];
euxton 1:75322449b2fd 85 config_t[8] = 0x00; // control b3 - extosc = 0
euxton 1:75322449b2fd 86 }
euxton 1:75322449b2fd 87 int main()
LancasterUniversity 0:0041f35b0c4c 88 {
euxton 1:75322449b2fd 89 // Initialise the micro:bit runtime.
euxton 1:75322449b2fd 90 uBit.init();
euxton 1:75322449b2fd 91 inc_hr = 0;
euxton 1:75322449b2fd 92 inc_mins = 0;
LancasterUniversity 0:0041f35b0c4c 93
euxton 1:75322449b2fd 94 // Register to receive events when any buttons are clicked, including the A+B virtual button (both buttons at once).
euxton 1:75322449b2fd 95 uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, onButton);
euxton 1:75322449b2fd 96 uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, onButton);
euxton 1:75322449b2fd 97
euxton 1:75322449b2fd 98 // Initialise microbit by reading the time from the RTCC module and adding control bits
euxton 1:75322449b2fd 99 // ST bit must be 1 Ext Osc must be 0
euxton 1:75322449b2fd 100 // Write this once for set up if backup has battery
euxton 1:75322449b2fd 101 //i2c.write(addr, config_t, 9); //send time info only to set up
euxton 1:75322449b2fd 102
euxton 1:75322449b2fd 103 // read stored time data
euxton 1:75322449b2fd 104 config_t[0] = 0x00; //reset pointer reg to '00'
euxton 1:75322449b2fd 105
euxton 1:75322449b2fd 106 // Set up config to read the time and set the control bits
euxton 1:75322449b2fd 107 i2c.write(addr, config_t, 1); // write address 00
euxton 1:75322449b2fd 108 i2c.read(addr, tim_read, 7); //read time ss mm hh from r1, r2, r3
euxton 1:75322449b2fd 109 setConfig(); //puts RTCC data into config array from tim_read array
euxton 1:75322449b2fd 110 // write the config data
euxton 1:75322449b2fd 111 i2c.write(addr, config_t, 9); // write the config data back to the RTCC module
euxton 1:75322449b2fd 112
euxton 1:75322449b2fd 113 while(1) {
euxton 1:75322449b2fd 114 // continuous loop to get time and display
euxton 1:75322449b2fd 115 // First Get the time
euxton 1:75322449b2fd 116 config_t[0] = 0x00; //reset pointer reg to '00'
euxton 1:75322449b2fd 117 i2c.write(addr, config_t, 1);
euxton 1:75322449b2fd 118 i2c.read(addr, tim_read, 3); //read time
euxton 1:75322449b2fd 119
euxton 1:75322449b2fd 120 // display routine for seconds
euxton 1:75322449b2fd 121 secs = bcd2dec(tim_read[0]);
euxton 1:75322449b2fd 122 // Commented out seconds display as cannot set this
euxton 1:75322449b2fd 123 //disp_time[7] = 48+LSN;
euxton 1:75322449b2fd 124 //disp_time[6] = 48+MSN;
euxton 1:75322449b2fd 125 //disp_time[5] = 58;
euxton 1:75322449b2fd 126 disp_time[7] = 20;
euxton 1:75322449b2fd 127 disp_time[6] = 20;
euxton 1:75322449b2fd 128 disp_time[5] = 20;
euxton 1:75322449b2fd 129
euxton 1:75322449b2fd 130 //Display and set mins
euxton 1:75322449b2fd 131 mins = bcd2dec(tim_read[1]);
euxton 1:75322449b2fd 132 disp_time[4] = 48+LSN;
euxton 1:75322449b2fd 133 disp_time[3] = 48+MSN;
euxton 1:75322449b2fd 134 disp_time[2] = 58;
euxton 1:75322449b2fd 135 // re-calculate mins section if button B is pressed
euxton 1:75322449b2fd 136 if (inc_mins > 0) {
euxton 1:75322449b2fd 137 mins = mins + inc_mins;
euxton 1:75322449b2fd 138 mins = mins%60;
euxton 1:75322449b2fd 139 ch_mins = 16*(mins/10) + mins%10;
euxton 1:75322449b2fd 140 MSN = msn(ch_mins);
euxton 1:75322449b2fd 141 LSN = lsn(ch_mins);
euxton 1:75322449b2fd 142 disp_time[4] = 48+LSN;
euxton 1:75322449b2fd 143 disp_time[3] = 48+MSN;
euxton 1:75322449b2fd 144 tim_read[1] = ch_mins;
euxton 1:75322449b2fd 145 inc_mins = 0;
euxton 1:75322449b2fd 146 //write the data back to RTCC
euxton 1:75322449b2fd 147 setConfig();
euxton 1:75322449b2fd 148 i2c.write(addr, config_t, 9);
euxton 1:75322449b2fd 149 }
euxton 1:75322449b2fd 150
euxton 1:75322449b2fd 151 //Display and set hours
euxton 1:75322449b2fd 152 hrs = bcd2dec(tim_read[2]);
euxton 1:75322449b2fd 153 disp_time[1] = 48+LSN;
euxton 1:75322449b2fd 154 disp_time[0] = 48+MSN;
euxton 1:75322449b2fd 155 // re-calculate hrs section if button A is pressed
euxton 1:75322449b2fd 156 if (inc_hr > 0) {
euxton 1:75322449b2fd 157 hrs = hrs + inc_hr;
euxton 1:75322449b2fd 158 hrs = hrs%24;
euxton 1:75322449b2fd 159 ch_hrs = 16*(hrs/10) + hrs%10;
euxton 1:75322449b2fd 160 MSN = msn(ch_hrs);
euxton 1:75322449b2fd 161 LSN = lsn(ch_hrs);
euxton 1:75322449b2fd 162 disp_time[1] = 48+LSN;
euxton 1:75322449b2fd 163 disp_time[0] = 48+MSN;
euxton 1:75322449b2fd 164 tim_read[2] = ch_hrs;
euxton 1:75322449b2fd 165 inc_hr = 0;
euxton 1:75322449b2fd 166 //write the data back to RTCC
euxton 1:75322449b2fd 167 setConfig();
euxton 1:75322449b2fd 168 i2c.write(addr, config_t, 9);
euxton 1:75322449b2fd 169 }
euxton 1:75322449b2fd 170
euxton 1:75322449b2fd 171 // create the display string and scroll it
euxton 1:75322449b2fd 172 ManagedString s = disp_time;
euxton 1:75322449b2fd 173 uBit.display.scroll(s);
euxton 1:75322449b2fd 174 uBit.sleep(50);
euxton 1:75322449b2fd 175
euxton 1:75322449b2fd 176 }
euxton 1:75322449b2fd 177
euxton 1:75322449b2fd 178
LancasterUniversity 0:0041f35b0c4c 179
LancasterUniversity 0:0041f35b0c4c 180 // If main exits, there may still be other fibers running or registered event handlers etc.
LancasterUniversity 0:0041f35b0c4c 181 // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then
LancasterUniversity 0:0041f35b0c4c 182 // sit in the idle task forever, in a power efficient sleep.
LancasterUniversity 0:0041f35b0c4c 183 release_fiber();
euxton 1:75322449b2fd 184 } // end of main
euxton 1:75322449b2fd 185