## Friday, December 11, 2009

### Protecting Flash Memory of a Fujitsu MCU

I had a requirement to protect flash memory of Fujitsu MB95F128JB MCU but I could not find any satisfactory hardware/software tool to protect it. Later, I conceived an idea to hack its .mhx file. After adding the following line before the last line of the .mhx file, it had been protected.
S104400001BA

Ref: http://en.wikipedia.org/wiki/SREC_%28file_format%29

## Saturday, October 10, 2009

### Multidrop network for RS232

I got a requirement to communicate one master device and eight slave devices. I intended to use RS485 half-duplex communication for this system but all devices happened to have only RS232 interfaces. RS232 communication is a sort of communication that is to be used for one-to-one system. There is no problem if only the master device transmits and all slaves are receiving. The problem is that transmit lines of the slaves cannot be disabled and so that they cannot connect to the same line. After analyzing the voltage signals, I have got an alternative solution to this problem. By adding a diode to the transmit line of each slave, I can use the system just like RS485 half-duplex communication. See the following figure for the hardware connection.

Updated: 2017 Sep 02

### UART/TTL-Serial network with single master and multiple slaves

If you are not using RS232 transceivers to change the physical signal voltages, the outputs of UARTs are still TTL level signals. In this case, you can connect multiple UARTs to a single master as follow.

## Friday, September 25, 2009

### CRC Calculation in VB and C

Just to share a few software modules that were written in Visual Basic 2005 and C for the calculation of CRC -Cyclic Redundancy Check.

### CRC Calculation in VB2005

The followings are the source code for various CRC calculations in VB2005. To make the calculation faster, they use CRC tables.

CRC Calculation - GitHub

An example usage for calculation of CRC16 CCITT is shown below.

Dim StrIn as String= "String to calculate CRC"
Dim CRCVal16 As UInt16 = 0
Dim crc As String
CRCVal16 = CRC16_CCITT.Calculate(StrIn)
crc = CRC16_CCITT.ToString(CRCVal16)


Initial value for CRC16 CCITT is 0xFFFF. The following example calculate CRC for Str1 and use that CRC value as initial value to calculate Str2.

CRCVal16 = CRC16_CCITT.Calculate(Str1)
CRCVal16 = CRC16_CCITT.Calculate(Str2, CRCVal16)
crc = CRC16_CCITT.ToString(CRCVal16)


### CRC Calculation in C

The followings are the source code for various CRC calculations in C. To save storage, they do not use CRC tables .

CRC Calculation - GitHub

An example usage for calculation of CRC16 CCITT is shown below.

#define STRLEN 4
char str[STRLEN]={0x01,0x01,0x00,0x0B};
unsigned char c[2];
unsigned int crc;
//Calculate CRC16 CCITT
crc=CRC16CCITT_InitialValue();
crc=CRC16CCITT_Calculate(str,STRLEN,crc);
CRC16CCITT_ToString(crc,c);
printf("CRC16 CCITT = %02X %02X \n",c[0],c[1]);


Online checksum calculator such as the following one may be useful to debug the code.

Online Checksum Calculator

## Tuesday, August 18, 2009

### SDCC - Small Device C Compiler

SDCC - Small Device C Compiler - is a free open source C compiler software for 8051 and a few other microcontrollers. Unlike SDCC, there are other popular commercially available compilers such as Keil that you can purchase. You can download a free evaluation version there but that trial version is limited to 2k byte code size. A good thing about SDCC is that you can get it for free at no cost. This post is just an overview of SDCC manual at http://sdcc.sourceforge.net/doc/sdccman.pdf. Writing and compiling of a few example C programs on Windows for 8051 are  also discussed.

Installing
Go to http://sdcc.sourceforge.net/ and download the setup program Run the setup program and follow the installation process.

Testing the SDCC Compiler
To test the installation of the compiler whether it is OK or not, go to command prompt and enter "sdcc -v". This should return sdcc's version number.

Example C Program
Type in the following example program using your favorite ASCII editor and save as led.c. This is an example C program for 8051 microcontroller to blink an LED connected to P3.4 pin.
#include<8052.h>
void main()
{
int i;
while(1)
{
P3_4=0;   //Output 0
for(i=0;i<30000;i++);  //delay loop
P3_4=1;   //Output 1
for(i=0;i<30000;i++);  //delay loop
}
}


Compiling and Getting Hex File
Go to the path where led.c is located and enter "sdcc led.c". If all goes well the compiler will link with the libraries and produce a led.ihx output file. You can enter "dir" to see if there is led.ihx file. After that, enter "packihx led.ihx>led.hex" to get the intel hex file that is suitable to download into your chip.

Projects with Multiple Source Files
SDCC can compile only ONE file at a time. Let us, for example, assume that you have a project containing the following file: main.c blink.c Type in the following example code in these files.
//File name: main.c
void main()
{
while(1)
{
toggle();
delay();
}
}


//File name: blink.c
#include <8052.h>
void toggle()
{
P3_4^=1;
}
void delay()
{
int i;
for(i=0;i<30000;i++); //delay loop
}


//File name: blink.h
void toggle();
void delay();


The files without main() function will need to be compiled separately with the commands: "sdcc -c blink.c". Then compile the source file containing the main() function and link the files together with the command- "sdcc main.c blink.rel". You will get main.ihx file and then you can get main.hex file as discussed before.

## Monday, March 16, 2009

### String and ASCII Code Conversion in VB 2005

We have written a customized class for various conversion between ASCII code and string that we need to use occasionally. The source code for the class can be downloaded A Visual Basic class to convert between hexadecimal, ascii, and text string on GitHub.
'Author: Yan Naing Aye
'WebSite: http://cool-emerald.blogspot.sg/
'Updated: 2009 April 24
'-----------------------------------------------------------------------------
Public Class ClsMyStr
Public Shared Function AsAsciiEncodedStr(ByVal CharString As String) As String
Dim outS As String = ""
Dim temp As String = ""
Dim i As Integer = 0
For i = 0 To CharString.Length - 1
temp = "00" & Hex(Asc(CharString(i)))
temp = Right(temp, 2)
outS = outS & temp
Next i
Return outS
End Function
Public Shared Function AsSpacedAsciiEncodedStr(ByVal CharString As String) As String
Dim outS As String = ""
Dim temp As String = ""
Dim i As Integer = 0
For i = 0 To CharString.Length - 1
temp = "00" & Hex(Asc(CharString(i)))
temp = Right(temp, 2)
outS = outS & temp & " "
Next i
Return outS
End Function
Public Shared Function AsAsciiDecodedStr(ByVal AsciiEncodedStr As String) As String
Dim outS As String = ""
Dim i As Integer = 0
Dim l As Integer = AsciiEncodedStr.Length - 2

If (AsciiEncodedStr.Length Mod 2) <> 0 Then
l -= 1
End If
For i = 0 To l Step 2
outS = outS & Chr(Val("&H" & AsciiEncodedStr.Substring(i, 2)))
Next i
Return outS
End Function
Public Shared Function GetAsciiEncodedStr(ByVal RawAsciiEncodedStr As String) As String
Dim i As Integer = 0
Dim c As String
Dim cmd As String = ""

For i = 0 To RawAsciiEncodedStr.Length - 1
c = RawAsciiEncodedStr(i)
If (Asc(c) >= &H30) AndAlso (Asc(c) <= &H39) Then
cmd = cmd & c
ElseIf (Asc(c) >= &H41) AndAlso (Asc(c) <= &H5A) Then
cmd = cmd & c
ElseIf (Asc(c) >= &H61) AndAlso (Asc(c) <= &H7A) Then
cmd = cmd & Chr(Asc(c) - &H20) 'change to upper case
Else
'MessageBox.Show("Got invalid character.")
End If
Next i
If cmd.Length < 2 Then
cmd = "0" & cmd
End If
Return cmd
End Function
Public Shared Function DoubleQuote() As String
Return ControlChars.Quote
End Function
Public Shared Function Byte2Text(ByVal byteArray() As Byte) As String
Dim str As String = BitConverter.ToString(byteArray)
Return str
End Function
Public Shared Function Byte2Str(ByVal byteArray() As Byte) As String
'Dim str As String = System.Text.Encoding.ASCII.GetString(byteArray)
Dim str As String = ""
For i As Integer = 0 To UBound(byteArray)
str &= Chr(byteArray(i))
Next
Return str
End Function
Public Shared Function Str2Byte(ByVal str As String) As Byte()
'Dim ba() As Byte = System.Text.Encoding.ASCII.GetBytes(str)
Dim ba() As Byte
Try
ReDim ba(str.Length - 1)
For i As Integer = 0 To UBound(ba)
ba(i) = Asc(str(i))
Next
Catch ex As Exception
ReDim ba(0)
ba(0) = 0
End Try
Return ba
End Function
Public Shared Function GetSignedDecimalText(ByVal RawStr As String) As String
Dim i As Integer = 0
Dim c As String
Dim cmd As String = ""

For i = 0 To RawStr.Length - 1
c = RawStr(i)
If (Asc(c) >= &H30) AndAlso (Asc(c) <= &H39) Then
cmd = cmd & c
ElseIf (Asc(c) = &H2D) Then
If cmd.Length = 0 Then
cmd = cmd & c
End If
Else
'MessageBox.Show("Got invalid character.")
End If
Next i
Return cmd
End Function
End Class



## Sunday, February 22, 2009

### Reading and Writing a File in VB 2005

We occasionally need to read or write a file in Visual Basic 2005. For an easy reference, we want to post a few code here. The following two examples of reading and writing a file are from this web site.

Dim objStreamReader As StreamReader
Dim strLine As String

'Pass the file path and the file name to the StreamReader constructor.

'Read the first line of text.

'Continue to read until you reach the end of the file.
Do While Not strLine Is Nothing
'Write the line to the Console window.
Console.WriteLine(strLine)

Loop

'Close the file.


Dim objStreamWriter As StreamWriter

'Pass the file path and the file name to the StreamWriter constructor.
objStreamWriter = New StreamWriter("C:\Testfile.txt")

'Write a line of text.
objStreamWriter.WriteLine("Hello World")
'Write a second line of text.
objStreamWriter.WriteLine("From the StreamWriter class")

'Close the file.
objStreamWriter.Close()


If an error occurs while processing the file, the current method might be exited before you have an opportunity to close the file. A Try ... Finally block can be used to avoid this problem.

Dim strLine As String
Dim sr As StreamReader = Nothing
Try
Finally
sr.Close()
End Try



Visual Basic 2005 has a new Using statement that can automatically release one or more IDisposable objects. Any exception will be reported to callers. If you want to catch exceptions, you need a complete Try ... Catch ... Finally block.

Dim strLine As String
End Using


Reading a text file can also be performed more easily by means of the new File.ReadAllText static method. For binary file, File.ReadAllBytes can be used.
Log File

We have written a class to write log files easily. Its source code can be seen and downloaded VB class for log file on GitHub.

'Author: Yan Naing Aye
'WebSite: http://cool-emerald.blogspot.sg/
'Updated: 2009 June 25
'-----------------------------------------------------------------------------
Imports System.IO
Public Class ClsLog
Private mEnableLog As Boolean = False
Private mLogFileDirectory As String = ""
Private mLogFilePath As String = ""
Private mLogFileLifeSpan As Integer = 0
Private mLogFileFirstName As String = "AppName"
Public Sub New()
mEnableLog = False
mLogFileDirectory = My.Application.Info.DirectoryPath
mLogFileLifeSpan = 0
mLogFileFirstName = My.Application.Info.AssemblyName
End Sub
Public Property LogFileLifeSpan() As Integer
Get
Return mLogFileLifeSpan
End Get
Set(ByVal value As Integer)
mLogFileLifeSpan = IIf(value >= 0, value, 0)
End Set
End Property
Public Property LogFileFirstName() As String
Get
Return mLogFileFirstName
End Get
Set(ByVal value As String)
mLogFileFirstName = value
End Set
End Property
Public Property LogEnable() As Boolean
Get
Return mEnableLog
End Get
Set(ByVal value As Boolean)
If value = True Then
If Directory.Exists(Me.LogFileDirectory) Then
mEnableLog = value
Else
mEnableLog = False
Throw New Exception("Invalid file directory.")
End If
Else
mEnableLog = value
End If
End Set
End Property
Public Property LogFileDirectory() As String
Get
Return mLogFileDirectory
End Get
Set(ByVal value As String)
value = Trim(value)
If Directory.Exists(value) Then
Dim i As Integer = value.Length - 1
If (((value(i)) = "\") OrElse ((value(i)) = "/")) Then
value = value.Substring(0, i)
End If
mLogFileDirectory = value
Else
Throw New Exception("Invalid file directory.")
End If
End Set
End Property
Public ReadOnly Property LogFilePath() As String
Get
Return mLogFileDirectory & "\" & mLogFileFirstName & Format(Now, "-yyyy-MMM-dd") & ".log"
End Get
End Property
Public Sub WriteLog(ByVal LogEntry As String)
If mEnableLog = True Then
mLogFilePath = mLogFileDirectory & "\" & mLogFileFirstName & Format(Now, "-yyyy-MMM-dd") & ".log"
Dim objStreamWriter As StreamWriter = New StreamWriter(mLogFilePath, True)
Try
objStreamWriter.WriteLine(LogEntry)
Catch ex As Exception
Finally
objStreamWriter.Close()
End Try
End If
End Sub
Public Sub WriteTimeAndLog(ByVal LogEntry As String)
WriteLog(Now.ToLongTimeString & " " & LogEntry)
End Sub
Public Sub CleanupFiles()
If mLogFileLifeSpan > 0 Then 'if life span is zero, there will be no cleaning up
Try
Dim LogFiles() As String = Directory.GetFiles(mLogFileDirectory)
For Each LogFile As String In LogFiles
If (DateDiff("d", File.GetLastWriteTime(LogFile), Now) > mLogFileLifeSpan) _
AndAlso (Right(LogFile, 4) = ".log") Then
File.Delete(LogFile)
End If
Next
Catch ex As Exception
End Try
End If
End Sub
End Class



## Sunday, February 1, 2009

### FAT32 Format

I want to use my removable hard disk on both Windows and Linux machines. The problem was that Linux does not support NTFS and I could not format my disk to FAT32 in Windows XP. Using "format x: /fs:fat32" command ended in vain because it was larger than 32 GB. I also tried to format in Windows Vista but it still did not work in Linux. Later, I found a small and easy to use freeware program called fat32format.exe that can format large hard disks very fast. Just partition the drive, then type "fat32format X:" where X is the partition letter. Formatting a drive in FAT32 will allow it to be read by other operating systems, such as Mac, Linux, older versions of Windows, etc.

## Tuesday, January 20, 2009

### Using Notify Icon in Visual Basic 2005

To add notify icon to system tray is much easier in VB2005 than VB6. Create a new Windows Application in VB2005. Add NotifyIcon control as shown in the following figure.

Select "NotifyIcon1" control. In its properties window, choose "Icon" and open your icon to be used. If you do not define an icon there, you will not see notify icon in the system tray.
To display the notify icon when you close your application, go to code view and enter the following code to FormClosing event.

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If MessageBox.Show("Do you really want to exit?", "Exit", MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.No Then
e.Cancel = True
Me.Visible = False
NotifyIcon1.Visible = True
End If
End Sub


To display the application back when you double click the notify icon in the system tray, write the following code in MouseDoubleClick event of NotifyIcon1 control.

Private Sub NotifyIcon1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
Me.Visible = True ' Show the form.
Me.Activate() ' Activate the form.
NotifyIcon1.Visible = False
End Sub


Then add the code 'Me.Close()' to their click event so that it becomes ...

Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
' Close the form, which closes the application.
Me.Close()
End Sub


Private Sub ContextMenuStrip1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ContextMenuStrip1.Click
Me.Close()
End Sub


Select NotifyIcon1 control and define the ContextMenuStrip1 control in its ContestMenuStrip property so that the pop up menu will appear when you right click on the notify icon.

After that you can run the program. When you close the window, a message box will appear to confirm that you really want to exit. If you choose "No", the application will remain in the system tray on which you can double click to call back the application.

## Sunday, January 18, 2009

### Capturing and Sending Key -Using AJAX

AJAX is not a new programming language, but a technique for creating better, faster, and more interactive web applications. By using the key object -XMLHttpRequest of AJAX, we can create a dynamic webpage which can make a request and get a response from web server in the background without reloading the page. The user may not even notice that it is communicating invisibly.
Let us discuss an example that captures and sends the key input using AJAX. This example is based on the one that can be found in W3Schools site. There will be three files- keyCapture.html, keyCapture.js, and keyCapture.php.
First, we will create an HTML page called "keyCapture.html" that have a DIV element to display the message returned by the server. All JavaScript will be put in a separate file.

<html><head>    <title>Key Capture</title>    <script src='keyCapture.js'></script></head><body><form>Press a key to send to server.<div id='text1' style="font-size: 40px; color:blue;"> </div></form></body></html>

Second, the JavaScript file called "keyCapture.js" is created to capture keyboard input and send to the server using AJAX. It is explained in details.

var xmlHttp;
document.onkeypress = DisplayMsg;
function DisplayMsg(key_event) {
var keyChar;
if (document.all) {
keyChar = String.fromCharCode(event.keyCode);
}
else if (document.getElementById) {
keyChar = String.fromCharCode(key_event.which);
}
else if (document.layers) {
keyChar = String.fromCharCode(key_event.which);
}
xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
return;
}
var url = "keyCapture.php";
url = url + "?keyC=" + keyChar + "&sid=" + Math.random();
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function stateChanged() {
document.getElementById('text1').innerHTML = xmlHttp.responseText;
}
}
function GetXmlHttpObject() {
var xmlHttp = null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}


There are three main parts in this JavaScript file.
1. Creating XMLHttpRequest object
2. To define a function to handle the data returned by the server
3. To send off a request to the server

1. Creating XMLHttpRequest object
Depending on browser, the method for creating XMLHttpRequest object can be different. ActiveXObject is used in Internet Explorer and XMLHttpRequest JavaScript object is used in other browsers. The following JavaScript function can be used to deal with different browsers.
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}


In the function that wants to use the XMLHttpRequest object, we can just call this GetXmlHttpObject() function as
var xmlHttp
xmlHttp=GetXmlHttpObject();


If the object cannot be created, we can alert a message that AJAX is not supported.

if (xmlHttp==null)
{
return;
}


2. To define a function to handle the data returned by the server
The following JavaScript define a function that will be called when the server response status has changed. The readyState property has five possible values (from 0 to 4) and it checks for request complete state (state value 4) before it process the response.

function stateChanged() { if (xmlHttp.readyState==4){ document.getElementById("txtHint").innerHTML=xmlHttp.responseText;}}

When the server response status has changed, the function stored in onreadystatechange property will be called automatically. It must be defined in the function that initiates the XMLHttpRequest as
xmlHttp.onreadystatechange=stateChanged;

3. To send off a request to the server
When we submit a request using "GET" method, the ids of the fields and values of that fields are sent in the url e.g.,
var url = "keyCapture.php";url = url + "?keyC=" + keyChar + "&sid=" + Math.random();
xmlHttp.open("GET", url, true);xmlHttp.send(null);