Home DIY or DIY Smart watches with their own hands for 1500 rubles. Part 3 – the program at the MC

Smart watches with their own hands for 1500 rubles. Part 3 – the program at the MC

by admin

Smart watches with their own hands for 1500 rubles. Part 3 - the program at the MC
Now it’s time to post the source code of the firmware of the IC, but first I want to thank bigbee for the brand new case for my watch, which he printed and sent to me completely free of charge. Also thanks to Chameleonka For the offer to print the case.
So, the program was written in Code Compmser Studio V 5.3.0
I won’t describe the code in detail but I will describe the important points (in my opinion).
I want to mention right away that this program is not perfect and not optimized.
Here we go
The program includes a file Symbols.h which contains a table of symbols, icons for the notification panel, numbers for the clock. All data are represented as arrays, which store the data for the pixel-by-pixel display on the screen.
The file TI_USCI_I2C_master.h is also included. This is a standard library from TI to work with the USCI module as an I2C master for receiving – transmitting data.
Inclusions and definitions

#include <msp430g2553.h>#include "Symbols.h"#include "TI_USCI_I2C_master.h"/* Bit operations */#define BIT_SET(lval, mask) ((lval) |= (mask))#define BIT_CLR(lval, mask) ((lval) = ~(mask))#define BIT_TEST(val, mask) (((val) (mask))==(mask))/* BSL */#define TXD BIT1 // P1.1: BSL TxD#define RXD BIT5 // P1.5: BSL RxD/* BT */#define BT_TXD BIT1 // P2.1: UART BT TxD#define BT_RXD BIT0 // P2.0: UART BT RxD#define BT_PWR BIT2 // P2.2, P3.2#define BT_LED BIT3 // P3.3/* LCD */#define PIN_RESET BIT2 // P1.2 RESET#define PIN_SCE BIT3 // P1.3 CS#define PIN_SDIN BIT4 // P1.4 SDA //mosi#define PIN_SCLK BIT1 // P3.1 SCK#define PIN_LED BIT0 // P3.0 display backlight#define LCD_C 0 // Command#define LCD_D 1 // Data/* Buttons vibro */#define B_CENT BIT4 // P2.4#define B_UP BIT3 // P2.3#define B_DOWN BIT5 // P2.5#define vibro BIT4 // P3.4/* System configuration */#define TIMER1A_CLOCK 1000000L // Timer1_A clock rate (1 MHz)#define UART_BAUD 9600 // desired UART baud rate#define BT_BITTIME (TIMER1A_CLOCK/UART_BAUD) // Bit interval#define BT_HALF_BT ((BT_BITTIME+1)/2) // Half-bit interval#define Slave_Address 0x68 // address RTC

Definition of functions

void check_akkum(void); // check battery statusvoid check_bluetooth(void); // check BT statusvoid uart_tx_bt(char c); // sending a symbol through BTvoid uart_puts_bt(char const* s); // sending a string by BTvoid get_time_from_rtc(void); // getting time from VFD and writing it to FLASHvoid set_time_to_rtc(void); // writing time to FLASHvoid LcdCharacter(char character); // display charvoid LcdClear(void); // clear the whole screenvoid clear_1(void); // clear the screen except for the status barvoid Lcd_set_pos(unsigned char c, unsigned char r); // set position in characters per linevoid Lcd_set_pos_pix(unsigned char c, unsigned char r); // set the position in pixels per linevoid lcd_contrast(unsigned char contrast2); // set the screen contrastvoid lcd_dig(unsigned char num, unsigned char pos_x, unsigned char pos_y); // clock digitsvoid lcd_dot(unsigned char num, unsigned char pos_x, unsigned char pos_y); //cdot the clockvoid LcdWrite(unsigned char dc, unsigned char data); // send the command/data to the screenvoid LcdString(char *characters); // output stringvoid lcd_show_sms(unsigned char a); // sms iconvoid lcd_show_call(unsigned char a); //call iconvoid lcd_show_bt(unsigned char a); // BT iconvoid lcd_show_bat(unsigned char proc); // battery iconvoid lcd_set_time_big(void); // show big clockvoid lcd_set_time_small(void); // display small clock (in status bar)void lcd_show_main(void); // show main screen (date and big clock)void menuu_setting(unsigned char submenu); // menuvoid down_sub_menu(void); // menu navigationvoid up_sub_menu(void); // and changes in the submenuvoid parse_string(void); // parsing of received string

Configuring MK modules to work with external clock modules :

  • DCO – Built-in oscillator frequency 8MHz;
  • Timer0 – PWM for display backlight;
  • Timer1 – Software UART to communicate with BT;
  • WDT+ – Interval timer for clock checks;
  • FLASH – Storage of changeable settings and date/time;
  • ADC10 – ADC for determining the battery voltage.

Initializing

 WDTCTL = WDTPW + WDTHOLD; // turn off watchdog// init clocksBCSCTL1 = CALBC1_8MHZ;DCOCTL = CALDCO_8MHZ;BCSCTL2 = 0; // MCLK = 8MHz/1, SMCLK = 8MHz/1BCSCTL3 = LFXT1S_2; // Mode 2 for LFXT1 : VLO = 12kHz__delay_cycles(800000);// put the BSL legs on the output and log. 0BIT_SET(P1DIR, TXD | RXD);BIT_CLR(P1OUT, TXD | RXD);edit_time = 0;// take the screen settings information from FLASHchar *a;a = (char*) 0x104d;contrast = *a++;pwm_width = 0x00ff | (*a++) << 8;timer_off = ((*a++) 0x00ff) << 8;timer_off |= ((*a++) 0x00ff);// set ports for LCDBIT_SET(P1DIR, PIN_RESET + PIN_SCE + PIN_SDIN);BIT_SET(P3DIR, PIN_SCLK);BIT_CLR(P1OUT, PIN_RESET + PIN_SDIN);BIT_CLR(P3OUT, PIN_SCLK);BIT_SET(P1OUT, PIN_SCE);BIT_SET(P3DIR, PIN_LED);BIT_SET(P3OUT, PIN_LED);BIT_SET(P1OUT, PIN_RESET);// LCD initialization sequenceLcdWrite(LCD_C, 0xE2); // software resetLcdWrite(LCD_C, 0x3D); // Charge pump ONLcdWrite(LCD_C, 0x01); // Charge pump=4LcdWrite(LCD_C, 0xA4); //LcdWrite(LCD_C, 0x2F); //LcdWrite(LCD_C, 0xC0); // normal up-downLcdWrite(LCD_C, 0xA0); // normal left-right__delay_cycles(800000);LcdWrite(LCD_C, 0xAF); // Display ONLcdClear();Lcd_contrast(contrast);BIT_SET(P3SEL, PIN_LED);BIT_SET(P3DIR, PIN_LED);// PWM timer for the backlightTACTL = TASSEL_2 + ID_0 + MC_1 + TACLR; // SMCLK/1 + direct count to TACCR0 + counter clearTACCR0 = 0x0fff; // PWM periodTACCR2 = pwm_width; // PWM fill for backlightTACCTL2 = OUTMOD_6; // PWM output// init BluetoothBIT_SET(P3DIR, BT_PWR);BIT_CLR(P3REN, BT_PWR);BIT_SET(P3OUT, BT_PWR);BIT_SET(P2DIR, BT_PWR);BIT_CLR(P2REN, BT_PWR);BIT_SET(P2OUT, BT_PWR); // power BT ONBIT_CLR(P3DIR, BT_LED); //bt statusbt_on = 1;lcd_show_bt(1);//Timer1 for uartTA1CTL = TASSEL_2 + ID_3 + MC_2 + TAIE; //SMCLK/8 + Continous up + interrupt enableTA1CCTL1 = OUT; //TxTA1CCTL0 = CM_2 + SCS + CAP + CCIE; //Rx//Rx and TX ports for BTBIT_SET(P2SEL, BT_TXD + BT_RXD);BIT_SET(P2DIR, BT_TXD);//timer for screen offBIT_SET(TA1CCTL2, CCIE);//button setupBIT_CLR(P2DIR, B_CENT|B_UP|B_DOWN);// direction of pins - INBIT_SET(P2REN, B_CENT|B_UP|B_DOWN);//connect resistorsBIT_SET(P2IE, B_CENT|B_UP|B_DOWN);// allow interruptsBIT_SET(P2IES, B_CENT|B_UP|B_DOWN);// interrupt occurs on 1/0 (release/press)BIT_CLR(P2IFG, B_CENT|B_UP|B_DOWN);// clearing the interrupt flag.// WDT+ as interval timer, 12 kHz - ACLK - VLOWDTCTL = WDTPW + WDTTMSEL + WDTSSEL;BIT_SET(IE1, WDTIE);// vibro - outputBIT_SET(P3DIR, vibro);BIT_CLR(P3OUT, vibro);lcd_show_main(); // main screen__enable_interrupt();edit_time = 0;get_time = 0;set_time = 0;get_time_from_rtc(); // update time__delay_cycles(8000000);set_time_to_rtc(); // update time// init ADCADC10CTL0 = SREF_1 + ADC10SR + REF2_5V + ADC10SHT_2 + REFON + ADC10ON + ADC10IEADC10CTL1 = INCH_0;ADC10AE0 |= 0x01; // set pin 0 as ADC input

Interruptions
All interrupt handlers disable other interrupts first, which are enabled back when the handler finishes.
When BT data is received, either Timer1 is interrupted if the clock is in active mode, or P2 if the clock is in power save mode.
In LPM3 mode, SMCLK is disabled, so the timer does not work. If the BT port P2 is interrupted, switch the MCU to active mode and set pin BT_RXD to Timer1 input.
At the end of data reception (end of message character 0x00) the received string is processed. The first character of the string is an ID. "1" – phone connected to the watch; "2" – incoming sms; "3" – incoming call; "4" – text to be simply displayed on the watch screen; "5" – date and time sent from the phone.
Parsing the line

 unsigned int il;unsigned char z, k;switch (inputString[0]) {case '1': { // indication of a phone successfully connected to BTBIT_SET(P3OUT, vibro);__delay_cycles(1600000);BIT_CLR(P3OUT, vibro);__delay_cycles(1600000);BIT_SET(P3OUT, vibro);__delay_cycles(1600000);BIT_CLR(P3OUT, vibro);__delay_cycles(1600000);BIT_SET(P3OUT, vibro);__delay_cycles(1600000);BIT_CLR(P3OUT, vibro);lcd_show_bt(2);bt_connect = 1;break;}case '2': { // incoming sms indicationcurrent_screen = 1;lcd_show_sms(1);lcd_show_call(0);clear_1();Lcd_set_pos(0, 1);z = 1;il = 1;k = 15;if (multiscreen) {current_screen = 4;while (il < 105) {LcdCharacter(inputString[il]);if (++il > k){Lcd_set_pos(0, ++z);k += 15;}}LcdCharacter(0x7f);} elsewhile (inputString[il] != 0x00) {LcdCharacter(inputString[il]);if (++il > k){Lcd_set_pos(0, ++z);k += 15;}}BIT_SET(P3OUT, vibro);__delay_cycles(2800000);BIT_CLR(P3OUT, vibro);__delay_cycles(2400000);BIT_SET(P3OUT, vibro);__delay_cycles(8000000);BIT_CLR(P3OUT, vibro);break;}case '3': { // incoming call indicationcurrent_screen = 1;lcd_show_sms(0);lcd_show_call(1);clear_1();Lcd_set_pos(0, 2);il = 1;z = 2;k = 15;while (inputString[il] != 0x00) {LcdCharacter(inputString[il]);if (++il > k){Lcd_set_pos(0, ++z);k += 15;}}call_true = 1;BIT_SET(P3OUT, vibro);__delay_cycles(1600000);BIT_CLR(P3OUT, vibro);__delay_cycles(800000);BIT_SET(P3OUT, vibro);__delay_cycles(8000000);BIT_CLR(P3OUT, vibro);__delay_cycles(1600000);BIT_SET(P3OUT, vibro);__delay_cycles(1600000);BIT_CLR(P3OUT, vibro);__delay_cycles(800000);BIT_SET(P3OUT, vibro);__delay_cycles(8000000);BIT_CLR(P3OUT, vibro);break;}case '4': { // displaying the sent textcurrent_screen = 1;lcd_show_sms(0);lcd_show_call(0);clear_1();Lcd_set_pos(0, 1);il = 1;z = 1;k = 15;if (multiscreen) {current_screen = 4;while (il < 105) {LcdCharacter(inputString[il]);if (++il > k){Lcd_set_pos(0, ++z);k += 15;}}LcdCharacter(0x7f);} elsewhile (inputString[il] != 0x00) {LcdCharacter(inputString[il]);if (++il > k){Lcd_set_pos(0, ++z);k += 15;}}break;}case '5': { // saving the sent time edit_time= 1;s10 = inputString[1] 0x0f;s1 = inputString[2] 0x0f;m10 = inputString[3] 0x0f;m1 = inputString[4] 0x0f;h10 = inputString[5] 0x0f;h1 = inputString[6] 0x0f;dw = (inputString[7] 0x0f) + 1 ;d10 = inputString[8] 0x0f;d1 = inputString[9] 0x0f;mo10 = inputString[10] 0x0f;mo1 = inputString[11] 0x0f;ye10 = inputString[14] 0x0f;ye1 = inputString[15] 0x0f;set_time = 1;break;}default: {break;}}if (!multiscreen)for (il = 313; il > 0; il--)inputString[il] = 0;

The interrupt handler P2 also checks for button presses. If the button is pressed, it exits the power save mode. Also for each button in the P2 interrupt handler there is a loop to check the "long" press.
The WDT+ interrupt handler checks the BT status, gives a command to update the time from the PDV, gives a command to enable the ADC.
The ADC10 interrupt handler gives a command to update the battery status. The ADC10 interrupt is triggered after the end of the conversion.
Working with FLASH

// writing data to FLASHchar *Flash_ptrC;Flash_ptrC = (char *) 0x1040; // Point to beginning of seg CFCTL2 = FWKEY + FSSEL_1 + FN1; // MCLK/3 for Flash Timing GeneratorFCTL1 = FWKEY + ERASE; // Set Erase bitFCTL3 = FWKEY ; // Clear LOCK*Flash_ptrC = 0x00; // Dummy write to erase Flash seg CFCTL1 = FWKEY + WRT; // Set WRT bit for write operationFlash_ptrC = (char *) 0x1040; // Point to beginning*Flash_ptrC++ = s10; // 0x1040*Flash_ptrC++ = s1; // 0x1041*Flash_ptrC++ = m10; // 0x1042*Flash_ptrC++ = m1; // 0x1043*Flash_ptrC++ = h10; // 0x1044*Flash_ptrC++ = h1; // 0x1045*Flash_ptrC++ = dw; // 0x1046*Flash_ptrC++ = d10; // 0x1047*Flash_ptrC++ = d1; // 0x1048*Flash_ptrC++ = mo10; // 0x1049*Flash_ptrC++ = mo1; // 0x104a*Flash_ptrC++ = ye10; // 0x104b*Flash_ptrC++ = ye1; // 0x104c*Flash_ptrC++ = contrast; // 0x104d*Flash_ptrC++ = (pwm_width 0xff00) > > 8; // 0x104e*Flash_ptrC++ = (timer_off 0xff00) > > 8; // 0x104f*Flash_ptrC++ = (timer_off 0x00ff); // 0x1050FCTL1 = FWKEY; // Clear WRT bitFCTL3 = FWKEY + LOCK; // Set LOCK// read data from FLASHchar *a;a = (char*) 0x1040;s10 = *a++;s1 = *a++;m10 = *a++;m1 = *a++;h10 = *a++;h1 = *a++;dw = *a++;d10 = *a++;d1 = *a++;mo10 = *a++;mo1 = *a++;ye10 = *a++;ye1 = *a++;contrast = *a++;pwm_width = 0x00ff | (*a++) << 8;timer_off = ((*a++) 0x00ff) << 8;timer_off |= ((*a++) 0x00ff);

Program sources here
And more photos of the new hull :
Smart watches with their own hands for 1500 rubles. Part 3 - the program at the MC
Smart watches with their own hands for 1500 rubles. Part 3 - the program at the MC
As always, I look forward to questions and comments.
Part 1 – The Beginning
Part 2 – Board and Components

You may also like