Jump to content
43oh

gssmahadevan

Members
  • Content Count

    10
  • Joined

  • Last visited

Reputation Activity

  1. Like
    gssmahadevan reacted to spirilis in [Energia Library] RF430CL - TI NFC RF430CL330H library   
    I have a library I've been working on for the past month or so to give Energia and Arduino users intuitive access to the TI RF430CL330H series of NFC transponders.
     
    https://github.com/spirilis/RF430CL
     
    This library is composed of two logical sections:
     
    1. The RF430 class which defines and manages a physical RF430CL330H NFC transponder over I2C using the "Wire" library
    2. The NDEF class system which allows users to conceptually define and manage NFC NDEF data records, importing & exporting them
     
    The NDEF class and subclasses (so far NDEF_URI, NDEF_TXT being the only RTD-specific subclasses implemented) maintain buffers for storing the NDEF "Type" field (a character string), "ID" field (optional, character string) and the actual payload.  The class is designed to be flexible so the user has to provide the buffer space (and maximum buffer size) for storing the Type, ID and Payload information, but some of the subclasses (and soon the base class) support defining those buffers as immutable data types (e.g. const uint8_t [] or const char [] arrays) for export usage only.
     
    For importing & exporting, the NDEF class and all subclasses have two methods:
     
    .sendTo(Stream &, boolean Message_Begin=true, boolean Message_End=true)
    .import(Stream &)
     
    sendTo writes byte-for-byte the physical NDEF record associated with that object's current state, returning an integer equal to the exact length (in bytes) of the NDEF binary record.  The two boolean arguments allow the user to customize the setting of the MB and ME bits in the NDEF header byte to support having multiple NDEF records in a single NFC memory segment.  If those boolean arguments are omitted, they default to "true" so the NDEF record will be written with both MB and ME bits set (typical usage for an NFC transponder housing only a single NDEF record).
     
    import uses the read() and readBytes() feature of the Stream object supplied to read, byte for byte, and analyze (rejecting by returning -1 if read errors or for RTD-specific sub-classes, if the header or structure of the record does not match the appropriate NDEF RTD type) and import the data.  Buffers must be defined for the NDEF object using .setPayloadBuffer(<buf>, <maxlen>) and for the base (generic) NDEF class, .setTypeBuffer() and optionally .setIDBuffer() so the import function has a place to store the TYPE and (optionally, if present, i.e. the "ID" bit is set in the NDEF header byte) ID strings.
     
    The RF430 class (which references the hardware) has an internal counter and I/O system which implements Arduino's "Stream" interface, so it's a valid target for the NDEF sendTo & import functions.  There are functions for changing/resetting the internal "pointer" as well as informing the RF430 library how much NDEF data is there (this must be set, or else any NFC master going to read or write to the transponder will error).
     
    Several examples are provided illustrating the use of the RF430 and NDEF classes and typical application program flow.  IRQ support is there, with the ability to detect whether an NFC master (e.g. cellphone) has read from the RF430CL330H recently, or has written a new record or series of records to the RF430CL330H's SRAM.
     
    There is still more work to be done to enable simpler and better-managed generic NFC importers, and I would like to make an NDEF subclass that eases the use of custom/externally-defined RTD types.
     
    As of now, this does not support the TRF7970A in any way.  In theory, I could support it in the future with the NDEF class infrastructure provided here.  The RF430CL330H is a whole lot simpler/easier to understand IMO.  I have been testing this with the F5529LP and DLP-RF430BP boosterpack.
     
    Here's a zip of the current codebase (from git as of 2/26/2015) - RF430CL_02262015.zip
     
    And here's one of the examples, illustrating how to write "Hello World" to the RF430CL330H and use Energia's Low-Power-Mode support (suspend() aka LPM4) to put the host MCU in deep sleep, waking up only when the RF430 sees an NFC master read or write to it:
    /* HelloWorld - NFC edition * Written for the TI RF430CL330H with Energia * * Showcases Low-Power Sleep modes in Energia and IRQ-driven wakeup of * the MCU based on RF430CL330H IRQs. * * 2/25/2015 Eric Brundick */ #include <Wire.h> #include <RF430CL.h> #include <NDEF.h> #include <NDEF_TXT.h> #define RF430CL330H_BOOSTERPACK_RESET_PIN 8 #define RF430CL330H_BOOSTERPACK_IRQ_PIN 12 RF430 nfc(RF430CL330H_BOOSTERPACK_RESET_PIN, RF430CL330H_BOOSTERPACK_IRQ_PIN); void setup() { Serial.begin(115200); delay(1000); Serial.println("Hello World - NFC edition!"); Serial.println("Here we will post the text \"Hello World\" to the RF430CL330H."); Serial.println("Initializing I2C and RF430CL330H-"); Wire.begin(); // Initialize I2C subsystem nfc.begin(); // Format RF430CL330H, prepare for data // Register interrupt to wake MCU when RF430CL330H INTO (IRQ) line triggers attachInterrupt(RF430CL330H_BOOSTERPACK_IRQ_PIN, wake_up, FALLING); Serial.println("Creating NFC NDEF_TXT object-"); NDEF_TXT helloWorld("en", "Hello World"); // English Serial.println("Posting to RF430CL330H-"); size_t ndef_size; ndef_size = helloWorld.sendTo(nfc); // Write NDEF data to NFC device memory nfc.setDataLength(ndef_size); // Inform NFC device memory how much data is there Serial.println("Activating RF430CL330H RF link-"); nfc.enable(); // Now we're live! } void loop() { if (nfc.loop()) { if (nfc.wasRead()) { Serial.println("Something has read the NFC device!"); } if (nfc.available()) { Serial.println("Something has re-written the NFC device!"); nfc.flush(); } nfc.enable(); // If nfc.loop() returns true, it will have disabled the RF link as a side-effect. } Serial.println("<low power sleep>"); Serial.flush(); // wait for unsent UART data to flush out before going into low-power sleep suspend(); // Enter indefinite sleep (LPM4 on MSP430, DEEPSLEEP on ARM) Serial.println("<wake up>"); } void wake_up() { wakeup(); // Signal Energia to wake the MCU upon IRQ exit }
  2. Like
    gssmahadevan reacted to spirilis in [Energia Library] Nordic nRF24L01+ library   
    Sure ... On the RX side, the transceiver is actually the event-producing piece; whereas the PIR sensor was in your TX example, the RX example is quite different.
     
    The nRF24L01+ will signal an IRQ on any of 3 conditions: TX succeeded, TX failed, RX event (successful receive of a packet with valid CRC, if CRC is enabled, which it is by default with my library).
     
    The former 2 are handled entirely within the context of Enrf24 when you run radio.flush(), so you never need to know about those.
    The last, however, is what you're looking for.
     
    The loop() should enter LPM4 when it's done handling any radio events, and then the nRF24L01+'s IRQ line should trigger an ISR that raises a flag and tells the chip to exit LPM4.
    Rewriting your example:
    #include <Enrf24.h> #include <nRF24L01.h> #include <string.h> #include <SPI.h> Enrf24 radio(P2_0, P2_1, P2_2); // P2.0=CE, P2.1=CSN, P2.2=IRQ const uint8_t rxaddr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x01 }; const char *str_ona = "ON_A"; const char *str_onb = "ON_B"; const char *str_onc = "ON_C"; void setup() { SPI.begin(); SPI.setDataMode(SPI_MODE0); SPI.setBitOrder(1); // MSB-first radio.begin(); // Defaults 1Mbps, channel 0, max TX power radio.setRXaddress((void*)rxaddr); pinMode(P2_3, OUTPUT); digitalWrite(P2_3, LOW); pinMode(P1_0, OUTPUT); digitalWrite(P1_0, LOW); pinMode(P2_4, OUTPUT); digitalWrite(P2_4, LOW); // IRQ config P2IFG &= ~BIT2; P2IES |= BIT2; // trigger P2.2 IRQ on High-To-Low transition P2IE |= BIT2; radio.enableRX(); // Start listening } volatile boolean radio_flag = FALSE; void loop() { char inbuf[33]; if (radio_flag) { if (radio.available(true)) { if (radio.read(inbuf)) { if (!strcmp(inbuf, str_ona)) digitalWrite(P2_3, HIGH); if (!strcmp(inbuf, str_onb)) digitalWrite(P1_0, HIGH); if (!strcmp(inbuf, str_onc)) digitalWrite(P2_4, HIGH); } } radio_flag = FALSE; // reload flag for next event } if (!radio.available(true)) { // Any more packets waiting? LPM4; // Assuming no more packets are pending, go to sleep. } else { radio_flag = TRUE; /* If a new packet arrived in the middle of us handling * the old one, manually re-trigger the radio_flag and * let loop() re-start so our code will handle the next * packet waiting in the transceiver's RX FIFO. */ } } // P2 ISR; should only be concerned with P2.2 here #pragma vector=PORT2_VECTOR __interrupt void P2ISR() { if (P2IFG & BIT2) { radio_flag = TRUE; __bic_SR_register_on_exit(LPM4_bits); P2IFG &= ~BIT2; } } As a side note, the fact that we have to go behind Energia's back and declare our own PORT2 ISR is another point of contention as to why Energia doesn't "properly cater to" LPM modes.  We shouldn't have to do this; there should be a special flag to attachInterrupt() that tells Energia "When this ISR runs, exit LPM" or perhaps some way for the ISR to inform the Energia PORT2 ISR that it should issue __bic_SR_register_on_exit(LPM4_bits) before exiting.  This is something I'd like to see changed in future versions of Energia.
     
    edit: Although, if your ISR runs long enough to let the Watchdog timer trigger, then it will exit LPM3; but I believe it'll still keep the ACLK disabled, so that's not really a proper & graceful exit.
  3. Like
    gssmahadevan reacted to stanley in [Energia Library] Nordic nRF24L01+ library   
    Before I forget, I quickly documented the entire process on my blog http://arduino-for-beginners.blogspot.com/2013/11/stellaris-launchpad-with-nrf24l01.html
  4. Like
    gssmahadevan reacted to hawwwran in [Energia Library] Nordic nRF24L01+ library   
    If someone else is interested in scanning for active devices on known array of addresses, here is my working solution:
     
    Device finder code:
    #include "Enrf24.h" #include "nRF24L01.h" #include <string.h> #include <SPI.h> Enrf24 radio(P2_0, P2_1, P2_2);  // P2.0=CE, P2.1=CSN, P2.2=IRQ const char IDENTIFY=1; char rxaddr[] = {'d','e','v','-','0'}; // address of commander (note that it's out of sequence of device addresses) char txaddr[] = {'d','e','v','-','a'}; // address of the first device unsigned long mil; unsigned long prev_time; char ch='a'; // set first "address" int verbosity=2; //0 - none, 1 - only responsive devices, 2 - only found devices, 3 - all tries char packet[]={0,0,0}; // set empty packet. First byte is command ID, the rest is DATA void setup() {   Serial.begin(9600);   // error led   pinMode(P1_0,OUTPUT);   digitalWrite(P1_0,LOW);   // success led   pinMode(P2_3,OUTPUT);   digitalWrite(P2_3,LOW);   SPI.begin();   SPI.setDataMode(SPI_MODE0);   SPI.setBitOrder(1); // MSB-first   radio.begin();  // Defaults 1Mbps, channel 0, max TX power     radio.setTXaddress((void*)txaddr);   radio.setRXaddress((void*)rxaddr);   radio.enableRX(); } void identifyDevices(int slow=0) // slow var is because of the serial output. If you need high verbosity, the serial could be overloaded {   char inbuf[33];     if(ch>'z'){ch='a';}   txaddr[4]=ch;   ch++;   radio.setTXaddress((void*)txaddr);     digitalWrite(P1_0,LOW);   digitalWrite(P2_3,LOW);     packet[0]=IDENTIFY;     radio.lastTXfailed=false;   radio.print(packet);   radio.flush();   if(radio.lastTXfailed)   { // blink error led (data was not received)     digitalWrite(P1_0,HIGH);     delay(1);     digitalWrite(P1_0,LOW);          if(verbosity>2)     { // No device detected on tested address       Serial.print("NONE [");       Serial.print(txaddr[0]);       Serial.print(txaddr[1]);       Serial.print(txaddr[2]);       Serial.print(txaddr[3]);       Serial.print(txaddr[4]);       Serial.println("]");     }   }   else   { // blink success led (data was received)     digitalWrite(P2_3,HIGH);     delay(5);     digitalWrite(P2_3,LOW);     //     delta_set(); // set delta (start timer)     while (!radio.available(true) && delta_get()<10) // wait 10ms for data to receive     {            }     if (radio.read(inbuf))     {       if(verbosity>0)       { // device found and respond received         Serial.print("OK [");         Serial.print(txaddr[0]);         Serial.print(txaddr[1]);         Serial.print(txaddr[2]);         Serial.print(txaddr[3]);         Serial.print(txaddr[4]);         Serial.print("] - ");         Serial.println(inbuf);       }     }     else     {       if(verbosity>1)       { // device found, but no response         Serial.print("NO RESPONSE [");         Serial.print(txaddr[0]);         Serial.print(txaddr[1]);         Serial.print(txaddr[2]);         Serial.print(txaddr[3]);         Serial.print(txaddr[4]);         Serial.println("]");       }     }     //   }   delay(slow); } void loop() {     identifyDevices(1000); } unsigned long delta_set() {       prev_time = millis();       return prev_time; } unsigned long delta_get() {       unsigned long time;       unsigned long delta;              time = millis();       if (time < prev_time) { // Timer overflow             delta = 0xffffffff - prev_time + time + 1;       } else {             delta = time - prev_time;       }       return delta; } Demo device code:
    #include "Enrf24.h" #include "nRF24L01.h" #include <string.h> #include <SPI.h> Enrf24 radio(P2_0, P2_1, P2_2); // P2.0=CE, P2.1=CSN, P2.2=IRQ const char IDENTIFY=1; char rxaddr[] = {'d','e','v','-','g'}; // address of the device char txaddr[] = {'d','e','v','-','0'}; // address of the commander void setup() {   Serial.begin(9600);   SPI.begin();   SPI.setDataMode(SPI_MODE0);   SPI.setBitOrder(1); // MSB-first     radio.begin();  // Defaults 1Mbps, channel 0, max TX power   radio.setRXaddress((void*)rxaddr);   radio.setTXaddress((void*)txaddr);     pinMode(P1_0, OUTPUT);   digitalWrite(P1_0, LOW);   pinMode(P1_3, OUTPUT);   digitalWrite(P1_3, LOW);   pinMode(P1_4, OUTPUT);   digitalWrite(P1_4, LOW);     radio.enableRX();  // Start listening } void loop() {   char inbuf[33];     while (!radio.available(true))   {     }   if (radio.read(inbuf))   {     Serial.println(inbuf);     if (inbuf[0]==IDENTIFY)     { // if IDENTIFIcation is required, respond      radio.print("Demo device #1");      radio.flush();     }   }   } It goes through all addresses (dev-a to dev-z) in about half a second (without the slow variable, with serial output verbosity 2 and with delays for led blink).
     
  5. Like
    gssmahadevan reacted to turd in MSP430FG4618 and 24LC512   
    Here's an example using an MSP430G2553 and a 24LC256.
    It's not perfect but it works.
     
    It first writes "HELLO WORLD" too 0x0000 then reads it back and sends it out the UART at 9600.
    I hope it helps
     

    //#include //For mspgcc //#include //For mspgcc #include "msp430g2553.h" //Address word + "HELLO WORLD" unsigned char txdata[14] = {0x00, 0x00, 0x00, 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x20, 0x57, 0x4F, 0x52, 0x4C, 0x44}; unsigned char rxdata[12]; unsigned char tx_byte_count; unsigned char rx_byte_count; unsigned char tx_byte_counter; unsigned char rx_byte_counter; unsigned char i; unsigned char tx_rx; void i2c_tx(unsigned char tx_count); void i2c_rx(unsigned char rx_count); void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop WDT BCSCTL1 = CALBC1_1MHZ; //Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; P1SEL = BIT1 + BIT2; //Set RXD and TXD P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2; //Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; //Baud = 9600 UCA0BR1 = 0; UCA0MCTL = UCBRS_1; //Modulation UCA0CTL1 &= ~UCSWRST; //Start USCI P1SEL |= BIT6 + BIT7; //Set I2C pins P1SEL2|= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; //Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; //Use SMCLK, keep SW reset UCB0BR0 = 12; //fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0b1010000; //Slave Address UCB0CTL1 &= ~UCSWRST; //Clear SW reset, resume operation IE2 |= UCB0TXIE; //Enable TX interrupt IE2 |= UCB0RXIE; //Enable RX interrupt __delay_cycles(20000); //Just a start up delay i2c_tx(13); //i2c TX 13 bytes(Address word + "HELLO WORLD" __delay_cycles(20000); //Allow 24LC256 to write data i2c_tx(2); //i2c TX address i2c_rx(12); //i2c RX data for(i = 1; i < 12; i++) { while(!(IFG2 & UCA0TXIFG)); UCA0TXBUF = rxdata[i]; //UART TX data } __bis_SR_register(CPUOFF + GIE); //Wait for a reset } void i2c_tx(unsigned char tx_count) { tx_rx = 0; tx_byte_count = tx_count + 1; tx_byte_counter = tx_count; // Load TX byte counter UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is TX'd } void i2c_rx(unsigned char rx_count) { tx_rx = 1; rx_byte_count = rx_count + 1; rx_byte_counter = rx_count; // Load RX byte counter UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is RX'd } //interrupt(USCIAB0TX_VECTOR) USCIAB0TX_ISR(void) #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) //For mspgcc { if(tx_rx == 0) { if (tx_byte_counter > 0) //Check TX byte counter { UCB0TXBUF = txdata[tx_byte_count - tx_byte_counter]; // Load TX buffer tx_byte_counter--; //Decrement TX byte counter } else if(tx_byte_counter == 0) { UCB0CTL1 |= UCTXSTP; //I2C stop condition while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent IFG2 &= ~UCB0TXIFG; //Clear USCI_B0 TX int flag __bic_SR_register_on_exit(CPUOFF); //Exit LPM0 } } else if(tx_rx == 1) { if (rx_byte_counter > 0) //Check RX byte counter { rxdata[rx_byte_count - rx_byte_counter] = UCB0RXBUF; rx_byte_counter--; //Decrement RX byte counter } else if(rx_byte_counter == 0) { UCB0CTL1 |= UCTXSTP; // I2C stop condition while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent rxdata[rx_byte_count - (rx_byte_counter + 1)] = UCB0RXBUF; rxdata[rx_byte_count - (rx_byte_counter + 1)] = UCB0RXBUF; IFG2 &= ~UCB0RXIFG; // Clear USCI_B0 RX int flag __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } } }
    It hasn't been tested with CCS or IAR just mspgcc.
     



  6. Like
    gssmahadevan got a reaction from Econiunioks in Does any one made SDCARD/MMC works with valueline MCUs   
    Finally I am able to write to SDcard write to an existing file.
    Two changes were done:
    * main.c: parser changes to allow write-commands to work
    * Enabling _USE_LSEEK and _USE_WRITE flags to enable lseek and write in FAT-FS
     
    Over next weekend, I will streamline the code and will post the code changes. I was doing following as per Petit-FS docs (and as suggested by Dan):

    1. pf_lseek(ofs); 2.1 pf_write(buff, btw, &bw); 2.2 pf_write(buff, btw, &bw); .. 3. pf_write(0, 0, &bw);
  7. Like
    gssmahadevan reacted to PentiumPC in Bluetooth Booster Pack / Breakout board - HC05/HC06   
    Cleanup the silkscreen, add in labels for all pin, rearrange stuff a bit.
    Still able to convert to breakout board. ( bit tight, need to cut properly.)
    Made provision for Hardware UART. (pin swap).
     
    Here is the the final look. (updated with new picture, fixing the mistake pointed out by RobG.)
     

  8. Like
    gssmahadevan got a reaction from bluehash in Does any one made SDCARD/MMC works with valueline MCUs   
    Finally I am able to write to SDcard write to an existing file.
    Two changes were done:
    * main.c: parser changes to allow write-commands to work
    * Enabling _USE_LSEEK and _USE_WRITE flags to enable lseek and write in FAT-FS
     
    Over next weekend, I will streamline the code and will post the code changes. I was doing following as per Petit-FS docs (and as suggested by Dan):

    1. pf_lseek(ofs); 2.1 pf_write(buff, btw, &bw); 2.2 pf_write(buff, btw, &bw); .. 3. pf_write(0, 0, &bw);
  9. Like
    gssmahadevan reacted to bluehash in Does any one made SDCARD/MMC works with valueline MCUs   
    Yes, that is correct. You can do it yourself.
    Thing that are needed for write support:
    1. Enable the parser to accept write commands
    2. Enabling write may cause some printf functions to be used, which makes the code larger.
     
    I'll fix it when I get the time.
  10. Like
    gssmahadevan reacted to DanAndDusty in Does any one made SDCARD/MMC works with valueline MCUs   
    I have written a library of routines for talking to SD Cards at a low level and Im working on a FAT32 compatible library.
     
    The SDCARD library Ive written uses 512 byte blocks and works fine.
     
    For the FAT library for program memory usage Im limiting it to only SD Cards.. NOT MMC or SDHC. From what I read SDHC cards ALWAYS return 512 byte blocks. SD Standard capacity cards can have the block size changed (Assuming the READ_BL_PARTIAL flag is set on the card). This means that you can read any block size from 1 byte upward. I *think* that you can only read with the RAM available on the valueline chips as it looks like not many cards have the WRITE_BL_PARTIAL flag set. So you have to write 512 bytes at a time. So updating the FAT table or directory entries looks VERY difficult if not impossible without an external storage.
     
    The restriction on reading partial blocks looks surmountable by initiating a read of a complete block and discarding the bytes either side of the bytes you are interested in.
     
    Bluehash also posted some code using someones library for talking to SDCards. If I remember right he disabled the writing code in the library. Anyways the link is Here.
     
    Im planning on releasing my library into the code area of the website when Im happy with it (and I get more non xmas time and can play). My eventual plan is to use it as a springboard to learning assembler by re-writing it once Ive got it completed. I know the guts of how it works so it should be a good project to learn on.
     
    Hope some of this helps.
     
    Dan
  11. Like
    gssmahadevan reacted to bluehash in PetiteFS FATfs SDCard USCI code   
    Edit: July 6th, 2014
    Please also note that Pabigot maintains BSP430 which has an example for the msp430. He also tracks any changes done to the ElmChan library with patches made to the example. Refer this post.
     
    ---------------------------------------
    First version. It's very untidy as I just got it to work. Works on USCI on the MSP430G2553. Supports Read/Listing. The monitor code does not have write yet. It works on the SDCard Boosterpack.
     

    I also used Rickta's serial code to reduce file size. I'll update to the next version once I have time and a clean it up to. Also need to add more features.

    Usage in screenshot.
    di : disk initialize
    fi : mount disk
    fl : list files
    fo filename: open file name.



    Latest Code:
    http://www.43oh.com/forum/viewtopic.php?f=10&t=1883&start=20#p18738'>Code Rev 0.2

    Member Contributed Code:
    Jazz_ys - http://forum.43oh.com/topic/1427-petitefs-fatfs-sdcard-usci-code/page__st__20#entry24449'>Link
    SDCARD_PetiteFS_2553_v0.01.zip
    SDCARD_PetiteFS_2553_v0.02.zip
×
×
  • Create New...