Thursday, December 19, 2013

kendo dataviz + PhoneGap + Scrolling + Windows Phone 8

The Kendo chart graph whose content is longer than its container DIV does not have scrollbar in Windows Phone 8. In contrast, it works beautifully in iOS and Android.
 <div class="chart_container" >  
           <div class="report_chart_placeholder" ></div>  
      </div>  

The graph component is built on report_chart_placeholder. Its minimum height / height is set. Overflow properties are also set correctly for chart_container. However, no scrollbar appears when the chart is higher than chart_container. Solution :
   
           <div class="chart_container" >  
           <div class="report_chart_placeholder_overlay" ></div>  
           <div class="report_chart_placeholder" ></div>  
      </div>  

I needed to use absolute position to place on top of the chart another DIV (report_chart_placeholder_overlay) with same height properties of the chart. Then the scrollbar shows up properly.

Tuesday, October 1, 2013

Symmetricds Cookies support

My problem : we need cookies support for SymmetricDS client in order to authenticate against central SymmetricDS.
Solution :
Create an extension point class
 package com.synch.extension;  
 import java.net.CookieHandler;  
 import java.net.CookieManager;  
 import java.net.CookiePolicy;  
 import org.jumpmind.extension.IExtensionPoint;  
 import org.slf4j.Logger;  
 import org.slf4j.LoggerFactory;  
 public class CookieManagerConf implements IExtensionPoint{  
      protected final Logger log = LoggerFactory.getLogger(getClass());  
      public CookieManagerConf() {  
           System.out.println("Cookie manager initialized ------------------------>");  
           log.info("Cookie manager initialized ---------------------->");  
           CookieManager manager = new CookieManager(null,CookiePolicy.ACCEPT_ALL);  
           CookieHandler.setDefault(manager);  
      }  
 }  

Create extension XML in {classpath}\conf\symmetric-extensions.xml as follow :
 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xmlns:lang="http://www.springframework.org/schema/lang"  
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
             http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd" default-lazy-init="true">  
      <bean id="cookieManager" class="com.synch.extension.CookieManagerConf">  
      </bean>  
 </beans>  

Kalman filter with dspic33f : fixed point vs floating point speed comparison

Initially, I implemented Kalman filter for Microchip dspic33f MPU with floating point arithmetic calculations(mainly 2x2 float matrices) to measure inclination angle. The filter works brilliantly. However, I knew that fixed point calculation can greatly speed up the floating point Kalman filter. Hence, I decided to implement my Kalman filter in Q16 format. After that, I compared speed of 2 algorithms by using an oscilloscope. The output pin is set at the beginning and cleared at the end of the Kalman process.
Floating point Kalman filter :

Fixed point Kalman filter :

From above pictures, the fixed Kalman filter uses only ~46% time taken by floating point Kalman filter. Note : My dspic33f runs at 80 MHz.

Sunday, September 29, 2013

Enable fixed point math function for Microchip MPLABX IDE

I have had hard time to enable fixed point capability for MPLABX project. So I decided to document my solution here : 1. Using .
 #include <libq.h>  
2. Step 2 is adding those libs to libraries folder of the project as follow:
libq-coff.a
libq-dsp-coff.a
libq-dsp-elf.a
libq-elf.a 3. Step 3 : right-click project --> Properties. Modify configuration as follow:
Press Apply and OK. 4. Clean and rebuild project.
Edit : If the path of lib files contains spaces, build error will happen. Therefore, we can copy those lib files to another folder (without spaces in path) and include them in our project.

Friday, July 12, 2013

HTMLUnit & Vaadin Testing

I have been trying to use HTMLUnit to automate Vaadin application testing. Here are list of little tricks that I have figured out:
1. debugId for Vaadin component need to be set such as
Button :
saveButton.setDebugId("DenormalizedProductFilterForm_save");
Select :
sl_fetchSize.setDebugId("DenormalizedProductFilterForm_sl_fetchSize");
2. We need to use waitForBackgroundJavaScriptStartingBefore method to wait for DOM components .
3. Sometimes, click() does not do the job. We need to use {e.click(); e.mouseDown(); e.mouseUp();} or {div.dblClick();} to simulate click.
Sample code
 package com.wapice.epid.test;  
 import java.io.IOException;  
 import java.io.Serializable;  
 import java.net.MalformedURLException;  
 import java.util.logging.Level;  
 import org.apache.commons.logging.LogFactory;  
 import org.junit.Before;  
 import org.junit.Test;  
 import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;  
 import com.gargoylesoftware.htmlunit.WebClient;  
 import com.gargoylesoftware.htmlunit.html.HtmlDivision;  
 import com.gargoylesoftware.htmlunit.html.HtmlElement;  
 import com.gargoylesoftware.htmlunit.html.HtmlForm;  
 import com.gargoylesoftware.htmlunit.html.HtmlPage;  
 import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;  
 import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;  
 import com.gargoylesoftware.htmlunit.html.HtmlTextInput;  
 public class TestSearchProduct implements Serializable {  
      /**  
       *   
       */  
      private static final long serialVersionUID = 1L;  
      @Before  
      public void before() {  
           LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log",  
                     "org.apache.commons.logging.impl.NoOpLog");  
           java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit")  
                     .setLevel(Level.OFF);  
           java.util.logging.Logger.getLogger("org.apache.commons.httpclient")  
                     .setLevel(Level.OFF);  
      }  
      public void testWithStress() {  
      }  
      @Test  
      public void test() {  
           final WebClient webClient = new WebClient();  
           webClient.getOptions().setThrowExceptionOnScriptError(false);  
           webClient.getOptions().setCssEnabled(true);  
           webClient.getOptions().setJavaScriptEnabled(true);  
           HtmlPage page;  
           try {  
                System.out.println("Starting test");  
                page = webClient  
                          .getPage("http://localhost:1123/someapp/application/");  
                // login  
                {  
                     HtmlForm form = page.getFormByName("loginform");  
                     HtmlSubmitInput button = form.getInputByName("submitButton");  
                     HtmlTextInput userName = form.getInputByName("j_username");  
                     userName.setValueAttribute("jaacco");  
                     HtmlPasswordInput password = form.getInputByName("j_password");  
                     password.setValueAttribute("jaacco");  
                     button.click();  
                }  
                // search for product  
                {  
                     page = webClient  
                               .getPage("http://localhost:1123/someapp/application/#listdenormalizedproductview");  
                     webClient.waitForBackgroundJavaScriptStartingBefore(5000);  
                     //select from Select  
                     {  
                          HtmlDivision div = page  
                                    .getHtmlElementById("DenormalizedProductFilterForm_sl_fetchSize");  
                          for (HtmlElement e : div.getElementsByTagName("div")) {  
                               e.click();  
                          }  
                          webClient.waitForBackgroundJavaScriptStartingBefore(1000);  
                          div = page.getHtmlElementById("VAADIN_COMBOBOX_OPTIONLIST");  
                          for (HtmlElement e : div.getElementsByTagName("td")) {  
                               if (e.asText().contains("200")) {  
                                    e.click();  
                                    e.mouseDown();  
                                    e.mouseUp();  
                                    break;  
                               }  
                          }  
                          webClient.waitForBackgroundJavaScriptStartingBefore(1000);  
                     }  
                     //click button  
                     {  
                          HtmlDivision div = page  
                                    .getHtmlElementById("DenormalizedProductFilterForm_save");  
                          div.dblClick();  
                     }  
                     webClient.waitForBackgroundJavaScriptStartingBefore(10000);  
                }  
           } catch (FailingHttpStatusCodeException e) {  
                e.printStackTrace();  
           } catch (MalformedURLException e) {  
                e.printStackTrace();  
           } catch (IOException e) {  
                e.printStackTrace();  
           }  
           webClient.closeAllWindows();  
      }  
 }  

Saturday, June 22, 2013

adis16209 : switch/change command delay

Recently, I have been doing testing for adis16209 sensor. I came across a strange problem when running this piece of code:
 write_spi(ROT_OUT);  
 //wait until we receive rot_out_value from SPI  
 uart_write(rot_out_value);  
 write_spi(YINCL_OUT);  
 //wait until we receive yincl_out_value from SPI  
 uart_write(yincl_out_value);  

The sensor returns false values for ROT_OUT and YINCL_OUT commands. I started to dig into the problem and came to a conclusion that if we want to change the command (For example from ROT_OUT to YINCL_OUT), we must do like this :
 //switch to ROT_OUT command  
 write_spi(ROT_OUT);  
 //small delay  
 delay_us(40);  
 write_spi(ROT_OUT);  
 //wait until we receive rot_out_value from SPI  
 uart_write(rot_out_value);  
 //switch to YINCL_OUT command  
 write_spi(YINCL_OUT);  
 //small delay  
 delay_us(40);  
 write_spi(YINCL_OUT);  
 //wait until we receive yincl_out_value from SPI  
 uart_write(yincl_out_value);  

Wednesday, June 19, 2013

TOMEE java.lang.OutOfMemoryError: PermGen space

In order to solve this annoying problem with PermGen space in TomEE (possibly Tomcat as well) when we try to run startup.bat:
- Create file with name setenv.bat in bin folder with content as follow :
set "CATALINA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=512m"

Friday, May 31, 2013

Installation Postgres service

The following script will install Postgres as a service in a specific port in Windows. The .bat file should be placed in the same folder as bin folder of Postgres
 @ECHO ON  
 REM The script sets environment variables helpful for PostgreSQL  
 @ECHO "%~dp0"  
 @SET PATH="%~dp0\bin";%PATH%  
 @SET PGDATA=%~dp0\data  
 @SET PGDATABASE=postgres  
 @SET PGUSER=postgres  
 @SET PGPORT=5439  
 @SET PGLOCALEDIR=%~dp0\share\locale  
 "%~dp0\bin\initdb" -U postgres -A trust   
 "%~dp0\bin\pg_ctl" -l logfile register -N Postgres_Service -o "-F -p %PGPORT%"  
 NET START Postgres_Service  

Monday, May 20, 2013

hibernate/JPA annotation for byte[] + blob in oracle + bytea in postgres

After reading this http://stackoverflow.com/questions/3677380/proper-hibernate-annotation-for-byte and try everything that I found over Internet .
Problem : I want to have a JPA/Hibernate annotation that stores byte[] as blob in Oracle and as bytea in postgres.
Answer there is no such annotation ! So annoying to be real !
It is a similar problem with boolean storage http://vthanhvinh.blogspot.fi/2013/05/orgpostgresqlutilpsqlexception-error.html. However, there is no annotation that can help in this case.
Luckily, we can override annotation mapping with xml file, my great discovery. I have a entity like this
 package com.wapice.example;  
 import javax.persistence.Column;  
 import javax.persistence.Entity;  
 import javax.persistence.Table;  
 import javax.persistence.TableGenerator;  
 @Entity  
 @Table(name ="SMMBINRESOURCE")  
 @TableGenerator(name = "BINRESOURCEID", table = "SMMID", pkColumnName = "SERIES", valueColumnName = "NEXTVAL", pkColumnValue = "BINRESOURCEID", initialValue = 0, allocationSize = 1)  
 public class BinaryResource extends ProjectSpecificObject<Long> {  
      private String _name;  
      private String _mimetype;  
      private byte[] _data;  
      // logged object fields  
      /**  
       *   
       */  
      private static final long serialVersionUID = 8989926469766677944L;  
      @Column(name="DATA",columnDefinition="BLOB")  
      public byte[] getData() {  
           return _data;  
      }  
      public void setData(byte[] data) {  
           _data = data;  
      }  
      @Column(name="NAME", columnDefinition="nvarchar2")  
      public String getName() {  
           return _name;  
      }  
      public void setName(String name) {  
           _name = name;  
      }  
      @Column(name="MIMETYPE", columnDefinition="nvarchar2")  
      public String getMimetype() {  
           return _mimetype;  
      }  
      public void setMimetype(String mimetype) {  
           _mimetype = mimetype;  
      }  
 }  

By using @Column(name="DATA",columnDefinition="BLOB") , it will work with Oracle and correctly map byte[] to blob. But that would not work with Postgres.
So I have a xml mapping file for postgres as follow:
 <?xml version="1.0" encoding="UTF-8" ?>  
 <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"  
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm    
 http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"  
   version="2.0">  
   <description>SMM extended mapping</description>  
   <package>entity</package>   
   <entity class="com.wartsila.smm.model.BinaryResource" name="SMMBINRESOURCE">      
     <table name="SMMBINRESOURCE"/>  
     <attributes>  
       <basic name="name">  
         <column name="NAME" length="100"/>  
       </basic>  
       <basic name="mimetype">  
            <column name="MIMETYPE"/>  
       </basic>  
       <basic name="data">  
             <column name="DATA" column-definition="bytea"/>  
       </basic>  
     </attributes>  
   </entity>  
 </entity-mappings>  
then I define Hibernate sessionFactory for Postgres SQL as :
 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
  xmlns:context="http://www.springframework.org/schema/context"  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
  xmlns:jee="http://www.springframework.org/schema/jee" xmlns:p="http://www.springframework.org/schema/p"  
  xsi:schemaLocation="  
  http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd  
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd  
  http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd  
  ">  
   <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
  <property name="dataSource">  
   <ref bean="smmDataSource" />  
  </property>  
  <!--   
  <property name="entityInterceptor">  
       <bean class="com.wartsila.smm.hibernate.interceptors.CutomEntityInterceptor"></bean>  
     </property>  
  -->  
  <property name="hibernateProperties">  
   <props>  
   <prop key="hibernate.connection.defaultNChar">true</prop>  
   <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>  
   <prop key="hibernate.show_sql">false</prop>  
   <prop key="hibernate.hbm2ddl.auto">validate</prop>  
   </props>  
  </property>  
  <property name="packagesToScan">  
       <list>  
         <value>com.wapice.example/value>  
       </list>  
     </property>  
     <property name="mappingResources">  
         <list>  
      <value>com/wapice/example/orm-postgres.xml</value>  
       </list>  
      </property>  
  </bean>  
 </beans>  

This will correctly map byte[] to bytea in Postgres. Moreover, as we can see BinaryResource extends from ProjectSpecificObject which is a @MappedSuperclass. But we do not need to re-define ProjectSpecificObject in xml mapping AGAIN. Therefore, in my opinion, this is quite nice solution.

Sunday, May 19, 2013

Keep sorting order in Vaadin table after clear container datasource / set new container datasource

When we reset the container datasource or clear the container datasource of the table, the sorting order of the table is reset.
The work around could be using
setSortAscending(!isSortAscending()); setSortAscending(isSortAscending()); setSortAscending(!isSortAscending());
to retain the sorting order settings like before the clear/reset of datasource.

Thursday, May 16, 2013

org.postgresql.util.PSQLException: ERROR: column "xxx" is of type smallint/integer/numeric but expression is of type boolean + Hibernate

I am implementing a synchronize solution between DB nodes : Oracle vs Postgres. Same J2EE web application will run on those 2 databases and a background process will synch those database with each other.
. One problem is Oracle stores boolean Hibernate mapping value as 1 or 0. In contrast, Postgres stores Hibernate boolean as 'y' or 'n' which is very annoying and troublesome when doing DB synch. So I would like to force Postgres to map Hibernate boolean type to numeric/integer/smallint by trying to implement a custom Dialect extends from PostgreSQLDialect. I tried to override
public String toBooleanValueString(boolean bool)
and register type mappings as well. But , sadly, after many trials , it seems that it does not work.
At the end, I needed to use the ugly solution by adding :
@Type(type="org.hibernate.type.NumericBooleanType")
to all boolean attributes in my mapped class. It is ugly because it adds dependency to Hibernate in my Model Project. However, I can live with it for now.
You may try to add columnDefinition="smallint" of JPA to mapped boolean atribute instead of using ugly @Type. However, to me, for several reasons, it is not an option.

Monday, April 29, 2013

Modbus RTU sample frame 8N1.

Recently, I have been working on modbus RTU for communication between ABB ACS800 (a type of motor drive) and dsPIC33FJ128mc. Finally, I made it to work.
However, during development time, I was trying to google for sample Modbus RTU frame, but I could not find a good source. Hence, after making it work, I decided to post it here:
Request frame : 1 3 0 101 0 1 148 21 (in DEC)

Respond frame : 0 1 3 2 52 22 47 74 0 (in DEC)

Wednesday, April 24, 2013

Oracle SET DEFINE OFF

I had a script that contains "&" characters and sqldeveloper constantly prompts me for input.
Solution found from https://forums.oracle.com/forums/thread.jspa?threadID=1032337 is just to simply call "SET DEFINE OFF;" at the beginning of the script.

Monday, April 22, 2013

Hibernate autocommit session + Transaction.

This feature is extremely dangerous If we are not aware of. For example:
Let's say I have a simple service method :
  @Transactional  
   public void addCompany(Company company) {  
       company.setName("Name_1");
       companyDAO.saveOrUpdate(company); 
       company.setName("Name_2");
   }  

companyDAO is using HibernateSupport to manage entities.
What do we expect the name of our company in the DB looks like ?
At first glimpse, one might just state : "Name_1" because we actually did not call DAO to save our entity.
However, that's might not be the case if autocommit feature of Hibernate session is ON (I think it is ON by default). Therefore:
companyDAO.saveOrUpdate(company); will attach company entity to current Hibernate session. And when transaction ends, Hibernate will try to commit session. As the result, name of target entity in DB is actually "Name_2". Suprise(or not) :) ! Transaction gives us great power, but great power comes great responsibility ;)

Thursday, April 11, 2013

Vaadin < 7.0.3 + TreeTable(or Table) + Context Menu ( Action Handler ) refreshing problem

Today, I had a tedious problem with Vaadin TreeTable's context menu. In addition, I do think that Table has similar problem as well.
Here is what I do :
1. Do addActionHandler(new Action.Handler() { ...}) to TreeTable.
2. After that, there is a button click event that triggers : removeAllActionHandlers();from TreeTable.
3. Lastly, I add new ActionHandler to TreeTable : addActionHandler(new Action.Handler() { ...})
I expected that context menus from Action.Handler created in step 3 will replace those context menus from step 1. However, that's not the case, context menu did not get updated/refreshed.
Although one ticket was submitted and marked as fixed in Vaadin's bug tracker : . It seems that I still need to force a refresh with refreshRowCache() to refresh context menu. However, refreshRowCache() has problems with generated columns of TreeTable that I can't use it. Moreover, refreshRowCache() is not such a good function to use according to Vaadin's document: "Note that calling this method is not cheap so avoid calling it unnecessarily" So I had a deeper look at the code :
  /**  
    * Removes all action handlers  
    */  
   public void removeAllActionHandlers() {  
     actionHandlers = null;  
     actionMapper = null;  
     // Assures the visual refresh. No need to reset the page buffer  
     // before as the content has not changed, only the action  
     // handlers.  
     refreshRenderedCells();  
   }  
The key problem lies in refreshRenderedCells function
  protected void refreshRenderedCells() {  
     ...  
     if (!isContentRefreshesEnabled) {  
       return;  
     }  
           ...  
  }  
Then I noticed isContentRefreshesEnabled is false. As a result, context menu was not updated properly:
  protected void enableContentRefreshing(boolean refreshContent) {  
     isContentRefreshesEnabled = true;  
     if (refreshContent) {  
       refreshRenderedCells();  
       // Ensure that client gets a response  
       markAsDirty();  
     }  
   }  
Voila, instead of calling refreshRowCache(), enableContentRefreshing(true) should be called to update the context menu.
1. Do addActionHandler(new Action.Handler() { ...}) to TreeTable.
2. After that, there is a button click event that trigger : removeAllActionHandlers();from TreeTable.
3. Add new ActionHandler to TreeTable : addActionHandler(new Action.Handler() { ...})
4. Call enableContentRefreshing(true)


I am not entirely sure if this is a bug, but at least it is my work-around for this problem.

Wednesday, April 10, 2013

ADIS16209 sensor & dspiC33FJ128MC802 & SPI

The task is my first hands-on experience with PIC programming(dspic33FJ). In my opinion, dspiC33FJ128MC802 is a powerful and flexible PIC since it has re-mappable I/Os. This particular feature has also imposed some difficulties for a PIC newbie like me.
So, here is the task : make ADIS16209 sensor work with dspiC33FJ128MC802 via SPI.
Connections:
PIN 6 <---> MOSI (Master out slave in)
PIN 7 <---> MISO (Master in slave out)
PIN 22 <---> CS (Chip select)
PIN 11 <---> CLK (Clock)

Biggest problem I have faced was setting correct clock edge and clock polarity for SPI.(I needed an oscilloscope to debug this)
Sample code that works :
 /*  
  * File:  main.c  
  *  
  * Created on February 9, 2010, 10:53 AM  
  */  
 #include <stdio.h>  
 #include <stdlib.h>  
 #include <p33Fxxxx.h>  
 _FOSCSEL(FNOSC_FRC);  
 _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);  
 _FWDT(FWDTEN_OFF);  
 _FICD(JTAGEN_OFF & ICS_PGD3);  
 short temp;  
 /*  
  *  
  */  
 void delay(void) {  
   long i = 5242;  
   while (i--)  
     ;  
 }  
 void Init_SPI(void) {  
   SPI1STATbits.SPIEN = 0; //Disable SPI1  
   _SPI1IE = 1;  
   _SPI1IF = 0;  
   //*******  
   SPI1CON1bits.MSTEN = 1;  
   SPI1CON1bits.MODE16 = 1;  
   SPI1CON1bits.PPRE = 0;  
   SPI1CON1bits.SPRE = 2;  
   SPI1CON1bits.CKE = 0;  
   SPI1CON1bits.CKP = 1;  
   SPI1CON1bits.SMP=0;  
   SPI1STATbits.SPIEN = 1;  
   _SPI1IF = 0;  
 }  
 void turnLEDDebugOFF() {  
   LATAbits.LATA0 = 0;  
 }  
 void __attribute__((__interrupt__, __auto_psv__)) _SPI1Interrupt(void) {  
   SPI1STATbits.SPIROV = 0;  
   temp = SPI1BUF;  
   temp&=0b0011111111111111; //mask out   
   _SPI1IF = 0;  
    LATBbits.LATB11 = 1; // raise the slave select line}  
 }  
 void write_SPI(short command) {  
   LATBbits.LATB11 = 0; // lower the slave select line  
   // temp = SPI1BUF; // dummy read of the SPI1BUF register to clear the SPIRBF flag  
   SPI1BUF = (command); // write the data out to the SPI peripheral  
  //  while (!SPI1STATbits.SPITBF);     // wait for the data to be sent out  
 //            
  // while (SPI1STATbits.SPIRBF);     // wait for the data to be sent out  
 //  
 }  
 int main(int argc, char** argv) {  
   RCONbits.SWDTEN = 0; /* Disable Watch Dog Timer*/  
   // Configure Oscillator to operate the device at 40Mhz  
   // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2  
   PLLFBD = 38; // M=154  
   CLKDIVbits.PLLPOST = 0; // N2=2  
   CLKDIVbits.PLLPRE = 0; // N1=10  
   OSCTUN = 0; // Tune the FRC  
   // Clock switching to incorporate PLL  
   __builtin_write_OSCCONH(0x01); // Initiate Clock Switch to Internal  
   // FRC with PLL (NOSC=0b001)  
   __builtin_write_OSCCONL(0x01); // Start clock switching  
   while (OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur  
   AD1PCFGL = 0xFFFF; // Pins to digital  
   LATAbits.LATA0 = 1;  
   TRISAbits.TRISA0 = 0;  
   TRISBbits.TRISB12 = 0; //output RB12  
   LATBbits.LATB12=0;  
   LATBbits.LATB12=1;  
   TRISBbits.TRISB3 = 1; //input RB3  
   RPINR20bits.SDI1R = 3; //SDI1 input is associated to pin RP3 (pin 7 of the dsPIC)  
   RPOR2bits.RP4R = 8; //remappable pin RP4 (pin 11 of the dsPIC) is associated to SCK1  
   RPOR1bits.RP2R = 7; //remappable pin RP2 (pin 6 of the dsPIC) is associated to SDO1  
  // RPOR5bits.RP11R = 9; //CS RP11  
   Init_SPI();  
   TRISBbits.TRISB3 = 1; //input RB3  
   TRISBbits.TRISB2 = 0; //output RB2  
   TRISBbits.TRISB4 = 0; //output RB4  
   TRISBbits.TRISB11 = 0; //output RB11  
   LATBbits.LATB11 = 1;  
   while (OSCCONbits.LOCK != 1) {  
   };  
   while (1) {  
     int i = 0;  
     for (i = 0; i < 255; i++) {  
       write_SPI(0x4A00); //read product identification  
       delay();  
     }  
   }  
   return (EXIT_SUCCESS);  
 }