From f7f0fc325d072235ae83dd91f3c233cffeda53c4 Mon Sep 17 00:00:00 2001 From: b Date: Sat, 27 Jun 2020 13:05:01 +0200 Subject: [PATCH] bidirectional transmission at 9600, new commands --- .gitignore | 1 + definitions.h | 43 +++- main.c | 593 +++++++++++++++++++++++++++++++++++--------------- makefile | 40 +++- 4 files changed, 481 insertions(+), 196 deletions(-) diff --git a/.gitignore b/.gitignore index 6c90a9d..d3aa545 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.a43 *.elf *.hex +*.map diff --git a/definitions.h b/definitions.h index 804f506..90da63b 100644 --- a/definitions.h +++ b/definitions.h @@ -1,8 +1,8 @@ -// SilentTimer Action Figure software, v1.5 +// SilentTimer Action Figure software, v2.1 // definitions.h // Definitions used by the code. // -// 03.05.2020 +// 09.06.2020 // Copyright (C) 2014-2017, 2020 Balthasar Szczepański // // This program is free software: you can redistribute it and/or modify @@ -39,7 +39,23 @@ //7 segment display -#if defined OLD_HARDWARE +#if defined NEW_DISPLAY + +#define SEG_A 0xfb +#define SEG_B 0xf7 // aaaa +#define SEG_C 0xfd // f b +#define SEG_D 0x7f // f b +#define SEG_E 0xbf //hh gggg +#define SEG_F 0xfe // e c +#define SEG_G 0xdf // e c +#define SEG_H 0xef // dddd + +#define PIN_AB 0x23 +#define PIN_CD 0x17 +#define PIN_EF 0x60 +#define PIN_GH 0x54 + +#elif defined OLD_HARDWARE #define SEG_A 0xdf #define SEG_B 0xef // aaaa @@ -50,6 +66,11 @@ #define SEG_G 0xf7 // e c #define SEG_H 0xfe // dddd +#define PIN_AB 0x54 +#define PIN_CD 0x67 +#define PIN_EF 0x12 +#define PIN_GH 0x30 + #else #define SEG_A 0xfd @@ -61,6 +82,11 @@ #define SEG_G 0xbf // e c #define SEG_H 0xf7 // dddd +#define PIN_AB 0x14 +#define PIN_CD 0x20 +#define PIN_EF 0x57 +#define PIN_GH 0x63 + #endif #define SYMB_0 (SEG_A & SEG_B & SEG_C & SEG_D & SEG_E & SEG_F ) @@ -132,11 +158,22 @@ #define EVENTS 0x1f +#define EVENT_ALARM 0x20 +#define EVENT_0 0x40 + #define ALARMVALUE 0xa5 + +//rs232 #define RXBUFSIZE 11 #define RXDATASIZE 5 +#define TXBUFSIZE 32 +#define TXBUFMASK 31 + +#define BAUDCOUNT 625 //6MHz/625 = 9600Hz (buzz. 4.8kHz) +#define BAUDHALF (313+200) //determined by oscilloscope observation + unsigned char bcd_add_byte (unsigned char, unsigned char); void lpm3 (); diff --git a/main.c b/main.c index 994cfda..8d6ede5 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,8 @@ -// SilentTimer Action Figure software, v1.5 +// SilentTimer Action Figure software, v2.1 // main.c // The main c file. // -// 03.05.2020 +// 27.06.2020 // Copyright (C) 2014-2017, 2020 Balthasar Szczepański // // This program is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . + // #define NEW_DISPLAY // #define OLD_HARDWARE // #define DEBAG #include "msp430.h" @@ -42,6 +43,7 @@ unsigned char changed; //changed value during edit unsigned char run; //switch used in some states unsigned char cont; //continued calculation + unsigned char buzzmode=0; //buzzer, 0-normal, 1-mute, 2-always on. //for RS232 receiving volatile unsigned char rxbyte=0; @@ -52,7 +54,16 @@ unsigned char rxdata[RXDATASIZE]; unsigned char rxcmd; + volatile unsigned char txbyte; + volatile unsigned char txcount=0; + volatile unsigned char txindW=0; + volatile unsigned char txindR=0; + volatile unsigned char txpin=1; + volatile unsigned char txbuf[TXBUFSIZE]; + volatile unsigned char txbuzz=0; + volatile unsigned char event=0; + unsigned char eventmask=0; const unsigned char symbol[16] ={ SYMB_0, @@ -81,6 +92,10 @@ void leave(void); void showvalue(void); + void send(unsigned char data); + void sendhex(unsigned char data); + void sendevent(unsigned char data); + void display( unsigned char *data); void spi( @@ -91,26 +106,81 @@ unsigned short n); int main( void ); - + + void send(unsigned char data) + { + if (data == '\n') + send ('\r'); + + while (((txindW - txindR) & TXBUFMASK) == TXBUFMASK) {} //wait for free buffer + + //put byte to output buffer + txbuf[txindW] = data; + ++txindW; + txindW &= TXBUFMASK; + + if (!(TACCTL0 & CCIE)) + { + TACCTL0 &= ~CCIFG; + TACCTL0 |= CCIE; + } + } + + void sendhex (unsigned char data) + { + unsigned char i,j; + + for (i=0; i<2; ++i) + { + j = i? (data & 0x0f) : (data>>4); + + if (j>9) + j += 87; + else + j += 48; + + send(j); + } + } + + void sendevent (unsigned char data) + { + if (data & eventmask) + { + send('O'); + sendhex(data); + send('\n'); + } + } + void display(unsigned char *data) { - //lsd - P1OUT =data[0]; - P3OUT |=0x80; //74hc373 latch enable - P3OUT &=0x0f; + unsigned char i,j; - P1OUT =data[1]; - P3OUT |=0x40; - P3OUT &=0x0f; + for(i=0,j=0x80; i<4; ++i, j>>=1) + // for(i=0,j=0x80; i<2; ++i, j>>=1) + { + P1OUT = data[i]; + P3OUT |= j; + P3OUT &= ~j; + } + // //lsd + // P1OUT =data[0]; + // P3OUT |=0x80; //74hc373 latch enable + // P3OUT &=0x0f; + + // P1OUT =data[1]; + // P3OUT |=0x40; + // P3OUT &=0x0f; - P1OUT =data[2]; - P3OUT |=0x20; - P3OUT &=0x0f; + // P1OUT =data[2]; + // P3OUT |=0x20; + // P3OUT &=0x0f; - //msd - P1OUT =data[3]; - P3OUT |=0x10; - P3OUT &=0x0f; + // //msd + // P1OUT =data[3]; + // P3OUT |=0x10; + // P3OUT &=0x0f; } void spi( @@ -207,58 +277,126 @@ #pragma vector=TIMERA0_VECTOR __interrupt void TA0_ISR() { + // P3OUT |=0x10; + rxpin = P2IN & 0x10; //quickly capture state of P2.4 - TACCTL0 &= ~CCIFG; + if(txpin) + P2OUT |= 0x04; + else + P2OUT &= ~0x04; - ++rxcount; + TACCTL0 &= ~CCIFG; - if (!(rxcount & 0x01)) //only every second count + if (rxcount) // receive mode { - if (rxcount == 2) //start bit - { - if (rxpin) //start fail - { - rxcount = 0; - TACCTL0 &= ~CCIE; //abort - } - } - else if (rxcount >= 20) //stop bit - { - if (rxpin) //correct stop bit + ++rxcount; + + // if (!(rxcount & 0x01)) //only every second count + // { + if (rxcount == 2) //start bit { - if (rxbyte == 0x0d || rxbyte == 0x0a) // CR or NL, end of frame + if (rxpin) //start fail { - if(rxind) - { - rxind = 0; - event |= EVENT_RS; //signal - } + rxcount = 0; + txcount = 0; + txindR = txindW; + P2OUT |= 0x04; + TACCTL0 &= ~CCIE; //abort } - else + } + else if (rxcount >= 11) //stop bit + { + if (rxpin) //correct stop bit { - if (rxbyte >= 'g' && rxbyte <= 'z') //new command + if (rxbyte == 0x0d || rxbyte == 0x0a) // CR or NL, end of frame { - rxind=0; + if(rxind) + { + rxind = 0; + event |= EVENT_RS; //signal + } } - if (rxind < RXBUFSIZE) //still place in buffer + else { - rxbuf[rxind] = rxbyte; //put byte to buffer - ++rxind; + if ((rxbyte >= 'g' && rxbyte <= 'z') || (rxbyte >= 'G' && rxbyte <= 'Z')) //new command + { + rxind=0; + } + if (rxind < RXBUFSIZE) //still place in buffer + { + rxbuf[rxind] = rxbyte; //put byte to buffer + ++rxind; + } } } + rxcount = 0; + txcount = 0; + txindR = txindW; + P2OUT |= 0x04; + TACCTL0 &= ~CCIE; //stop receiving } - rxcount = 0; - TACCTL0 &= ~CCIE; //stop receiving - } - else //receive single bit + else //receive single bit + { + rxbyte >>= 1; + rxbyte |= rxpin ? 0x80 : 0x00; + } + // } + if(event) + _BIC_SR_IRQ(OSCOFF|CPUOFF|SCG1|SCG0); + } + + else if ((txindR != txindW) || txcount) //transmit mode + { + if(txcount) + --txcount; + + if (!txcount) //reached end of byte { - rxbyte >>= 1; - rxbyte |= rxpin ? 0x80 : 0x00; + if (txindR != txindW) //bytes to send available + { + txbyte=txbuf[txindR]; + ++txindR; //next byte + txindR &= TXBUFMASK; + txcount = 10; + } + + else if (txbuzz) //buzzer should be done + { + txbyte = 0x55; + txcount = 10; + } } + + // if (!(txcount & 0x01)) //every second count + // { + if ((txcount == 1) || (txcount == 0)) //stop bit + txpin = 1; + else if (txcount == 10) //start bit + txpin = 0; + else if (txcount < 10) //data bits + { + txpin = txbyte & 0x01; + txbyte >>= 1; + } + else //before start + txpin = 1; + // } } - if(event) - _BIC_SR_IRQ(OSCOFF|CPUOFF|SCG1|SCG0); + + else if (txbuzz) //buzzer should be done + { + txcount = 2; //start buzzer from stop bit + } + + + else //nothing left to do + { + txpin = 1; + TACCTL0 &= ~CCIE; + } + + // P3OUT &= ~0x10; return; } @@ -287,17 +425,27 @@ } else if(P2IFG&0x10) // RS232 { + // P3OUT |= 0x10; P2IFG &= ~0x10; if(!rxcount) //start bit detected { - TACTL |= TACLR; //reset timer + // TACTL |= TACLR; //reset timer + TACTL &= ~MC_3; //stop timer + TAR = BAUDHALF; //set timer to half count + TACTL |= MC_1; //start timer TACCTL0 &= ~CCIFG; //clear any waiting timer interrupt TACCTL0 |= CCIE; //enable timer interrupts rxcount = 1; rxbyte = 0; + + txcount = 0; //cancel transmission + // txindW = 0; + txindR = txindW; + txpin = 1; } + // P3OUT &= ~0x10; } else P2IFG=0; @@ -335,6 +483,7 @@ void gettime(void) mode=MODE_ALARM; alarm[0]=0; //alarm removed after activated spi(RTC_WRITE,0x20,inbuf,alarm,1); + sendevent(EVENT_ALARM); } @@ -498,7 +647,7 @@ void leave (void) //to execute when leaving an edit state else { alarm[0]=0; - spi(RTC_WRITE,0x20,inbuf,outbuf,1); + spi(RTC_WRITE,0x20,inbuf,alarm,1); } mode=MODE_TIME; break; @@ -664,7 +813,7 @@ void exec (void) //execute every second event |= EVENT_RTC; break; case MODE_DOWN: - if(run && (settime[1] | settime[0])) + if(run && (settime[1] || settime[0])) { if(settime[0]) settime[0]=bcd_add_byte(settime[0],0x99); @@ -673,6 +822,8 @@ void exec (void) //execute every second settime[0]=0x59; settime[1]=bcd_add_byte(settime[1],0x99); } + if (!(settime[1] || settime[0])) + sendevent(EVENT_0); } else run=0; @@ -839,7 +990,7 @@ void showvalue () //determine what to show on display break; case MODE_VER: dispvalue[4] = SYMB_NUL; - dispvalue[5] = SYMB_0; + dispvalue[5] = SYMB_1; dispvalue[6] = SYMB_2; dispvalue[7] = SYMB_NUL; dot |= 0x02; //. @@ -928,20 +1079,35 @@ void showvalue () //determine what to show on display if(dot & (1<>1] = j<<4; } - switch (rxcmd) + if(rxcmd & 0x20) //lowercase { - case 'g': //force display value - forcedisp[0]=rxdata[0]; - forcedisp[1]=rxdata[1]; - forcedisp[2]=rxdata[2]; - forcedisp[3]=rxdata[3]; - forcedisp[4]=1; - break; - case 'h': //free display value - forcedisp[4]=0; - break; - case 'i': //trigger event - event |= rxdata[0]; - break; - case 'j': //go to mode - mode = rxdata[0]; - enter(); - break; - case 'k': //select digit - digit = rxdata[0]; - break; - case 'l': //value under digit - i = digit >> 1; - j = settime[i]; - if (digit & 0x01) - { - j &= 0x0f; - j |= rxdata[0]<<4; - } - else + switch (rxcmd) { - j &= 0xf0; - j |= rxdata[0]&0x0f; + case 'g': //force display value + for (i=0; i<4; ++i) + forcedisp[i]=rxdata[i]; + forcedisp[4]=1; + break; + case 'h': //free display value + forcedisp[4]=0; + break; + case 'i': //trigger event + event |= rxdata[0]; + break; + case 'j': //go to mode + mode = rxdata[0]; + enter(); + break; + case 'k': //select digit + digit = rxdata[0]; + break; + case 'l': //value under digit + i = digit >> 1; + j = settime[i]; + if (digit & 0x01) + { + j &= 0x0f; + j |= rxdata[0]<<4; + } + else + { + j &= 0xf0; + j |= rxdata[0]&0x0f; + } + settime[i] = j; + break; + case 'm': //confirm editing + changed=1; + leave(); + enter(); + break; + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': //enter values + changed = 1; + settime[0] = rxdata[0]; + settime[1] = rxdata[1]; + settime[2] = rxdata[2]; + switch (rxcmd) + { + case 'n': //set time + mode = MODE_EDIT | MODE_SETTIME; + break; + case 'o': //set alarm + mode = MODE_EDIT | MODE_SETALARM; + if(settime[0]==0xff && settime[1]==0xff) + { + changed=0; + alarm[0]=ALARMVALUE; + } + break; + case 'p': //set date + mode = MODE_EDIT | MODE_SETDATE; + break; + case 'q': //set year + mode = MODE_EDIT | MODE_SETYEAR; + break; + case 'r': //set countdown + mode = MODE_EDIT | MODE_SETDOWN; + run=0; + break; + case 's': //set calibration + mode = MODE_EDIT | MODE_SETCALIB; + break; + case 't': //set debug address + mode = MODE_EDIT | MODE_SETDEBUGADDR; + break; + case 'u': //set debug value + mode = MODE_EDIT | MODE_SETDEBUGVAL; + break; + case 'v': //perform calculation + calcdata[0]=0x00; + calcdata[1]=0x00; + for (i=0; i<5; ++i) + calcdata[i+2]=rxdata[i]; + // calcdata[3]=rxdata[1]; + // calcdata[4]=rxdata[2]; + // calcdata[5]=rxdata[3]; + // calcdata[6]=rxdata[4]; + calcdata[7]=0; + run = 1; + cont = 0xFF; + mode = MODE_EDIT | MODE_SETCALCNUM; + } + leave(); + break; + case 'w': //set value + settime[0]=rxdata[0]; + settime[1]=rxdata[1]; + settime[2]=rxdata[2]; + break; + case 'x': //set run/pause + run = rxdata[0]; + break; + case 'y': //set buzzer mode + buzzmode = rxdata[0]; + break; + case 'z': //set memory + p = (unsigned char*)(*((unsigned short*)rxdata)); + *p = rxdata[2]; + break; } - settime[i] = j; - break; - case 'm': //confirm editing - changed=1; - leave(); - enter(); - break; - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': //enter values - changed = 1; - settime[0] = rxdata[0]; - settime[1] = rxdata[1]; - settime[2] = rxdata[2]; + } + else //uppercase + { + send(rxcmd); switch (rxcmd) { - case 'n': //set time - mode = MODE_EDIT | MODE_SETTIME; + case 'G': //get time + gettime(); + for (i=0; i<8; ++i) + { + if (i != 4) + sendhex(time[i]); //hs + } + sendhex(lastyear[4]); //yL break; - case 'o': //set alarm - mode = MODE_EDIT | MODE_SETALARM; - if(settime[0]==0xff && settime[1]==0xff) - changed=0; + case 'H': //get state + sendhex(mode); break; - case 'p': //set date - mode = MODE_EDIT | MODE_SETDATE; + case 'I': //get display + for (i=0; i<4; ++i) + sendhex(dispvalue[i]); break; - case 'q': //set year - mode = MODE_EDIT | MODE_SETYEAR; + case 'J': //get value + sendhex(settime[0]); + sendhex(settime[1]); + sendhex(settime[2]); break; - case 'r': //set countdown - mode = MODE_EDIT | MODE_SETDOWN; - run=0; + case 'K': //get calculation + for (i=0; i<8; ++i) + sendhex(calcdata[i]); break; - case 's': //set calibration - mode = MODE_EDIT | MODE_SETCALIB; + case 'L': //get run state + sendhex(run); break; - case 't': //set debug address - mode = MODE_EDIT | MODE_SETDEBUGADDR; + case 'M': //get version + sendhex(1); + sendhex(2); break; - case 'u': //set debug value - mode = MODE_EDIT | MODE_SETDEBUGVAL; + case 'N': //get pinout + sendhex(PIN_AB); + sendhex(PIN_CD); + sendhex(PIN_EF); + sendhex(PIN_GH); + break; + case 'O': //subscribe for events + eventmask = rxdata[0]; + sendhex(0); + break; + case 'P': //get alarm + if(alarm[0]) + { + sendhex(alarm[1]); + sendhex(alarm[2]); + } + else + { + sendhex(0xFF); + sendhex(0xFF); + } + break; + case 'Q': //get diit + sendhex(digit); + break; + case 'R': //set memory + p = (unsigned char*)(*((unsigned short*)rxdata)); + sendhex(*p); break; - case 'v': //perform calculation - calcdata[0]=0x00; - calcdata[1]=0x00; - calcdata[2]=rxdata[0]; - calcdata[3]=rxdata[1]; - calcdata[4]=rxdata[2]; - calcdata[5]=rxdata[3]; - calcdata[6]=rxdata[4]; - calcdata[7]=0; - run = 1; - cont = 0xFF; - mode = MODE_EDIT | MODE_SETCALCNUM; } - leave(); - break; + send('\n'); } } else if (event & EVENT_RTC) { event &= ~ EVENT_RTC; + sendevent(EVENT_RTC); gettime(); exec(); } showvalue(); - display(forcedisp[4]?forcedisp:dispvalue); } else //go to low power mode if nothing's going on diff --git a/makefile b/makefile index 55c300b..623bf44 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,8 @@ -# SilentTimer Action Figure software, v1.5 +# SilentTimer Action Figure software, v2.1 # makefile # -# 29.02.2016 -# Copyright (C) 2014-2016 Balthasar Szczepański +# 27.06.2020 +# Copyright (C) 2014-2016, 2020 Balthasar Szczepański # # 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 @@ -19,13 +19,19 @@ CC=msp430-gcc CF=-g -Wa,-g,-L -Os -mmcu=msp430f1232 -# OC=msp430-objcopy -# OF=-O ihex +OC=msp430-objcopy +OF=-O ihex -all: st.elf +all: st.elf st_AB.elf st_ID.elf st.hex st_AB.hex st_ID.hex main.o: main.c definitions.h makefile - msp430-gcc -g -c -Os -mmcu=msp430f1232 -o main.o main.c + msp430-gcc -g -c -Os -mmcu=msp430f1232 -o main.o main.c + +main_AB.o: main.c definitions.h makefile + msp430-gcc -g -c -Os -mmcu=msp430f1232 -o main_AB.o main.c -D OLD_HARDWARE + +main_ID.o: main.c definitions.h makefile + msp430-gcc -g -c -Os -mmcu=msp430f1232 -o main_ID.o main.c -D NEW_DISPLAY asmp.s: asm.S makefile msp430-gcc -E -mmcu=msp430f1232 -o asmp.s asm.S @@ -34,9 +40,19 @@ asm.o: asmp.s makefile msp430-as -g -mmcu=msp430f1232 -o asm.o asmp.s st.elf: main.o asm.o makefile - msp430-gcc -g -mmcu=msp430f1232 -o st.elf main.o asm.o -#st.elf: main.c asm.S definitions.h makefile -# $(CC) $(CF) -o st.elf asm.S main.c + msp430-gcc -g -mmcu=msp430f1232 -o st.elf main.o asm.o -Xlinker -Map=st.map -# st.hex: st.elf makefile -# $(OC) $(OF) st.elf st.hex +st_AB.elf: main_AB.o asm.o makefile + msp430-gcc -g -mmcu=msp430f1232 -o st_AB.elf main_AB.o asm.o -Xlinker -Map=st_AB.map + +st_ID.elf: main_ID.o asm.o makefile + msp430-gcc -g -mmcu=msp430f1232 -o st_ID.elf main_ID.o asm.o -Xlinker -Map=st_ID.map + +st.hex: st.elf makefile + $(OC) $(OF) st.elf st.hex + +st_AB.hex: st_AB.elf makefile + $(OC) $(OF) st_AB.elf st_AB.hex + +st_ID.hex: st_ID.elf makefile + $(OC) $(OF) st_ID.elf st_ID.hex -- 2.30.2