SamuelVergeiner 0 Posted January 25, 2018 Share Posted January 25, 2018 Hello, I hope this is the right forum to post in, I'm a new user here... So, I have been trying to get the RFM12b module to work with my MSP430F5529. The connections are as follows for transmission: VDD --> 3.3V GND--> GND SDO-->P6.5 nIRQ-->P3.4 nSEL-->P3.3 SCK-->P1.6 SDI-->P6.6 Now, I have the following code, in which I only configure the module and try to read its status register: #include "main.h" void WriteCMD(unsigned int CMD); void Write1(); void Write0(); int check_status(); void main() { //init ports P6DIR |= BIT5; //set SDO as output on P6.5 P3DIR &= ~BIT4; //set nIRQ as input on P3.4 P3REN |= BIT4; P3DIR |= BIT3; //set nSEL as output on P3.3 P1DIR |= BIT6; //set SCK as output on P1.6 P6DIR &= ~BIT6; //set SDI as input on P6.6 P6REN &= ~BIT6; //init rfm12b WriteCMD(0x80D8);//enable register,433MHz,12.5pF WriteCMD(0x82D8);//enable receive,!PA WriteCMD(0xA640);// WriteCMD(0xC647);// WriteCMD(0x94A0);//VDI,FAST,134kHz,0dBm,-103dBm WriteCMD(0xC2AC); WriteCMD(0XCC77);// WriteCMD(0xCA80); WriteCMD(0xCA83);//FIFO8,SYNC, WriteCMD(0xC49B); WriteCMD(0x9850);//!mp,9810=30kHz,MAX OUT WriteCMD(0xE000);//NOT USE WriteCMD(0xC800);//NOT USE WriteCMD(0xC000);//1.0MHz,2.2V //statusregister auslesen int cnt = 16; int result = 0; int temp = 0; P3OUT &= ~BIT3; //set nSEL low P6OUT &= ~BIT5; //set SDO low while(cnt--) { __delay_cycles(10); temp = P6IN; temp = temp <<2; result |= temp; result = result <<1; P1OUT |= BIT6; // set SCK high __delay_cycles(10); __no_operation(); P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); P3OUT |= BIT3; //set nSEL high; } __no_operation(); while(1) { __no_operation(); result= result-1; result = result+1; } } void WriteCMD( unsigned int CMD ) { unsigned char n=16; P1OUT &= ~ BIT6; //set SCK low P3OUT &= ~BIT3; //set nSEL low, selecting the rfm12b __delay_cycles(10); while(n--) { if(CMD&0x8000) { Write1(); } else { Write0(); } CMD=CMD<<1; } P1OUT &= ~ BIT6; //set SCK low P3OUT |= BIT3; //set nSEL high, deselecting the rfm12b __delay_cycles(10); } void Write0 (void) { P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); P6OUT &= ~BIT5; //set SDO low __delay_cycles(10); P1OUT |= BIT6; //set SCK high, rfm now reads SDO __delay_cycles(10); P1OUT &= ~BIT6; //set SCK low } void Write1(void) { P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); P6OUT |= BIT5; //set SDO high __delay_cycles(10); P1OUT |= BIT6; //set SCK high, rfm now reads SDO __delay_cycles(10); P1OUT &= ~BIT6; //set SCK low } Now, the status register should read "0x4000", but I always get "0xFFF8" and this makes me nervous. I have also tried simply connecting two modules and sending data between the two with a bit different programms, but that also didn't yield any results. Can anyone here help me? I've been to the 10th site of Google search results and haven't found anything that could help me. I got my instructions from the following site: https://gobotronics.wordpress.com/2010/10/07/rfm12-programming/. Thanks in advance! Quote Link to post Share on other sites
terjeio 134 Posted January 25, 2018 Share Posted January 25, 2018 I think I have spotted at least three mistakes when reading back the result: 1 . You shift the contents of P6IN the wrong way and do not mask the unwanted bits before or'ing with the result (assuming MSB is sent first). 2. You shift the result after adding a new bit, the shift should be done before adding it. 3. You deselect the device after reading the first bit (MSB) of the result. Move setting nSel high out of the loop. result <<= 1; result |= (P6IN >> 6) & 0x01; The code above migth work for reading the result. However, why not use one of the USCI modules for SPI instead of bitbanging? From a quick glance at the datasheet it seems you can use a fairly high data rate. Fmilburn 1 Quote Link to post Share on other sites
SamuelVergeiner 0 Posted January 28, 2018 Author Share Posted January 28, 2018 Thank you for your answer. First things first, I am a student at a technical school in Austria and this is part of a project for class. My problem is that our teacher does not really want to help us if we have problems. He always tells us to "google ourself". Now, that I have struggled so long, I thought that my only way to ever getting this thing to run is by asking in a forum, and here we are. (And by the way, I have to use bitbanging because my teacher wants me to.) So, I have implemented your code, with a slight change, so I can analyse it better. Now, my result is always 0x0000. Shouldn't I be getting "0x4000"? All the connections are soldered properly and my program seems to do what it should, but I simply do not get the right value. What else can I do? My code is exactly the same except this passage: /statusregister auslesen int cnt = 16; int result = 0; int temp = 0; P3OUT &= ~BIT3; //set nSEL low P6OUT &= ~BIT5; //set SDO low while(cnt--) { result <<=1; temp = P6IN; temp >>=6; temp &= 0x01; result |= temp; P1OUT |= BIT6; // set SCK high __delay_cycles(10); P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); } P3OUT |= BIT3; //set nSEL high; __no_operation(); while(1) { __no_operation(); result= result-1; result = result+1; } } Please help me, I am beginning to loose my mind on this... Quote Link to post Share on other sites
Frida 4 Posted January 29, 2018 Share Posted January 29, 2018 On 25/1/2018 at 12:07 PM, SamuelVergeiner said: From doc rfm12b are: SDI, SCK and nSEL output from f5529 and SDO and nIRQ input to f5529 Your init: P6DIR | = BIT5; // set SDO as output on P6.5 P6DIR & = ~ BIT6; // set SDI as input on P6.6 is wrong In your reading routine, you must have SCK high before reading input eg. P1OUT | = BIT6; // set SCK high __delay_cycles (10); temp = p6in; P1OUT & = ~ BIT6; // set SCK low __delay_cycles (10); Hope it helps! Quote Link to post Share on other sites
SamuelVergeiner 0 Posted January 31, 2018 Author Share Posted January 31, 2018 I have implemented your changes in my program, but it does not work after all. Thank you for pointing me to this error - I must have confused the modules in- and outputs with the controller's. I do not know what else I could try. My teacher didn't even want to look at my program. He just kept saying that the internet is my friend. My program now looks like this: #include "main.h" #include <stdint.h> void WriteCMD(unsigned int CMD); void Write1(); void Write0(); int check_status(); void main() { //WDTCTL = WDTPW + WDTHOLD; // stop watchdog timer to prevent time out reset //init ports P6DIR &= ~BIT5; //set SDO as input on P6.5 P6REN &= ~BIT5; P3DIR &= ~BIT4; //set nIRQ as input on P3.4 P3REN &= ~BIT4; P3REN |= BIT4; P3DIR |= BIT3; //set nSEL as output on P3.3 P1DIR |= BIT6; //set SCK as output on P1.6 P6DIR |= BIT6; //set SDI as output on P6.6 //init rfm12b WriteCMD(0x80D8);//enable register,433MHz,12.5pF WriteCMD(0x82D8);//enable receive,!PA WriteCMD(0xA640);// WriteCMD(0xC647);// WriteCMD(0x94A0);//VDI,FAST,134kHz,0dBm,-103dBm WriteCMD(0xC2AC); WriteCMD(0XCC77);// WriteCMD(0xCA80); WriteCMD(0xCA83);//FIFO8,SYNC, WriteCMD(0xC49B); WriteCMD(0x9850);//!mp,9810=30kHz,MAX OUT WriteCMD(0xE000);//NOT USE WriteCMD(0xC800);//NOT USE WriteCMD(0xC000);//1.0MHz,2.2V //statusregister auslesen int cnt = 16; int result = 0; int temp = 0; P3OUT &= ~BIT3; //set nSEL low P6OUT &= ~BIT6; //set SDI low while(cnt--) { result <<=1; P1OUT |= BIT6; // set SCK high __delay_cycles(10); temp = P6IN; temp >>=4; temp &= 0x01; result |= temp; P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); } P3OUT |= BIT3; //set nSEL high; __no_operation(); while(1) { __no_operation(); result= result-1; result = result+1; } } void WriteCMD( unsigned int CMD ) { unsigned char n=16; P1OUT &= ~ BIT6; //set SCK low P3OUT &= ~BIT3; //set nSEL low, selecting the rfm12b __delay_cycles(10); while(n--) { if(CMD&0x8000) { Write1(); } else { Write0(); } CMD=CMD<<1; } P1OUT &= ~ BIT6; //set SCK low P3OUT |= BIT3; //set nSEL high, deselecting the rfm12b __delay_cycles(10); } void Write0 (void) { P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); P6OUT &= ~BIT6; //set SDI low __delay_cycles(10); P1OUT |= BIT6; //set SCK high, rfm now reads SDO __delay_cycles(10); P1OUT &= ~BIT6; //set SCK low } void Write1(void) { P1OUT &= ~BIT6; //set SCK low __delay_cycles(10); P6OUT |= BIT6; //set SDI high __delay_cycles(10); P1OUT |= BIT6; //set SCK high, rfm now reads SDO __delay_cycles(10); P1OUT &= ~BIT6; //set SCK low } And for clearence, the pins in my initiation (SDO, SDI, nIRQ, nSEL, SCK) are connected as in the attached picture. Meaning that the SDO port of the RFM12b is connected to P6.5 and is defined as an input for my controller. Now, that the initiation is correct, only the connections can be wrong. My program is right after all, isn't it? I hope I am not getting on your nerves with my noobery, but I can't solve this problem on my own. Looking forward to your reply! Quote Link to post Share on other sites
dubnet 238 Posted January 31, 2018 Share Posted January 31, 2018 What your professor should have said is: "A logic analyzer is your best friend". Seriously though, if you can borrow a logic analyzer to monitor what is happening on your communication lines that would allow you to see what is really happening. It is very difficult to troubleshoot communication issues between devices without one since you can't tell if you have a hardware issue, a software issue or a combination of the two. If you can't get a hold of a logic analyzer then a four channel memory scope, although not ideal, could help shed some light on the situation as well. Quote Link to post Share on other sites
Frida 4 Posted February 1, 2018 Share Posted February 1, 2018 Firstly, you have not stopped watchdog. void main () { // WDTCTL = WDTPW + WDTHOLD; // stop watchdog timer to prevent time out reset // init ports Secondly, what bit do you read now and how many shift do you have? temp = p6in; temp >> = 4; These are the most illuminated points now. Keep on, at last it will success. Quote Link to post Share on other sites
SamuelVergeiner 0 Posted February 7, 2018 Author Share Posted February 7, 2018 The line concerning watchdog was copied from a program we wrote with our teacher, haha. I bet, he doesn't even know how to code himself *face palm*. But, i googled it and the posts there say that the line "WDTCTL = WDTPW + WDTHOLD;" should stop watchdog. However, others say that "WDTCL = WDTPW | WDTHOLD;" Which one is the right one? Secondly, I am reading P6.5 - in the byte P6 the "x" (00x0000). So, I have to shift it four positions to the right in order for bit0 to be the value I want to read, if I understand this correctly. I do not have my MSP with me at the moment, but I will do some trial and error today and post my "results". Quote Link to post Share on other sites
Frida 4 Posted February 7, 2018 Share Posted February 7, 2018 In logical circles, we normally use + and * for OR and AND, which in programming is also | and &. So +, OR or | are the same. So *, AND or & is the same. Port P6 has 8 bits that we usually count bit 1 to bit 8, but The processor counts from 0 to 7. | --- P6.5 ~ SDO | BIT 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 WEIGHT 128 64 32 16 8 4 2 1 Quote Link to post Share on other sites
terjeio 134 Posted February 8, 2018 Share Posted February 8, 2018 Quote So +, OR or | are the same. Not always so, e.g.: 2 + 1 + 1 = 4, 2 | 1 | 1 = 3 I prefer to OR bitwise constants, adding them is not logical... Quote Link to post Share on other sites
Frida 4 Posted February 8, 2018 Share Posted February 8, 2018 Yes, when you join the 10's system, it does not work. But when using weighted values, it works. 16 + 8 + 4 = 28 16 | 8 | 4 = 28 [edit] The rules of calculation must be used on logic circles, not on normal account. There were rules I learned in the 1970s. 2 + 1 + 1 = 3, not 4 If you take 1 + 1 = 1 because 1 becomes or with 1. 2 + 1 = 3 because 2 becomes or with 1. Binary is 2 = 10 and 1 = 01, these or together give 3 = 11. 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.