touch 34 Posted March 2, 2011 Share Posted March 2, 2011 Here's some code I ported over from the Arduino to work on the MSP430G series. It's for decoding the Wiegand protocal used in this RFID reader: http://www.seeedstudio.com/depot/125khz ... th=144_153 It will print any detected RFID cards 3 byte ID over serial in HEX. Ports 1.4/1.5 are used for DATA0/DATA1 // Copyright (c) 2010 seeed technology inc. // Author: Icing Chang // Version: september 2, 2010 // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // Modified to by touch to work on the MSP430. #include #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600) char RFIDcardNum[3]; char evenBit = 0; char oddBit = 0; char isData0Low = 0; char isData1Low = 0; int recvBitCount = 0; char isCardReadOver = 0; int checkParity(); void resetData(); void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); unsigned int txData; // UART internal variable for TX void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1SEL = UART_TXD; P1DIR = UART_TXD + BIT0; P1IES |= 0x01; P1IFG = 0; P1IE |= BIT4 + BIT5; _BIS_SR(GIE); TimerA_UART_init(); TimerA_UART_print("RFID Ready:"); while(1){ if(isData0Low||isData1Low){ if(1 == recvBitCount){//even bit evenBit = (1-isData0Low)&isData1Low; } else if( recvBitCount >= 26){ oddBit = (1-isData0Low)&isData1Low; isCardReadOver = 1; } else{ //only if isData1Low = 1, card bit could be 1 RFIDcardNum[2-(recvBitCount-2)/8] |= (isData1Low << (7-(recvBitCount-2)%8)); } //reset data0 and data1 isData0Low = 0; isData1Low = 0; } //print the card id number if(isCardReadOver){ if(checkParity()){ TimerA_UART_print(RFIDcardNum); __delay_cycles(100000); } resetData(); } } } int checkParity(){ int i = 0; int evenCount = 0; int oddCount = 0; for(i = 0; i < 8; i++){ if(RFIDcardNum[2]&(0x80>>i)){ evenCount++; } } for(i = 0; i < 4; i++){ if(RFIDcardNum[1]&(0x80>>i)){ evenCount++; } } for(i = 4; i < 8; i++){ if(RFIDcardNum[1]&(0x80>>i)){ oddCount++; } } for(i = 0; i < 8; i++){ if(RFIDcardNum[0]&(0x80>>i)){ oddCount++; } } if(evenCount%2 == evenBit && oddCount%2 != oddBit){ return 1; } else{ return 0; } } void resetData(){ RFIDcardNum[0] = 0; RFIDcardNum[1] = 0; RFIDcardNum[2] = 0; evenBit = 0; oddBit = 0; recvBitCount = 0; isData0Low = 0; isData1Low = 0; isCardReadOver = 0; } #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { if(P1IFG & BIT4){ recvBitCount++; isData1Low = 1; } if(P1IFG & BIT5){ recvBitCount++; isData0Low = 1; } P1IFG = 0; } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } bluehash 1 Quote Link to post Share on other sites
bluehash 1,581 Posted March 2, 2011 Share Posted March 2, 2011 O_O good stuff touch. Thanks for sharing. Maybe we should have a small contest pool for the code vault and ported over code. Quote Link to post Share on other sites
JMLB 24 Posted March 2, 2011 Share Posted March 2, 2011 O_O good stuff touch. Thanks for sharing. Maybe we should have a small contest pool for the code vault and ported over code. that would be neat. You could require that the code is formatted in a library or some thing so it would be easy to use. Quote Link to post Share on other sites
bluehash 1,581 Posted March 2, 2011 Share Posted March 2, 2011 I was thinking the way Arduino manages its libraries. There is a core folder for low level functions and then a library folder for examples like ADC/RFID etc interfaces. Lets think about this a little more. Quote Link to post Share on other sites
zeke 693 Posted March 2, 2011 Share Posted March 2, 2011 I think this is a good idea too. We might have to come up with function templates for how code is called ie: a standard and expected way of doing things. But I have to ask, isn't MSPhere doing this already with his library work? Quote Link to post Share on other sites
bluehash 1,581 Posted March 2, 2011 Share Posted March 2, 2011 Unsure if its being activeyly developed. We can always use code from there or develop over it. Quote Link to post Share on other sites
GeekDoc 226 Posted March 6, 2011 Share Posted March 6, 2011 I bought a few of these Parallax units when Radio Shack (You've got questions, we've got blank stares) had them on clearance for $10. They're serial, so not the same as touch's, but I really should figure out how to read them with the MSP430. How many bytes can you store in flash on the 16-pin value line chips? The ids are 10 bytes each. Quote Link to post Share on other sites
NatureTM 100 Posted March 6, 2011 Share Posted March 6, 2011 I bought a few of these Parallax units when Radio Shack (You've got questions, we've got blank stares) had them on clearance for $10. They're serial, so not the same as touch's, but I really should figure out how to read them with the MSP430. How many bytes can you store in flash on the 16-pin value line chips? The ids are 10 bytes each. Hey Geek, yeah, when I go to "The Shack," I usually just say "I'm going to the parts drawers" and they leave me alone, aside from some cell phone/battery sales talk. I used to respect Radio Shack employees, but not any more. About the Parallax RFID reader, I picked up a few myself, and I have code for the MSP430 for them. It's just that my code is always so ugly I rarely share it, but if you just want something to start from, let me know, and I'll post/pm you it. I wish I wrote cleaner code... I have so much just sitting on my HDD! Quote Link to post Share on other sites
touch 34 Posted March 6, 2011 Author Share Posted March 6, 2011 I wanted to get some of the Parallax RFID readers but my Radio Shack had none . Looking at the specs they appear to use a 10byte card ID, the RDM630 cards appear to be 3 byte only. I also wondered about storing stuff in flash, as I wasn't able to find anything on storing stuff in the MSP430's flash memory. I had originally planned on making it so I could authorize or de-authorize cards from my RFID reader, but just ended up hardcoding the card ID's. Quote Link to post Share on other sites
bluehash 1,581 Posted March 6, 2011 Share Posted March 6, 2011 There is a monitor(pdf) program for the MSP430. You can store your IDs via the UART or probably even look through the code on how they use the flash. Also the "Flashing DCO constants" thread has some code on writing into Flash memory(Seg A) viewtopic.php?f=10&t=239&hilit=flash#p1803 Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A FCTL1 = FWKEY + WRT; // Set WRT bit for write operation Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts for (j = 0; j *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit GeekDoc 1 Quote Link to post Share on other sites
bluehash 1,581 Posted March 6, 2011 Share Posted March 6, 2011 Just as a warning, don't overwrite the section where the constants are. You will also need to modify your command(.cmd) file Another helpful thread at TI's e2e. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.