{"id":1494,"date":"2014-11-22T22:11:47","date_gmt":"2014-11-22T22:11:47","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=1494"},"modified":"2015-01-22T14:32:25","modified_gmt":"2015-01-22T14:32:25","slug":"msp430f2013_i2c","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2014\/11\/msp430f2013_i2c\/","title":{"rendered":"msp430f2013 I2C frustrations"},"content":{"rendered":"<p><a href=\"http:\/\/41j.com\/blog\/wp-content\/uploads\/2014\/11\/display.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/41j.com\/blog\/wp-content\/uploads\/2014\/11\/display-1024x638.jpg\" alt=\"display\" width=\"700\" height=\"436\" class=\"aligncenter size-large wp-image-1495\" srcset=\"https:\/\/41j.com\/blog\/wp-content\/uploads\/2014\/11\/display-1024x638.jpg 1024w, https:\/\/41j.com\/blog\/wp-content\/uploads\/2014\/11\/display-300x187.jpg 300w, https:\/\/41j.com\/blog\/wp-content\/uploads\/2014\/11\/display.jpg 1280w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>UPDATE: See <a href=\"http:\/\/41j.com\/blog\/2014\/11\/msp430-with-st7032i-now-working\/\">this post<\/a> which shows how I finally got it working.<\/p>\n<p>I&#8217;ve been trying to get a ST7032i based display working with a msp430f2013 on a EZ430-F2013. Unfortunately without much success. After hours of debugging I discovered that the glass on the display was fractured&#8230; guess I&#8217;ll be ordering some more.<\/p>\n<p>Anyway, it did get as far as acknowledging my commands. And I found a working I2C sample. It was hidden pretty well on the TI site, I think in a zip called slac080l.zip. The file I was working from was msp430x20x3_usi_07.c. My hacked version is reproduced below, you can almost feel the frustration I&#8217;m sure (it&#8217;s an absolute mess). But it does work with the MSP430GCC compiler, and produce working I2C output.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/* --COPYRIGHT--,BSD_EX\r\n * Copyright (c) 2012, Texas Instruments Incorporated\r\n * All rights reserved.\r\n *\r\n * Redistribution and use in source and binary forms, with or without\r\n * modification, are permitted provided that the following conditions\r\n * are met:\r\n *\r\n * *  Redistributions of source code must retain the above copyright\r\n *    notice, this list of conditions and the following disclaimer.\r\n *\r\n * *  Redistributions in binary form must reproduce the above copyright\r\n *    notice, this list of conditions and the following disclaimer in the\r\n *    documentation and\/or other materials provided with the distribution.\r\n *\r\n * *  Neither the name of Texas Instruments Incorporated nor the names of\r\n *    its contributors may be used to endorse or promote products derived\r\n *    from this software without specific prior written permission.\r\n *\r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;\r\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r\n * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r\n * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r\n * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n *\r\n *******************************************************************************\r\n * \r\n *                       MSP430 CODE EXAMPLE DISCLAIMER\r\n *\r\n * MSP430 code examples are self-contained low-level programs that typically\r\n * demonstrate a single peripheral function or device feature in a highly\r\n * concise manner. For this the code may rely on the device's power-on default\r\n * register values and settings such as the clock configuration and care must\r\n * be taken when combining code from several examples to avoid potential side\r\n * effects. Also see www.ti.com\/grace for a GUI- and www.ti.com\/msp430ware\r\n * for an API functional library-approach to peripheral configuration.\r\n *\r\n * --\/COPYRIGHT--*\/\r\n\/\/******************************************************************************\r\n\/\/  MSP430F20xx Demo - I2C Master Transmitter, single byte\r\n\/\/\r\n\/\/  Description: I2C Master communicates with I2C Slave using\r\n\/\/  the USI. Master data is sent and increments from 0x00 with each transmitted\r\n\/\/  byte which is verified by the slave.\r\n\/\/  LED off for address or data Ack; LED on for address or data NAck.\r\n\/\/  ACLK = n\/a, MCLK = SMCLK = Calibrated 1MHz\r\n\/\/\r\n\/\/  ***THIS IS THE MASTER CODE***\r\n\/\/\r\n\/\/                  Slave                      Master\r\n\/\/          (msp430x20x3_usi_08.c)\r\n\/\/               MSP430F20x2\/3              MSP430F20x2\/3\r\n\/\/             -----------------          -----------------\r\n\/\/         \/|\\|              XIN|-    \/|\\|              XIN|-\r\n\/\/          | |                 |      | |                 |\r\n\/\/          --|RST          XOUT|-     --|RST          XOUT|-\r\n\/\/            |                 |        |                 |\r\n\/\/      LED &lt;-|P1.0             |        |                 |\r\n\/\/            |                 |        |             P1.0|-&gt; LED\r\n\/\/            |         SDA\/P1.7|&lt;-------|P1.7\/SDA         |\r\n\/\/            |         SCL\/P1.6|&lt;-------|P1.6\/SCL         |\r\n\/\/\r\n\/\/  Note: internal pull-ups are used in this example for SDA &amp; SCL\r\n\/\/\r\n\/\/  Z. Albus\r\n\/\/  Texas Instruments Inc.\r\n\/\/  May 2006\r\n\/\/  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A\r\n\/\/******************************************************************************\r\n#include &lt;msp430.h&gt;\r\n\r\n\r\n\/\/ commands\r\n#define LCD_CLEARDISPLAY 0x01\r\n#define LCD_RETURNHOME 0x02\r\n#define LCD_ENTRYMODESET 0x04\r\n#define LCD_DISPLAYCONTROL 0x08\r\n#define LCD_CURSORSHIFT 0x10\r\n#define LCD_FUNCTIONSET 0x20\r\n#define LCD_SETCGRAMADDR 0x40\r\n#define LCD_SETDDRAMADDR 0x80\r\n#define LCD_EX_SETBIASOSC 0x10 \/\/ Bias selection \/ Internal OSC frequency adjust\r\n#define LCD_EX_SETICONRAMADDR 0x40 \/\/ Set ICON RAM address\r\n#define LCD_EX_POWICONCONTRASTH 0x50 \/\/ Power \/ ICON control \/ Contrast set(high byte)\r\n#define LCD_EX_FOLLOWERCONTROL 0x60 \/\/ Follower control\r\n#define LCD_EX_CONTRASTSETL 0x70 \/\/ Contrast set(low byte)\r\n\/\/ flags for display entry mode\r\n#define LCD_ENTRYRIGHT 0x00\r\n#define LCD_ENTRYLEFT 0x02\r\n#define LCD_ENTRYSHIFTINCREMENT 0x01\r\n#define LCD_ENTRYSHIFTDECREMENT 0x00\r\n\/\/ flags for display on\/off control\r\n#define LCD_DISPLAYON 0x04\r\n#define LCD_DISPLAYOFF 0x00\r\n#define LCD_CURSORON 0x02\r\n#define LCD_CURSOROFF 0x00\r\n#define LCD_BLINKON 0x01\r\n#define LCD_BLINKOFF 0x00\r\n\/\/ flags for display\/cursor shift\r\n#define LCD_DISPLAYMOVE 0x08\r\n#define LCD_CURSORMOVE 0x00\r\n#define LCD_MOVERIGHT 0x04\r\n#define LCD_MOVELEFT 0x00\r\n\/\/ flags for function set\r\n#define LCD_8BITMODE 0x10\r\n#define LCD_4BITMODE 0x00\r\n#define LCD_2LINE 0x08\r\n#define LCD_1LINE 0x00\r\n#define LCD_5x10DOTS 0x04\r\n#define LCD_5x8DOTS 0x00\r\n#define LCD_EX_INSTRUCTION 0x01 \/\/ IS: instruction table select\r\n\/\/ flags for Bias selection\r\n#define LCD_BIAS_1_4 0x08 \/\/ bias will be 1\/4\r\n#define LCD_BIAS_1_5 0x00 \/\/ bias will be 1\/5\r\n\/\/ flags Power \/ ICON control \/ Contrast set(high byte)\r\n#define LCD_ICON_ON 0x08 \/\/ ICON display on\r\n#define LCD_ICON_OFF 0x00 \/\/ ICON display off\r\n#define LCD_BOOST_ON 0x04 \/\/ booster circuit is turn on\r\n#define LCD_BOOST_OFF 0x00 \/\/ booster circuit is turn off\r\n#define LCD_OSC_122HZ 0x00 \/\/ 122Hz@3.0V\r\n#define LCD_OSC_131HZ 0x01 \/\/ 131Hz@3.0V\r\n#define LCD_OSC_144HZ 0x02 \/\/ 144Hz@3.0V\r\n#define LCD_OSC_161HZ 0x03 \/\/ 161Hz@3.0V\r\n#define LCD_OSC_183HZ 0x04 \/\/ 183Hz@3.0V\r\n#define LCD_OSC_221HZ 0x05 \/\/ 221Hz@3.0V\r\n#define LCD_OSC_274HZ 0x06 \/\/ 274Hz@3.0V\r\n#define LCD_OSC_347HZ 0x07 \/\/ 347Hz@3.0V\r\n\/\/ flags Follower control\r\n#define LCD_FOLLOWER_ON 0x08 \/\/ internal follower circuit is turn on\r\n#define LCD_FOLLOWER_OFF 0x00 \/\/ internal follower circuit is turn off\r\n#define LCD_RAB_1_00 0x00 \/\/ 1+(Rb\/Ra)=1.00\r\n#define LCD_RAB_1_25 0x01 \/\/ 1+(Rb\/Ra)=1.25\r\n#define LCD_RAB_1_50 0x02 \/\/ 1+(Rb\/Ra)=1.50\r\n#define LCD_RAB_1_80 0x03 \/\/ 1+(Rb\/Ra)=1.80\r\n#define LCD_RAB_2_00 0x04 \/\/ 1+(Rb\/Ra)=2.00\r\n#define LCD_RAB_2_50 0x05 \/\/ 1+(Rb\/Ra)=2.50\r\n#define LCD_RAB_3_00 0x06 \/\/ 1+(Rb\/Ra)=3.00\r\n#define LCD_RAB_3_75 0x07 \/\/ 1+(Rb\/Ra)=3.75\r\n\r\n\r\n\r\nchar MST_Data = 0x40;                     \/\/ Variable for transmitted data\r\nchar SLV_Addr = 0x7C;                  \/\/ Address is 0x48 &lt;&lt; 1 bit + 0 for Write\r\nint I2C_State = 0;                     \/\/ State variable\r\n\r\nint main(void)\r\n{\r\n  volatile unsigned int i;             \/\/ Use volatile to prevent removal\r\n\r\n  WDTCTL = WDTPW + WDTHOLD;            \/\/ Stop watchdog\r\n                __delay_cycles(250000);\r\n  if (CALBC1_1MHZ==0xFF)\t\t\t   \/\/ If calibration constants erased\r\n  {\t\t\t\t\t\t\t\t\t\t\t\r\n    while(1);                          \/\/ do not load, trap CPU!!\t\r\n  }\r\n  DCOCTL = 0;                               \/\/ Select lowest DCOx and MODx settings\r\n  BCSCTL1 = CALBC1_1MHZ;               \/\/ Set DCO\r\n  DCOCTL = CALDCO_1MHZ;\r\n\r\n  P1OUT = 0xC0;                        \/\/ P1.6 &amp; P1.7 Pullups, others to 0\r\n  P1REN |= 0xC0;                       \/\/ P1.6 &amp; P1.7 Pullups\r\n  P1DIR = 0xFF;                        \/\/ Unused pins as outputs\r\n  P2OUT = 0;\r\n  P2DIR = 0xFF;\r\n\r\n  USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; \/\/ Port &amp; USI mode setup\r\n  USICTL1 = USII2C+USIIE;              \/\/ Enable I2C mode &amp; USI interrupt\r\n  USICKCTL = USIDIV_3+USISSEL_2+USICKPL; \/\/ Setup USI clocks: SCL = SMCLK\/8 (~125kHz) \/\/ was USIDIV_3\r\n  USICNT |= USIIFGCC;                  \/\/ Disable automatic clear control\r\n  USICTL0 &amp;= ~USISWRST;                \/\/ Enable USI\r\n  USICTL1 &amp;= ~USIIFG;                  \/\/ Clear pending flag\r\n  __enable_interrupt();\r\n\r\n  int a=0;\r\n  for(int n=0;;n++)\r\n  {\r\n    if(n==0) MST_Data = 0x00;\r\n    if(n==1) MST_Data = LCD_EX_SETBIASOSC | LCD_BIAS_1_5 | LCD_OSC_183HZ;\r\n    if(n==2) MST_Data = 0x00;\r\n    if(n==3) MST_Data = LCD_EX_FOLLOWERCONTROL | LCD_FOLLOWER_ON | LCD_RAB_2_00;\r\n    if(n==4) MST_Data = 0x00;\r\n    if(n==5) MST_Data = LCD_DISPLAYON | LCD_CURSORON | LCD_BLINKON;\r\n    if(n==6) MST_Data = 0x00;\r\n    if(n==7) MST_Data = LCD_ENTRYMODESET | LCD_ENTRYLEFT;\r\n\r\n    if(n==9) MST_Data = 0x00;\r\n    if(n==10) MST_Data = LCD_EX_CONTRASTSETL | (0x0c &amp; 0x0f);\r\n    if(n==11) MST_Data = 0x00;\r\n    if(n==12) MST_Data = LCD_EX_POWICONCONTRASTH | LCD_ICON_ON | LCD_BOOST_ON | ((0x0c &gt;&gt; 4) &amp; 0x03);\r\n    if(n==14) MST_Data = 0x00;\r\n    if(n==15) MST_Data = LCD_CLEARDISPLAY;\r\n    if(n==16) MST_Data = 0x00;\r\n    if(n==17) MST_Data = 0x40;\r\n    if(n==18) MST_Data = 'a'+a;\r\n    USICTL1 |= USIIFG;                 \/\/ Set flag and start communication\r\n    LPM0;                              \/\/ CPU off, await USI interrupt\r\n   \/\/ __no_operation();                  \/\/ Used for IAR\r\n\/\/    for (i = 0; i &lt; 5000; i++);        \/\/ Dummy delay between communication cycles\r\n    P1OUT &amp;= ~0x01;           \/\/ LED off\r\n    __delay_cycles(500000);\r\n    if(n==18)n=16;\r\n    a++;\r\n  }\r\n}\r\n\r\n\/******************************************************\r\n\/\/ USI interrupt service routine\r\n******************************************************\/\r\n#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)\r\n#pragma vector = USI_VECTOR\r\n__interrupt void USI_TXRX (void)\r\n#elif defined(__GNUC__)\r\nvoid __attribute__ ((interrupt(USI_VECTOR))) USI_TXRX (void)\r\n#else\r\n#error Compiler not supported!\r\n#endif\r\n{\r\n  switch(I2C_State)\r\n    {\r\n      case 0: \/\/ Generate Start Condition &amp; send address to slave\r\n              P1OUT &amp;= ~0x01;           \/\/ LED off\r\n              USISRL = 0x00;           \/\/ Generate Start Condition...\r\n              USICTL0 |= USIGE+USIOE;\r\n              USICTL0 &amp;= ~USIGE;\r\n              USISRL = SLV_Addr;       \/\/ ... and transmit address, R\/W = 0\r\n              USICNT = (USICNT &amp; 0xE0) + 0x08; \/\/ Bit counter = 8, TX Address\r\n              I2C_State = 2;           \/\/ Go to next state: receive address (N)Ack\r\n              break;\r\n\r\n      case 2: \/\/ Receive Address Ack\/Nack bit\r\n              USICTL0 &amp;= ~USIOE;       \/\/ SDA = input\r\n              USICNT |= 0x01;          \/\/ Bit counter = 1, receive (N)Ack bit\r\n              I2C_State = 4;           \/\/ Go to next state: check (N)Ack\r\n              break;\r\n\r\n      case 4: \/\/ Process Address Ack\/Nack &amp; handle data TX\r\n              USICTL0 |= USIOE;        \/\/ SDA = output\r\n              if (USISRL &amp; 0x01)       \/\/ If Nack received...\r\n              { \/\/ Send stop...\r\n                USISRL = 0x00;\r\n                USICNT |=  0x01;       \/\/ Bit counter = 1, SCL high, SDA low\r\n                I2C_State = 10;        \/\/ Go to next state: generate Stop\r\n              \/\/  P1OUT |= 0x01;         \/\/ Turn on LED: error\r\n                P1OUT |= 0x01;         \/\/ Turn on LED: error\r\n                __delay_cycles(5000000);\r\n              }\r\n              else\r\n              { \/\/ Ack received, TX data to slave...\r\n                USISRL = MST_Data;     \/\/ Load data byte\r\n                USICNT |=  0x08;       \/\/ Bit counter = 8, start TX\r\n                I2C_State = 6;         \/\/ Go to next state: receive data (N)Ack\r\n                P1OUT &amp;= ~0x01;        \/\/ Turn off LED\r\n              }\r\n              break;\r\n\r\n      case 6: \/\/ Receive Data Ack\/Nack bit\r\n              USICTL0 &amp;= ~USIOE;       \/\/ SDA = input\r\n              USICNT |= 0x01;          \/\/ Bit counter = 1, receive (N)Ack bit\r\n              I2C_State = 8;           \/\/ Go to next state: check (N)Ack\r\n              break;\r\n\r\n      case 8: \/\/ Process Data Ack\/Nack &amp; send Stop\r\n              USICTL0 |= USIOE;\r\n              if (USISRL &amp; 0x01)       \/\/ If Nack received...\r\n              ;\/\/  P1OUT |= 0x01;         \/\/ Turn on LED: error\r\n              else                     \/\/ Ack received\r\n              {\r\n                MST_Data++;            \/\/ Increment Master data\r\n              \/\/  P1OUT &amp;= ~0x01;        \/\/ Turn off LED\r\n              }\r\n              \/\/ Send stop...\r\n              USISRL = 0x00;\r\n              USICNT |=  0x01;         \/\/ Bit counter = 1, SCL high, SDA low\r\n              I2C_State = 10;          \/\/ Go to next state: generate Stop\r\n              break;\r\n\r\n      case 10:\/\/ Generate Stop Condition\r\n              USISRL = 0x0FF;          \/\/ USISRL = 1 to release SDA\r\n              USICTL0 |= USIGE;        \/\/ Transparent latch enabled\r\n              USICTL0 &amp;= ~(USIGE+USIOE);\/\/ Latch\/SDA output disabled\r\n              I2C_State = 0;           \/\/ Reset state machine for next transmission\r\n              LPM0_EXIT;               \/\/ Exit active for next transfer\r\n              break;\r\n    }\r\n\r\n  USICTL1 &amp;= ~USIIFG;                  \/\/ Clear pending flag\r\n}\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>UPDATE: See this post which shows how I finally got it working. I&#8217;ve been trying to get a ST7032i based display working with a msp430f2013 on a EZ430-F2013. Unfortunately without much success. After hours of debugging I discovered that the glass on the display was fractured&#8230; guess I&#8217;ll be ordering some more. Anyway, it did [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-1494","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-o6","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1494","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=1494"}],"version-history":[{"count":2,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1494\/revisions"}],"predecessor-version":[{"id":1992,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1494\/revisions\/1992"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=1494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=1494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=1494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}