Sunday, March 29, 2009

Sending SMS in PDU mode (GSM)

This topic is not exactly limited to embedded domain. When we want to use sms protocol on GSM network, the communication can be done over a GSM modem. Some GSM modems provide a mean to install a java applet onto modem's firmware itself to control and interact via AT commands. However, usually GSM modem can be controlled using AT commands via serial interface.
The following discussion will focus on how to send an sms in PDU mode via serial interface to modem using AT commands.

Modem Configuration and Data Formatting
  1. Get the serial interface configured according to the baud rate specified in modem's data sheet.
  2. Test the modem's response by sending AT and then enter key ( ASCII - 0x0A,0x0D) from serial interface. Modem will send back OK if the communication between controller and modem is working.
  3. If your SIM requires PIN to unlock, send AT+CPIN="****", where **** are pin number in ASCII. To ensure if SIM is ready, send AT+CPIN? If response is SIM PIN, the SIM card is still waiting for the correct PIN to get unlocked. If response is READY, the communication to GSM network through SIM is ready to begin.
  4. In order to see what are the causes of error when we cannot send AT commands, we have to enable error printing from modem. It can be done by sending AT+CMEE=2. This will switch on verbose error reporting.
  5. In order to get receiving packets from network, we have to configure the modem such that unsolicited report is ON. To accomplish that, send AT+CNMI=0,2,0,1,0.
  6. After all this configuration, we are now ready to send SMS.
  7. Send AT+CMGF=0 to set the modem to PDU mode. ( some modem supports text mode)
  8. Format the PDU as follow
  • Octect (1) SMSC information --> 0x00 [ determined by modem ]
  • Octect (2) PDU-first octect --> 0x11 [ Validity period Type - relative, SMS-submit (yup, we are sending out)]
  • Octect(3) MessageReference--> 0x00 [ the modem decides what was the last counter value for send messages]
  • Octect(4) LenPhNo--> 0x0A [ let say we are sending to singapore handphone +6590123456]
  • Octect(5) Type of Addr --> 0x91 [ International ISDN ]
  • Octect(6-10) PhNoInDecimalSemiOctect format --> 0x56 0x09 0x21 0x43 0x65
  • (note: if phone number is of Odd count, the last nibble is filled with 15(0xf), For example for phone number +65901234567, the formatted octects are 0x56 0x09 0x21 0x43 0x65 0xF7)
  • Octect(11) Protocol Identifier --> 0x00 [ we are sending normal sms and not some special protocol like fax over GSM]
  • Octect(12) Data Coding Scheme --> 0x00 [ 7 bits defaut], however if you want to send UCS-2 format ( other languauge support-e.g. chinese character), set it to 0x19 [UCS2, Class-1 message], Or if you are sending some special data of byte size, use 0x15 [8-bit encoding]
  • Octect(13) Validity Perios --> 0xA7 [12 hours]
  • Octect(14) User Data Len --> (length of your data)
  • Octect(15 - ??) --> DATA
Ok, now we have the data ready to send.

Sending ..
  1. Send AT+CMGS=** to modem. Here, ** is Length of Data excluding SMSC information. Therefore, following the above format, it will be at (Length of your data + 13).
  2. after that, send carriage return+ line feed (0x0d, 0x0a)
  3. Then, Send the above formatted message, followed by (Ctrl+z = 0x0a) [ NOTE here: don't send enter*]
  4. If the message is sucessfuly send, you can read back modem response as OK, +CMGS=**, where ** is last message reference number.
Since we turned on verbose error reporting, we can see the problem in case any error has occured. Bye for now..

Monday, August 11, 2008

a Book excerpt on Embedded Site

The following links a book excerpt is posted in embedded.com ebook.
DSP Tricks: A/D converter testing techniques and finding missing codes in ADCs

USB and Serial flash boot table for C55


USB bootloader bootable options in TI's 5000 series DSPs are hardware configured for choosing boot options, whether to boot from binary file downloaded through USB cable from host PC or from it's MCBSP serial port, etc.

Upon powerup, pre-programmed bootloader in the DSP chip starts to run and check hardware pins to decide from where it has to download the codes. Our program, which is output from the compiler ( .out file) can be converted into suitable format that's capable of system start up after being downloaded from respective interface, i.e. , USB or flash or external memory etc.

The following shows the option set up in .cmd file for hex55.exe

USB boot loader bootable options in .cmd file

Input.out .out file

-boot generate boot table

-v5510:2 boot table format = 2.0 for C5509a ( Modify accordingly)

-serial8 8 bits serial interface

-reg_config 0x1c00, 0x2810 CPU clock set to 192MHz ( maximum)

-delay 0x80 Delay program start to run after bootable finished downloading

-b output binary format

-o Output.bin name of output file

- map Output.bxp map file to describe detail of bootable memory allocation


EEPROM bootloader bootable options in cmd files

Input.out .out file

-boot generate boot table

-v5510:2 boot table format = 2.0 for C5509a

-serial8 8 bits serial interface

-reg_config 0x1c00, 0x2810 CPU clock set to 192MHz (maximum)

-reg_config 0x280B, 0x0004 MCBSP0 clock set to 1/5 of CPU clock = 38.4MHz (for faster download, this is optimized for 50MHz serial flash memory)

-b output binary format

-o Output.bin name of output file

- map Output.bxp map file to describe detail of bootable memory allocation


Friday, August 8, 2008

Some Useful Links for USB

Just wanna share some useful links with you today.
Though there are so many people explaining about USB, USB cables, USB protocol and how descriptors are exchanged and stuffs, I found the following links useful for those who wants to know what is going on in usb enumeration process.
Some might not find them necessary. But, of course, we firmware engineers deal with this low-level headaches ( headaches that we are addicted to .. haha! ) on everyday basis.
Next Monday, I will come up with Generating Boot table format for usb bootloading and serial flash bootloader for TI C55x processors. Now, Enjoy your weekend! Relax your Binary Reasoning and Analytical Intelligence Network and be more productive next week ^_^

USB Made Simple

How USB works


USB Interop Testing

Thursday, August 7, 2008

Checking Task Stack Overflow in DSP/BIOS

For embedded system, reliability is of great importance. At the later stage of development, with all functionality are tested working, we are left with this challenging work of optimizing speed and memory consumptions of each process thread in our system. Of course we all want to have freedom in assigning stack size to ensure that there is no overflow even when there are certain unfavorable events happen to our system. Yet, unfortunately, the nature of our work requires us to work in a box.
How can we check the task overflow?
In DSP/BIOS, we can make use of task-specific API to check Stack overflow for each task thread.
Firstly, How Task Specific Stacks are used for context switching and function Calling?

at Calling Function
1. Content of RETA to Stack Pointer’s TOS. Content of CFCT to System Stack Pointer’s TOS.
2. Return address (PC+1) to RETA. Loop Context to CFCT.

at Returning Function
1. Content RETA to PC. Content of CFCT to Loop Context bit.
2. TOS of Stack and SysStack to RETA and CFCT respectively.

Note:

TOS – Top of Stack
RETA – Return address register
CFCT – Control flow context Register
PC – Program Counter

Context Switch for DSP/BIOS threads

DSP/BIOS has 4 types of threads as arranged in the following in the order of highest priority to lowest.
1. HWI ( hardware Interrupt )
2. SWI ( software Interrupt )
3. TSK ( Task) and
4. IDL(System Task) – Inaccessible lowest priority system thread.

HWIs and SWIs use DSP/BIOS general Stack and SysStack as these threads will not be blocked until the processing is done. On the other hand, each task uses its dedicated task-specific Stack and SysStack. This is because tasks are blocking threads (can be suspended and preempted by higher priority threads) and it is needed to preserve context information for preemption context switch as well as its own function callings.

Allocation of Stack size and SysStack size for each task requires us to ensure that the stack doesn’t overflow while making the stack size (and thus the memory usage ) to be minimum.

DSP/BIOS Object Task_statistic can be used to determine the actual usage of stack, by reading the statistics at the end of thread before exiting. After observing the actual usage, the stack size can be adjusted. For detailed example, Refer to [ Ref: SPRU 432F DSP/BIOS User Guide, Chapter 4 Thread Scheduling ]

TSK_Stat statbuf; /* declare buffer */
TSK_stat(TSK_self(), &statbuf); /* call func to get status */
if (statbuf.used > (statbuf.attrs.stacksize * 9 / 10)) {
LOG_printf(&trace, "Over 90% of task's stack is in use.\n")
}

Wednesday, August 6, 2008

Hi

Hi There!
This is my first post, just to greet you all.
What is expected to come from this blog are embedded development tips, especially for TI DSP/BIOS. It has been my cup of tea for some years now and I feel like sharing some simple and helpful stuffs with you.
Have a nice day and see you again.
P.S. Don't forget to leave me comments or questions if you have any!