AN-1138: LINB DLL Programmer´s Guide
Introduction
This application note describes the library functions available in the LINBWSD.dll library. These functions can be used to create an USB-to-LIN downloader for integrated battery sensor devices. LINBWSD.dll uses Protocol 6 for Flash/EE memory programming via LIN. Protocol 6 is explained in detail in Application Note AN-946. LINBWSD.dll can be used for LIN programming with the following IBS devices:
Disclaimer
All LINBWSD library code provided by Analog Devices, Inc., including this file, is provided as is without warranty of any kind, either expressed or implied. Users assume all risk from the use of this code. It is the responsibility of the user integrating this code into an application to ensure that the resulting application performs as required and is safe.
Hardware Setup
Downloader Jumper Settings
The downloader board allows two interfaces to be connected, LIN and I2C. The LIN functionality of the interface is determined by the on-board jumper connections, J5 and J6, as shown in Figure 2.
Download Sequence
LINBWSD.dll contains a security sequencer to prevent corruption of the Flash. The normal download sequence using the DLL functions follows:
- OpenDongle();
- GetDongleStatus();
- ReadDongleIdent();
- AssignNAD();
- If no default, NAD should be used
- InitLINkernel();
- ImportHexData();
- GetImportInfo();
- DoPageErase();
- Number of pages get by GetImportInfo();
- DoDataWrite();
- Number of bytes get by GetImportInfo();
- DoWriteCRC();
- DoResetKernel();
- Used if necessary
- CloseDongle();
- If no more CPUs to be programmed
- ReadByIdentifier();
GetDLLInfo
Getting the DLL version information.
void GetDLLInfo (char *pcDLLInfo, BYTE *pusStringLen)
Parameters
Parameter | Description |
*pcDLLInfo | Pointer to a char buffer that contains the version information from the DLL |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
Return Value
There is no return value.
Remark
It is necessary that an application close the opened USB port before closing the application. If an error occurs, the DLL opens a MessageBox.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); GetDLLInfo(pMessage,&usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); MessageBox(strMessage);
OpenDongle
Opening USB port and looking for LIN-Dongle.
BYTE OpenDongle (char *pcOpenPortError, BYTE *pusStringLen)
Parameters
Parameter | Description |
*pcOpenPortError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
Return Value
The return values for OpenDongle are as follows:
- 0 = no error.
- 1 = error during opening of USB port or no LIN-Dongle connected.
Remark
If the application tries to open an already open port, the DLL ignores the command.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = OpenDongle(pMessage,&usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }
CloseDongle
Close USB port.
BYTE CloseDongle()
Parameters
There are no parameters.
Return Value
The return values for CloseDongle are as follows:
- 0 = no error.
- 1 = error during closing of USB port.
Remark
It is necessary that the application close the open USB port before closing the application. If an error occurs, the DLL opens a MessageBox.
Example
BYTE usResult; usResult = closeDongle();
GetDongleStatus
Starting dongle firmware, and testing hardware and software version from dongle.
BYTE GetDongleStatus (char *pcOpenPortError, BYTE *pusStringLen)
Parameters
Parameter | Description |
*pcOpenPortError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
Return Value
The return values for GetDongleStatus are as follows:
- 0 = no error.
- 1 = error during dongle initialization or wrong dongle.
Remark
There is no remark.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = GetDongleStatus(pMessage,&usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }
DoReadDongleIdent
Reading dongle firmware information.
BYTE DoReadDongleIdent (1, char *pcDongleIdent, BYTE *pusStringLen)
Parameters
Parameter | Description |
1 | First parameter must be 1 and should not be changed |
*pcDongleIdent | Pointer to a char buffer that contains the hardware and software information in ASCII from the dongle |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
Return Value
The return values for DoReadDongleIdent are as follows:
- 0 = no error.
- 1 = error during getting dongle information.
Remark
There is no remark.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = DoReadDongleIdent(1,pMessage,&usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) { MessageBox(strMessage); return }
InitLinKernel
Connecting to kernel and getting its identification.
BYTE InitLinKernel (char *pcLinInitError, BYTE *pusStringLen, BYTE *pusCPU_Ident)
Parameters
Parameter | Description |
*pcLinInitError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
*pusCPU_Ident | Pointer to a variable of type BYTE that receives the CPU variant |
Return Value
The return values for InitLinKernel are as follows:
- 0 = no error.
- 1 = error during initialization or no LIN-Dongle connected.
- 2 = detecting wrong CPU signature.
Remark
If GetDongleStatus() failed, the application should not use this function.
If the application does not use the default NAD, the AssignNAD() should call before InitLinKernel is called.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; BYTE usCPU_Ident; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = InitLinKernel(pMessage,&usStrLen,&usCPU_Ident); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) / / Error { MessageBox(strMessage); return; }
ImportHexData
Importing the file that should be programmed.
BYTE ImportHexData (char *cHexFilePath, char *pcImportError, BYTE *pusStringLen)
Parameters
Parameter | Description |
*cHexFilePath | The file path to the hex file |
*pcImportError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
Return Value
The return values for ImportHexData are as follows:
- 0 = no error.
- 1 = error during import.
Remark
The application should use GetImportInfo() to get information about the imported data for erase, program, and verify.
Example
char *pMessage; char szFileName[1024]; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = ImportHexData(szFileName ,pMessage, &usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }
GetImportInfo
Getting information about the imported file.
BYTE GetImportInfo (&ulEndAdr, &ulHexBytes, &ucMaxPages, &ulAdrOffset)
Parameters
Parameter | Description |
&ulEndAdr | Variable for the highest address in hex file |
&ulHexBytes | Variable for the number of bytes imported |
&ucMaxPages | Variable for the number of pages to erase |
&ulAdrOffset | Offset for programming (not necessary at the moment) |
Return Value
There is no return value.
Remark
There is no remark.
Example
char *pMessage; char szFileName[1024]; BYTE usStrLen; BYTE usResult; CString strMessage; unsigned long ulEndAdr, ulHexBytes, ulAdrOffset; BYTE ucMaxPages; pMessage = strMessage.GetBuffer(100); usResult = ImportHexData(szFileName ,pMessage, &usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; } else { GetImportInfo(&ulEndAdr, &ulHexBytes, &ucMaxPages, &ulAdrOffset); }
DoPageErase
Erase one single page.
BYTE DoPageErase (char *pcPageEraseError, BYTE *pusStringLen, BYTE *pusErasedPageNumber)
Parameters
Parameter | Description |
*pcPageEraseError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
*pusErasedPageNumber | Pointer to a variable of type BYTE that receives the number of pages that are erased |
Return Value
The return values for DoPageErase are as follows:
- 0 = no error.
- 1 = error during page erase.
- 2 = application tries to erase more pages than necessary.
Remark
usErasedPageNumber is always 1.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; BYTE ucPage = 0; do { pMessage = strMessage.GetBuffer(100); usResult = DoPageErase(pMessage, &usStrLen, &usErasedPageNumber); strMessage.ReleaseBuffer(); if(usResult == 1) { strMessage.SetAt(usStrLen,'\0'); MessageBox(strMessage); return; } if(usResult == 2) { MessageBox(„No more pages to erase“); ucPage = ucMaxPages; } ucPage ++; } while(ucPage<ucMaxPages); // ucMaxPage contains the value get by GetImportInfo()
DoDataWrite
Writing data to flash, and verifying the written data.
BYTE DoDataWrite (char *pcWriteDataError, BYTE *pusStringLen, BYTE *pusDataLen)
Parameters
Parameter | Description |
*pcWriteDataError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
*pusDataLen | Pointer to a variable of type BYTE that receives the number of bytes that are written |
Return Value
The return values for DoDataWrite are as follows:
- 0 = no error.
- 1 = error during data write.
Remark
If not all pages are erased, the application cannot write data.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; BYTE usDataLen; CString strMessage; unsigned long ulWrittenHexBytes = 0; do { pMessage = strMessage.GetBuffer(100); usResult = DoDataWrite(pMessage, &usStrLen, &usDataLen); strMessage.ReleaseBuffer(); if(usResult == 1) { strMessage.SetAt(usStrLen,'\0'); MessageBox(strMessage); return; } ulWrittenHexBytes += (unsigned long)usDataLen; } while(ulWrittenHexBytes < ulHexBytes); // ulHexBytes contains the value get by GetImportInfo()
DoWriteCRC
Writing checksum to 0x80014.
BYTE DoWriteCRC (char *pcWriteCRCError, BYTE *pusStringLen, usCRC_Val)
Parameters
Parameter | Description |
*pcWriteCRCError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
usCRC_Val | 0 = writing calculated value from hex import 1 = writing value for code development 2 = writing value from imported hex file |
Return Value
The return values for DoWriteCRC are as follows:
- 0 = no error.
- 1 = error during writing checksum.
Remark
If program and verify are not successful, the DLL blocks this function.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = DoWriteCRC(pMessage,&usStrLen, 1); // code development strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }
DoResetKernel
Reset of the CPU
BYTE DoResetKernel (char *pcResetKernelError, BYTE *pusStringLen)
Parameters
Parameter | Description |
*pcResetKernelError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
Return Value
The return values for DoResetKernel are as follows:
- 0 = no error.
- 1 = error during reset of kernel.
Remark
There is no remark.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = DoResetKernel(pMessage,&usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }
AssignNAD
Assigning a new NAD to the kernel.
BYTE AssignNAD (char *pcAssignNADError, BYTE *pusStringLen, BYTE usNewNAD)
Parameters
Parameter | Description |
*pcAssignNADError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
usNewNAD | New NAD |
Return Value
The return values for AssignNAD are as follows:
- 0 = no error.
- 1 = error during assignment of NAD.
Remark
There is no remark.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = AssignNAD(pMessage,&usStrLen); strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }
ReadByIdentifier
Reading the identifiers.
BYTE ReadByIdentifier (char *pcRBIError, BYTE *pusStringLen, BYTE usIdentifier)
Parameters
Parameter | Description |
*pcRBIError | Pointer to a char buffer that contains ASCII data |
*pusStringLen | Pointer to a variable of type BYTE that receives the length of the ASCII data |
usIdentifier | 0x0 0x32 0x33 0x34 |
Return Value
The return values for ReadByIdentifier are as follows:
- 0 = no error.
- 1 = error during read by identifier.
Remark
There is no remark.
Example
char *pMessage; BYTE usStrLen; BYTE usResult; CString strMessage; pMessage = strMessage.GetBuffer(100); usResult = ReadByIdentifier(pMessage,&usStrLen,0); // reading 0x0 strMessage.ReleaseBuffer(); strMessage.SetAt(usStrLen,'\0'); if(usResult != 0) // Error { MessageBox(strMessage); return; }