Created
June 9, 2011 13:06
-
-
Save monsonite/1016694 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// File Name : c_msp_uni_05.c | |
// UNIO_memory , MSP430 family , C language , bit-bang method. | |
// Dependencies : msp430x12xx.h | |
// Processor : MSP430F1232 | |
// Hardware : MicroChip's UNIO EEPROM = 11XXX on Softbaugh EVB . | |
// Debug Module : MSP-FET430UIF - Texas Instruments | |
// I.D.E. : IAR | |
// Company : MicroChip Technology , Inc. | |
// Author : Alexandru Valeanu | |
//........................................................................... | |
// SOFTWARE LICENSE AGREEMENT | |
//........................................................................... | |
// "Microchip Technology Inc. (“Microchip”) licenses this software to you | |
// solely for use with Microchip Serial EEPROM products. | |
// The software is owned by Microchip and/or its licensors, and is protected | |
// under applicable copyright laws. All rights reserved. | |
// SOFTWARE IS PROVIDED “AS IS.” MICROCHIP AND ITS LICENSOR EXPRESSLY | |
// DISCLAIM ANY WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING | |
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS | |
// FOR A PARTICULAR PURPOSE,OR NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP | |
// AND ITS LICENSORS BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR | |
// CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, | |
// COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY | |
// CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE | |
// THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS." | |
//*************************************************************************** | |
// History : V1.0 - Initial Release | |
//........................................................................... | |
// File Description : This is the file for the AN1186 | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// HARDWARE CONDITIONS | |
// The 4 onboard LEDs display success & errror messages. | |
// In order to perform all of these, they were wired as below : | |
// P1.3 - D4 , P1.2 - D3 , P1.1 - D2 , P1.0 - D1 . | |
// The list of error messages is presented in the 'main' function. | |
// .......................................................................... | |
// The microcontroller is powered by the internal RC oscillator. | |
// In order to increase the communication speed, the micro was overclocked | |
// at a 10Mhz rate ( the datasheet of the MCU doesn't recommend to use | |
// a higher rate then 8 Mhz ). If a 8Mhz clock speed is desired, to obtain | |
// the necessary delays, delay functions must be changed accordingly . | |
// ( the initialization of the oscillator, too ). | |
// The RC oscillator is used in conjunction with an external resistor : | |
// R29 (on the E.V.B.) = 100K. It will also decrease the temperature | |
// drift, as described in the datasheet of the micro. | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
#include <msp430x12x2.h> | |
//............................................................................. | |
// GLOBAL CONSTANTS | |
//............................................................................. | |
#define DEVADR 0xa0 // slave address | |
#define START 0x55 // start header | |
#define READ 0x03 // READ instruction | |
#define CRRD 0x06 // READ from crt address instruction | |
#define WRITE 0x6c // WRITE instruction | |
#define WREN 0x96 // WRITE ENABLE instruction | |
#define WRDI 0x91 // WRITE DISABLE instruction | |
#define RDSR 0x05 // READ STATUS register instruction | |
#define WRSR 0x6e // WRITE STATUS REGISTER instruction | |
#define ERAL 0x6d // ERASE entire array instruction | |
#define SETAL 0x67 // SET entire array instruction | |
#define NOPROT 0x00 // disable all write protections | |
#define SCIO 0x01 // SCIO = P3.0 | |
#define STRSZ 0x10 // size of string = 16 bytes | |
#define timeout 0x14 // timeout at sampling SAK/NOSAK | |
//............................................................................. | |
// Timer based delays are more accurate, accordingly, a higher communication | |
// speed was obtained through this method. As an alternative, instructions | |
// based delays are presented below, too. | |
//............................................................................. | |
#define QBT 0xa0 // quarter bit(timer) --> 12 Khz | |
// #define QBT 0x90 | |
// #define QBT 0x80 | |
// #define QBT 0x70 | |
// #define QBT 0x60 // quarter bit(timer) --> 25 Khz | |
// #define QBT 0x50 | |
// #define QBT 0x40 // 32Khz | |
//............................................................................. | |
// #define QBT 0x3c // 35khz | |
// #define QBT 0x3a // 37khz | |
// #define QBT 0x38 // 38khz | |
// #define QBT 0x34 // 40khz | |
// #define QBT 0x32 // 42khz | |
//............................................................................. | |
// #define QBT 0x30 // 44khz | |
//............................................................................. | |
// #define QBT 0x2e // 45Khz | |
// #define QBT 0x2c // 47khz | |
// #define QBT 0x2a // 50khz | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
#define QBI 0x20 // quarter bit(instr) (32:2us)=16us MAX | |
// #define QBI 0x12 // quarter bit(instr) (18:2us)=09us MED | |
// #define QBI 0x10 // 16:2us = 08us / speed = 23Khz | |
// #define QBI 0x0d // 14:2us = 07us / speed = 29Khz | |
// #define QBI 0x0c // 12:2us = 06us / speed = 32Khz | |
//.............................................................................. | |
// #define QBI 0x0b // 11:2us = 5.5us / speed = 33khz | |
//.............................................................................. | |
// #define QBI 0x0a // 10:2us = 05us / speed = 37Khz | |
// #define QBI 0x09 // 09:2us =4.5us / speed = 42Khz | |
// #define QBI 0x08 // quarter bit(instr) (08:2us)=04us | |
// #define QBI 0x05 // quarter bit(instr) (05:2us)=02us | |
// #define QBI 0x04 // | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// GLOBAL VARIABLES | |
//............................................................................. | |
unsigned char err_cnt ; // error counter | |
unsigned char eep_buf ; // eeprom's data buffer | |
unsigned int tqb ; // calculated externally and loaded in | |
// timer_A as quarter bit | |
unsigned int thb ; // calculated externally and loaded in | |
// timer_A as half bit | |
unsigned int iqb ; // quarter bit through instructions | |
unsigned int ihb ; // half bit through instructions | |
unsigned char load[STRSZ] ; // global string for "copystr" function | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// FUNCTIONS PROTOTYPES | |
//.............................................................................. | |
void ini_wdt(void);void ini_rosc(void);void ini_gpio(void);void ini_tim(void); | |
void mak(void);void nomak(void);void sak(void);void sakq(void);void nosak(void); | |
void uni_wr(void);unsigned char uni_rdq(void);void uni_wrmns(void); | |
void uni_wrms(unsigned char ms);void uni_wrnms(unsigned char nms); | |
void uni_head(void) ; void uni_head2(void) ; | |
void uni_cmnd(unsigned char cmnd) ; void uni_cmnd2(unsigned char cmnd) ; | |
void uni_eral(void);void uni_eral2(void);void uni_setal(void);void uni_setal2(void); | |
void uni_wrsr(unsigned char stat) ; void ini_unio(void) ; void uni_wippol(void); | |
unsigned char uni_rdsr(void) ; | |
void uni_wrbyte(unsigned int eep_adr,unsigned char eep_data); | |
void uni_rdbyte(unsigned int eep_adr,unsigned char *dst); | |
void uni_crrdbyte(unsigned char *dst); | |
void uni_wrstr(unsigned char *source,unsigned int eep_adr,unsigned char lofsstr); | |
void uni_rdstr(unsigned char *dest,unsigned int eep_adr,unsigned char lofdstr); | |
void uni_crrdstr(unsigned char *dest,unsigned char lofdstr); | |
void dltim(unsigned int steps); void dlins(unsigned int steps); | |
void calcdly(void); | |
void dlthb(void);void dltqb(void);void dlihb(void);void dliqb(void); | |
void dlythdr(void);void dlytss(void);void dlystby(void);void dly5ms(void); | |
void dly250ms(void);void dly1s(void);void ferror(void); | |
void copystr(unsigned char d[],unsigned char s[],unsigned char strsz); | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// INITIALIZATION FUNCTIONS | |
//.............................................................................. | |
void ini_wdt(void) | |
{ WDTCTL = WDTPW + WDTHOLD ; } // pswd + stop | |
//............................................................................. | |
void ini_rosc(void) | |
{ // internal RC oscillator | |
BCSCTL1 = 0xc7 ; // XTOFFF + XTS + RSEL=7(?) | |
DCOCTL = 0xe0 ; // DCO = 7 (max fqv) : Rext=100k (R29) | |
BCSCTL2 |= DCOR ; // choose external resistor | |
} // MCLK ~ 10Mhz (overclock) | |
//............................................................................. | |
void ini_tim(void) | |
{ | |
TACTL = TASSEL_2 + MC_0 ; // SMCLK + stop timer | |
CCTL1 &= ~CAP ; // compare mode | |
CCTL1 |=OUTMOD_1 ; // set mode | |
} | |
//............................................................................. | |
void ini_gpio(void) | |
{ | |
P1SEL = 0x00 ; // all GPIO | |
P1DIR = 0x0f ; // LEDs = out | |
P2SEL = 0x01 ; // P2.0 = out = ACLK | |
P2DIR = 0x01 ; // only for XTAL | |
P3SEL = 0x3e ; // P3.0 = SCIO = GPIO | |
P3OUT = 0x01 ; // P3.0 = 1 | |
P3DIR = 0x5b ; // P3.0 = OUT | |
P3OUT = 0x01 ; // P3.0 = 1 | |
} | |
// ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// UNIO CONTROL FUNCTIONS | |
//........................................................................ | |
void mak(void) | |
{ P3OUT &= ~SCIO ; // P3.0 = 0 | |
dlthb() ; // dly halfbit through timer | |
// dlihb() ; // dly halfbit through instructions | |
P3OUT |= SCIO ; // P3.0 = 1 | |
dlthb() ; // dly halfbit through timer | |
// dlihb() ; // dly halfbit through instructions | |
} | |
//........................................................................ | |
void nomak(void) | |
{ P3OUT |= SCIO ; // P3.0 = 1 | |
dlthb() ; // dly halfbit through timer | |
// dlihb() ; // dly halfbit through instructions | |
P3OUT &= ~SCIO ; // P3.0 = 0 | |
dlthb() ; // dly halfbit through timer | |
// dlihb() ; // dly halfbit through instructions | |
} | |
//......................................................................... | |
void sak(void) // SAK = 0 - 1 | |
{ unsigned char wait=timeout ; // init "wait" variable | |
// P3OUT |= SCIO ; // P3.0 = 1 | |
P3DIR = 0x5a ; // P3.0 = INPUT | |
while (P3IN&SCIO) // if SCIO = 1 | |
{ wait-- ; // decrement timeout variable | |
if(wait==0){ferror() ;} } // if timeout , final error | |
dlthb() ; dlthb() ; // wait a bit period | |
//dlihb() ; dlihb() ; // wait a bit period | |
if(!(P3IN&SCIO)) // no edge inside SAK | |
{ ferror() ; } // same error inside SAK | |
else | |
{ P3OUT |= SCIO ; // set P3.0 | |
P3DIR=0x5b ; } } // if no_error, P3.0=OUTPUT | |
//......................................................................... | |
void sakq(void) // sample : 1/4 bit + 3/4 bit(QB) | |
{ | |
//P3OUT |= SCIO // P3.0 = 1 | |
P3DIR = 0x5a ; // P3.0 = INPUT | |
dltqb() ; // wait quarter bit | |
//dliqb() ; // wait quarter bit | |
if(P3IN&SCIO){ferror();} // pin=1 at (1/4) bit, error | |
else { | |
dlthb() ; // wait half bit till 3/4 bit | |
//dlihb() ; // wait half bit till 3/4 bit | |
if(!(P3IN&SCIO)) // if pin=0 at (3/4) bit | |
{ ferror() ; } // error | |
else { | |
dltqb() ; // wait till the end of bit | |
//dliqb() ; // wait till the end of bit | |
P3DIR=0x5b ; } // restore pin as OUTPUT | |
} } | |
//......................................................................... | |
void nosak(void) | |
{ unsigned char wait=timeout ; // init wait variable | |
// P3OUT |= SCIO ; // P3.0 = 1 | |
P3DIR = 0x5a ; // P3.0 = INPUT | |
while(!(P3IN&SCIO)) // wait pin=1 | |
{ wait-- ; | |
if(wait==0){ferror(); } } // timeout, same errror as in SAK | |
dlthb() ; dlthb() ; // wait end of bit | |
// dlihb() ; dlihb() ; // wait end of bit | |
P3DIR = 0x5b ; } // restore pin as OUTPUT | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// SERIALIZATION FUNCTIONS | |
//......................................................................... | |
void uni_wr(void) // writes an 8b streaming | |
{ unsigned char bitmask = 0x80 ; // bit mask for the char | |
while(bitmask) // for 8 bits | |
{ if(eep_buf&bitmask) // if ( bit=1) | |
{ P3OUT &= ~SCIO ; // bit=1 --> 0-1 | |
dlthb() ; // pin=0 + hfbit delay | |
// dlihb() ; // pin=0 + hfbit delay | |
P3OUT |= SCIO ; // pin=1 | |
dlthb() ; // pin=1 + hfbit delay | |
// dlihb() ; // pin=1 + hfbit delay | |
} | |
else | |
{ P3OUT |= SCIO ; // bit=0 --> 1-0 | |
dlthb() ; // pin=1 + hfbit delay | |
// dlihb() ; // pin=1 + hfbit delay | |
P3OUT &= ~SCIO ; // pin=0 | |
dlthb() ; // pin=0 + hfbit delay | |
// dlihb() ; // pin=0 + hfbit delay | |
} | |
bitmask = bitmask >>1 ; } } // shift right mask for 8 bits | |
//.......................................................................... | |
unsigned char uni_rdq(void) // reads an 8b streaming | |
{ unsigned char bitmask = 0x80 ; // bit mask for the char | |
// P3OUT |=SCIO ; // P3.0 = 1 | |
P3DIR = 0x5a ; // SCIO = input | |
while(bitmask) // for 8 bits | |
{ | |
dltqb() ; // first smpl = (1/4) bit | |
// dliqb() ; // first smpl = (1/4) bit | |
if(!(P3IN&SCIO)) // if first sample=0 | |
{ | |
dlthb() ; // wait a half bit period | |
// dlihb() ; // wait a half bit period | |
if(!(P3IN&SCIO)) { ferror() ; } // if 2nd smpl=0, 0&&0->error | |
else { eep_buf|=bitmask ; } } // 0 && 1 => 1 | |
else | |
{ // if first smpl=1 | |
dlthb() ; // wait a half bit period | |
// dlihb() ; // wait a half bit period | |
if(P3IN&SCIO) { ferror() ; } // if 2nd smpl=1,1&&1->error | |
else { eep_buf &= ~bitmask ; } } // 1 && 0 => 0 | |
dltqb() ; | |
// dliqb() ; // final quarter bit delay | |
bitmask = bitmask >>1 ; } // shift right mask for 8 bits | |
P3DIR = 0x5b ; return eep_buf ; } // pin = out , return data buffer | |
//.............................................................................. | |
unsigned char uni_rd3q(void) // reads an 8b streaming | |
{ unsigned char bitmask = 0x80 ; // bit mask for the char | |
// P3OUT |=SCIO ; // P3.0 = 1 | |
P3DIR = 0x5a ; // SCIO = input | |
while(bitmask) // for 8 bits | |
{ | |
// dltqb() ; // delay (1/4) bit | |
dliqb() ; // first smpl = (1/4) bit | |
// dlthb() ; // wait a half bit period | |
dlihb() ; // wait a half bit period | |
if(!(P3IN&SCIO)) // sample at 3/4 bit | |
{ eep_buf &= ~bitmask ; } // if (3/4)bit = 0 --> bit = 0 | |
else { eep_buf|=bitmask ; } // if (3/4)bit = 1 --> bit = 1 | |
dliqb() ; // final quarter bit delay | |
bitmask = bitmask >>1 ; } // shift right mask for 8 bits | |
P3DIR = 0x5b ; return eep_buf ; } // pin = out , return data buffer | |
//.............................................................................. | |
void uni_wrmns(void) // write + MAK + NOSAK | |
{ eep_buf = START ; uni_wr() ; // stream out 'START' previously loaded | |
mak() ; nosak() ; } // master ACK + slave NOACK | |
//........................................................................... | |
void uni_wrms(unsigned char ms) // write + MAK + SAK | |
{ eep_buf = ms ; uni_wr() ; // stream out 'eep_buf' previously loaded | |
mak() ; // master ACK | |
sak() ; // slave ACK | |
// sakq() ; // slave ACK (quarter bit) | |
} | |
//........................................................................... | |
void uni_wrnms(unsigned char nms) // write + NOMAK + SAK | |
{ eep_buf = nms ; uni_wr() ; // stream out 'eep_buf' previously loaded | |
nomak() ; // master NOACK | |
sak() ; // slave ACK | |
// sakq() ; // slave ACK ( quarter bit ) | |
} | |
// ¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// UNIO HEADER FUNCTIONS | |
// ............................................................................ | |
void uni_head(void) // first time , after POR | |
{ | |
P3OUT &= ~SCIO ; // clear pin | |
dlythdr() ; // Thdr delay | |
P3OUT |= SCIO ; // set pin | |
dlystby() ; // Tstby delay | |
P3OUT &= ~SCIO ; // clear pin ( before START ) | |
dlythdr() ; } // Thdr | |
//.............................................................................. | |
void uni_head2(void) // for consecutive commands | |
{ P3OUT |= SCIO ; // set pin | |
dlytss() ; // Tss delay | |
P3OUT &= ~SCIO ; // clear pin ( before START ) | |
dlythdr() ; } // Thdr | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// UNIO COMMAND FUNCTIONS | |
//.............................................................................. | |
void uni_cmnd(unsigned char cmnd) // WREN , WRDI , ERAL , SETAL | |
{ uni_head() ; // perform the POR header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x04 ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x05 ; | |
uni_wrnms(cmnd) ; } // end with : wr(cmnd) + nomak + sak | |
//.............................................................................. | |
void uni_cmnd2(unsigned char cmnd) // WREN , WRDI , ERAL , SETAL | |
{ uni_head2() ; // perform the 2nd header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x04 ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x05 ; | |
uni_wrnms(cmnd) ; } // end with : wr(cmnd) + nomak + sak | |
//............................................................................... | |
void uni_eral(void) // erase entire array (00) | |
{ uni_cmnd(WREN) ; // ERAL needs WREN | |
uni_cmnd(ERAL) ; // ERAL command | |
dly5ms() ; dly5ms() ; } // ERAL/SETAL need 10ms Twc | |
// Not yet tested on this micro. For more details see the data sheet of the | |
// memory and the related app note (AN1184) - UNIO on 8051 + asm | |
//............................................................................... | |
void uni_eral2(void) // erase entire array(00)-consecutive cmnd | |
{ uni_cmnd2(WREN) ; // ERAL needs WREN | |
uni_cmnd2(ERAL) ; // ERAL command | |
dly5ms() ; dly5ms() ; } // ERAL/SETAL need 10ms Twc | |
// Not yet tested on this micro. For more details see the data sheet of the | |
// memory and the related app note (AN1184) - UNIO on 8051 + asm | |
//............................................................................... | |
void uni_setal(void) // set entire array (ff) | |
{ uni_cmnd(WREN) ; // SETAL needs WREN | |
uni_cmnd(SETAL) ; // SETAL command | |
dly5ms() ; dly5ms() ; } // ERAL/SETAL need 10ms Twc | |
// Not yet tested on this micro. For more details see the data sheet of the | |
// memory and the related app note (AN1184) - UNIO on 8051 + asm | |
//............................................................................... | |
void uni_setal2(void) // set entire array(ff)-consecutive cmnd | |
{ uni_cmnd2(WREN) ; // SETAL needs WREN | |
uni_cmnd2(SETAL) ; // SETAL command | |
dly5ms() ; dly5ms() ; } // ERAL/SETAL need 10ms Twc | |
// Not yet tested on this micro. For more details see the data sheet of the | |
// memory and the related app note (AN1184) - UNIO on 8051 + asm | |
//............................................................................... | |
void uni_wrsr(unsigned char stat) // write to status register (after POR) | |
{ uni_head() ; // perform the first header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x01 ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x02 ; | |
uni_wrms(WRSR) ; // wr(WRSR) + mak + sak | |
err_cnt = 0x03 ; | |
uni_wrnms(stat) ; // end with : wr + nomak + sak | |
dly5ms() ; } // 5msec = Twc | |
// The list of error messages is presented in the 'main' function. | |
//.............................................................................. | |
void ini_unio(void) | |
{ uni_wrsr(NOPROT) ; // write in status reg - NOPROT = 00 | |
} // disable all write protections | |
//.............................................................................. | |
unsigned char uni_rdsr(void) // read the status register | |
{ uni_head2() ; // (second) consecutive header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
uni_wrms(RDSR) ; // wr(RDSR) + mak + sak | |
uni_rdq() ; // eep_buf = status reg | |
// uni_rd3q() ; | |
nomak() ; // master NOACK | |
// sakq() ; // SAK with quarter bit sampling | |
sak() ; // SAK with normal sampling | |
return eep_buf ; } // return the result of uni_rdq | |
//.............................................................................. | |
void uni_wippol(void) // polling of WIP flag = bit0 of SR | |
{ while(uni_rdsr()&0x01) ; // wait the flag to be cleared by hw | |
} // may replace Twc | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// UNIO BYTE ACCESS FUNCTIONS | |
// The list of error messages is presented in the 'main' function. | |
//.............................................................................. | |
void uni_wrbyte(unsigned int eep_adr, unsigned char eep_data) | |
{ // writes a byte at the spec address | |
uni_cmnd2(WREN) ; // first, enable writes, consecutive cmnd | |
uni_head2() ; // 2nd header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x06 ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x07 ; | |
uni_wrms(WRITE) ; // wr(WRITE) + mak + sak | |
err_cnt = 0x08 ; | |
uni_wrms(eep_adr>>8) ; // wr(eep_adr>>) + mak + sak | |
uni_wrms(eep_adr&0xff) ; // wr(eep_adr&0xff) + mak + sak | |
err_cnt = 0x0a ; | |
uni_wrnms(eep_data) ; // wr(eep_data) + nomak + sak | |
dly5ms() ; // write cycle time after each byte | |
// uni_wippol() ; // pol WIP flag as Twc | |
} | |
//........................................................................... | |
void uni_rdbyte(unsigned int eep_adr, unsigned char *dst) | |
{ // reads a byte from the spec adr | |
uni_head2() ; // 2nd header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x0b ; | |
uni_wrms(DEVADR) ; // wr + mak + sak | |
err_cnt = 0x0c ; | |
uni_wrms(READ) ; // wr + mak + sak | |
err_cnt = 0x0d ; | |
uni_wrms(eep_adr>>8) ; // wr + mak + sak | |
uni_wrms(eep_adr&0xff) ; // wr + mak + sak | |
err_cnt = 0x0f ; | |
uni_rdq() ; // eep_buf = read data byte | |
// don't loose time storing now the result | |
// uni_rd3q() ; | |
nomak() ; // master noack | |
sak() ; // slave ack | |
// sakq() ; // slave ack ( quarter bit ) | |
*dst = eep_buf ; // store read byte in the end | |
} | |
//........................................................................... | |
void uni_crrdbyte(unsigned char *dst) | |
{ // reads a byte from the crt adr | |
uni_head2() ; // 2nd header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x0b ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x0c ; | |
uni_wrms(CRRD) ; // wr(CRRD) + mak + sak | |
err_cnt = 0x0f ; | |
uni_rdq() ; // eep_buf = read data byte | |
// don't loose time storing now the result | |
// uni_rd3q() ; | |
nomak() ; // master noack | |
sak() ; // slave ack | |
// sakq() ; // slave ack (quarter bit) | |
*dst = eep_buf ; // store read byte in the end | |
} | |
// Not yet tested on this micro. For more details see the data sheet of the | |
// memory and the related app note (AN1184) - UNIO on 8051 + asm | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// UNIO STRING ACCESS FUNCTIONS | |
//........................................................................... | |
void uni_wrstr(unsigned char *source,unsigned int eep_adr,unsigned char lofsstr) | |
// writes a string at the spec addr ; the length of the string(source) must be : | |
// lofsstr = [2 - 16] ; for single byte strings use "uni_wrbyte" | |
{ | |
unsigned char k = 0 ; ; // init char counter inside the string | |
copystr(load,source,lofsstr) ; // bring inside the function the string | |
uni_cmnd2(WREN) ; // enable writes | |
uni_head2() ; // header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x06 ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x07 ; | |
uni_wrms(WRITE) ; // wr(WRITE) + mak + sak | |
err_cnt = 0x08 ; | |
uni_wrms(eep_adr>>8) ; // wr(eep_adr>>8) + mak + sak | |
uni_wrms(eep_adr&0xff) ; // wr(eep_adr&0xff) + mak + sak | |
err_cnt = 0x09 ; | |
while(k<lofsstr-1) // for (n-1) bytes | |
{ uni_wrms(load[k]) ; k++ ; } // wr(bytes) + mak + sak | |
err_cnt = 0x0a ; | |
uni_wrnms(load[k]) ; // wr(last byte) + nomak + sak | |
dly5ms() ; // final write cycle time | |
// uni_wippol() ; // polling WIP flag | |
} | |
//............................................................................. | |
void uni_rdstr(unsigned char *dest,unsigned int eep_adr,unsigned char lofdstr) | |
// reads a string from the spec addr ; the length of the destination string | |
// must be : lofdstr = [ 2 - 16 ] ; for single byte strings use "uni_rdbyte" | |
{ | |
unsigned char k = 0 ; ; // init char counter inside the string | |
uni_head2() ; // 2nd header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x0b ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x0c ; | |
uni_wrms(READ) ; // wr(READ) + mak + sak | |
err_cnt = 0x0d ; | |
uni_wrms(eep_adr>>8) ; // wr(eep_adr>>8) + mak + sak | |
uni_wrms(eep_adr&0xff) ; // wr + mak + sak | |
err_cnt = 0x0e ; | |
while(k<lofdstr-1) // for (n-1) bytes | |
{ | |
uni_rdq() ; // eep_buf = read bytes | |
// uni_rd3q() ; | |
// don't loose time now to store data | |
mak() ; // master ACK | |
sak() ; // slave ACK | |
// sakq() ; // slave ACK with quarter bit | |
load[k] = eep_buf ; k++ ; } // store locally data, incr counter | |
err_cnt = 0x0f ; | |
uni_rdq() ; // eep_buf = last read byte | |
// uni_rd3q() ; | |
nomak() ; // master NOACK | |
sak() ; // slave ACK | |
// sakq() ; // slave ACK , quarter bit | |
load[k] = eep_buf ; // store locally last byte | |
copystr(dest,load,lofdstr) ; // internal string(load)-->dest | |
} | |
//.............................................................................. | |
void uni_crrdstr(unsigned char *dest,unsigned char lofdstr) | |
// reads a string from the crt addr ; the length of the destination string | |
// must be : lofdstr = [ 2 - 16 ] ; for single byte strings use "uni_crrdbyte" | |
{ | |
unsigned char k = 0 ; // init char counter inside the string | |
uni_head2() ; // 2nd header of the protocol | |
uni_wrmns() ; // wr(START) + mak + nosak | |
err_cnt = 0x0b ; | |
uni_wrms(DEVADR) ; // wr(DEVADR) + mak + sak | |
err_cnt = 0x0c ; | |
uni_wrms(READ) ; // wr(READ) + mak + sak | |
err_cnt = 0x0e ; | |
while(k<lofdstr-1) // for (n-1) bytes | |
{ | |
uni_rdq() ; // eep_buf = read bytes | |
// uni_rdq() ; | |
// don't loose time now to store data | |
mak() ; // master ACK | |
sak() ; // slave ACK | |
// sakq() ; // slave ACK with quarter bit | |
load[k] = eep_buf ; k++ ; } // store locally data, incr counter | |
err_cnt = 0x0f ; | |
uni_rdq() ; // eep_buf = last read byte | |
// uni_rd3q() ; | |
nomak() ; // master NOACK | |
sak() ; // slave ACK | |
// sakq() ; // slave ACK , quarter bit | |
load[k] = eep_buf ; // store locally last byte | |
copystr(dest,load,lofdstr) ; // internal string(load)-->dest | |
} | |
// Not yet tested on this micro. For more details see the data sheet of the | |
// memory and the related app note (AN1184) - UNIO on 8051 + asm | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// UNIO AUXILIARY FUNCTIONS | |
//.............................................................................. | |
void dltim(unsigned int steps) | |
{ // delay through timer_A <10Mhz> | |
// offset=4us, step=0.1us | |
TACTL = MC_0 + TACLR ; // stop and clear timer | |
CCR1 = steps ; // load delay value | |
TACTL = TASSEL_2 + MC_2 ; // SMCLK + continous mode | |
while(!(CCTL1 & CCIFG)) ; // wait CCIFG | |
CCTL1 &= ~CCIFG ; // clear CCIFG | |
TACTL = TASSEL_2 + MC_0 ; // stop timer | |
} | |
//.............................................................................. | |
void dlins(unsigned int steps) | |
{ // delay through instructions | |
unsigned int k ; // offset=2us , step=0.5us | |
for(k=0;k<steps;k++) | |
{;} } | |
//............................................................................... | |
// CALCULATE global variables : tqb , thb , iqb , ihb . They must be calculated | |
// in a separate initialization function , in order to avoid loss of time | |
// inside delay functions. Derived from "dltim" & "dlins" functions, we will use | |
// dltqb(tqb) , dlthb(thb) , dliqb(iqb) , dlihb(ihb) functions. | |
// Moreover, we will avoid : dltim(tqb) , etc, because this call will also loose | |
// processing bandwidth. | |
// FORMULAS : ( don't forget that the timer delay has a 4us offset (40steps<0.1us>) | |
// and instruction based delay has a 2us offset (4steps<0.5us>) ) | |
//................................................................................ | |
//dltqb(tqb) = QBT = 40steps(4us) + tqb | |
// tqb = QBT - 40steps(4us) | |
//dlthb(thb) = HBT = 40steps(4us) + thb = 2*QBT | |
// thb = 2*QBT - 40steps(4us) | |
//................................................................................ | |
//dliqb(iqb) = QBI = 04steps(2us) + iqb | |
// iqb = QBI - 04steps(2us) | |
//dlihb(ihb) = HBI = 04steps(2us) + ihb = 2*QBI | |
// ihb = 2*QBI - 04steps(2us) | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
void calcdly(void) // tqb , thb , iqb , ihb | |
{ | |
tqb = QBT - 40 ; // quarter bit ( timer ) | |
thb = 2*QBT - 40 ; // half bit ( timer ) | |
iqb = QBI - 4 ; // quarter bit ( instr ) | |
ihb = 2*QBI - 4 ; // half bit ( instr ) | |
} | |
//................................................................................. | |
void dlthb(void) | |
{ // delay HB through timer | |
// offset=4us, step=0.1us | |
TACTL = MC_0 + TACLR ; // stop and clear timer | |
CCR1 = thb ; // load delay value hf bit | |
TACTL = TASSEL_2 + MC_2 ; // SMCLK + continous mode | |
while(!(CCTL1 & CCIFG)) ; // wait CCIFG | |
CCTL1 &= ~CCIFG ; // clear CCIFG | |
TACTL = TASSEL_2 + MC_0 ; // stop timer | |
} | |
//.............................................................................. | |
void dltqb(void) | |
{ // delay QB through timer | |
// offset=4us, step=0.1us | |
TACTL = MC_0 + TACLR ; // stop and clear timer | |
CCR1 = tqb ; // load delay value hf bit | |
TACTL = TASSEL_2 + MC_2 ; // SMCLK + continous mode | |
while(!(CCTL1 & CCIFG)) ; // wait CCIFG | |
CCTL1 &= ~CCIFG ; // clear CCIFG | |
TACTL = TASSEL_2 + MC_0 ; // stop timer | |
} | |
//.............................................................................. | |
void dlihb(void) | |
{ // delay HB through instructions | |
unsigned int k ; // offset=2us , step=0.5us | |
for(k=0;k<ihb;k++) {;} } // | |
//............................................................................... | |
void dliqb(void) | |
{ // delay QB through instructions | |
unsigned int k ; // offset=2us , step=0.5us | |
for(k=0;k<iqb;k++) {;} } // | |
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
void dlythdr(void) // short low pulse before START | |
{ | |
dltim(100) ; // 100 timer steps = 10us | |
// dlins(20) ; // 20 instr steps = 10 us | |
} | |
//............................................................................... | |
void dlytss(void) // short high pulse for consecutive cmnds | |
// instead STBY | |
{ dltim(400) ; } // 400 timer steps = 40us | |
//............................................................................... | |
void dlystby(void) | |
{ dltim(8000) ; } // 8,000 timer steps = 800us(>600us) | |
//............................................................................... | |
void dly5ms(void) | |
{ dltim(50000) ; } // 50,000 timer steps = 5,000us = 5ms | |
//............................................................................... | |
void dly250ms(void) | |
{ unsigned char k = 50 ; // 50 * 5ms = 250 ms | |
while(--k) { dly5ms() ; } } // usefull for messages display | |
//............................................................................... | |
void dly1s(void) | |
{ dly250ms() ; dly250ms() ; | |
dly250ms() ; dly250ms() ; } // 4 * 250 ms = 1 sec | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
void ferror(void) // final error , for low level functions | |
{ | |
while(1) // flash infinetely | |
{ P1OUT = ~err_cnt ; dly1s() ; // LEDs active on "0" | |
P1OUT = 0xff ; dly1s() ; } } | |
//................................................................................ | |
void copystr(unsigned char d[],unsigned char s[],unsigned char strsz) | |
{ unsigned char n ; | |
for(n=0;n<strsz;n++) | |
{ d[n]=s[n] ; } } // copy source in destination | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// MAIN FUNCTION | |
//................................................................................ | |
// A 4 bits counter displayed on LEDs means that everything is OK : | |
// no errors in the low level functions, reads = writes. | |
// A 2Hz blinking (00-0f) means that the code didn't detect any error in low level | |
// functions, but reads <> writes. | |
// A 0.5Hz blinking ( 00 - 01, 00 - 02 , ... , 00 - 0f ) detects an error in | |
// a low level function . The related error_list is presented down the page. | |
void main(void) | |
{ | |
#define ADR0 0x0020 // initialization of the address | |
#define RND_MODE 0 // random byte access mode | |
#define PG_MODE 1 // page access mode | |
// .......................................................................... | |
unsigned char access_mode = RND_MODE ; // set the access mode to RAND | |
// unsigned char access_mode = PG_MODE ; // set the access mode to PAGE | |
unsigned int adr_cnt ; // address counter | |
unsigned char ch_cnt ; // character counter inside strings | |
unsigned char *src_str = "UNI_MSP_CCC_BB.C" ; | |
// source string which will be written | |
// UNI = UNIO protocol - MSP=MSP430 family | |
// CCC = "C" language , BB = bitbang meth | |
unsigned char dst_str[STRSZ]; // destination string,read from the eep | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// call all initialization routines | |
ini_wdt() ; // W.D.T.'s init | |
ini_rosc() ; // oscillator's init-RCosc-Rext=100k | |
ini_gpio() ; // GPIO's init | |
ini_tim() ; // Timers' init | |
calcdly() ; // calculates externally values of dlys | |
// do not loose time inside functions | |
//............................................................................ | |
// below, few test functions for delays (through instructions & timer) | |
// keep in mind that : main clock ~ 10Mhz ( overclock ) | |
// tqb = QBT - 40 / thb = 2*QBT - 40 (100ns resolution & 4us offset) | |
// iqb = QBI - 04 / ihb = 2*QBI - 04 (0.5us resolution & 2us offset) | |
// long delays are performed through timer_A | |
// short delays are performed through timer or instructions | |
// QBT_max = 0xa0 = 160 * 100ns ~ 16us ( bit > 64us [ < 015Khz ] ) | |
// QBT_min = 0x28 = 040 * 100ns ~ 04us ( bit > 16us [ < 060Khz ] ) | |
// QBI_max = 0x20 = 032 * 500ns ~ 16us ( bit > 64us [ < 015Khz ] ) | |
// QBI_min = 0x04 = 004 * 500ns ~ 02us ( bit > 08us [ < 125Khz ] ) | |
//............................................................................ | |
goto ini ; | |
// goto s1 ; // jmp to 1sec LEDs toggle | |
// goto ms250 ; // jmp to 0.25sec LEDs toggle | |
// goto tim ; // jmp to short delays through timer | |
// goto ins ; // jmp to short delays through instructions | |
// goto ms5 ; // jmp to 5msec delay through timer | |
s1: while(1) | |
{ P1OUT = 0x00 ; dly1s() ; // toggle LEDs at a rate | |
P1OUT = 0x0f ; dly1s() ; } // of 1 second | |
ms250: while(1) | |
{ P1OUT = 0x00 ; dly250ms() ; // toggle LEDs at a rate | |
P1OUT = 0x0f ; dly250ms() ; } // of 0.25 seconds | |
tim: while(1) | |
{ P3OUT |= SCIO ; dltqb() ; // toggle P3.0 at QB timer | |
P3OUT &=~SCIO ; dltqb() ; | |
P3OUT |= SCIO ; dlthb() ; // toggle P3.0 at HB timer | |
P3OUT &=~SCIO ; dlthb() ; } | |
ins: while(1) | |
{ P3OUT |= SCIO ; dliqb() ; // toggle P3.0 at QB instructions | |
P3OUT &=~SCIO ; dliqb() ; | |
P3OUT |= SCIO ; dlihb() ; // toggle P3.0 at HB instructions | |
P3OUT &=~SCIO ; dlihb() ; } | |
ms5: while(1) | |
{ P3OUT |= SCIO ; dly5ms() ; // toggle P3.0 at 5msec | |
P3OUT &=~SCIO ; dly5ms(); } | |
//........................................................................... | |
ini: ini_unio() ; // INIT UNIO memory | |
// write(#00)-->status register | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// WRITE SOURCE STRING IN EEPROM | |
//............................................................................ | |
if(access_mode==RND_MODE) // if RANDOM MODE | |
{ ch_cnt=0 ; adr_cnt=ADR0 ; // initialize char & address counters | |
while(ch_cnt<STRSZ) // repeat till the end of the string | |
{uni_wrbyte(adr_cnt,src_str[ch_cnt]); // write a random byte | |
ch_cnt++ ; adr_cnt++ ; } } // increment both counters | |
else // if PAGE MODE | |
{uni_wrstr(src_str,ADR0,STRSZ) ; } // write (page mode) from the source | |
// string , beginning from ADR0 address | |
// length of the string = STRSZ | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// READ EEPROM IN THE DESTINATION STRING | |
// ............................................................................ | |
if(access_mode==RND_MODE) // in RANDOM MODE | |
{ch_cnt=0 ; adr_cnt=ADR0 ; // init both counters : char & address | |
while(ch_cnt < STRSZ) // repeat till the end of the string | |
{uni_rdbyte(adr_cnt,dst_str+ch_cnt); // fill the destination string with chrs | |
ch_cnt++ ; adr_cnt++ ; } } // increment both counters (chr&address) | |
else | |
{uni_rdstr(dst_str,ADR0,STRSZ) ; } // in PAGE MODE , sequential read | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// COMPARE SOURCE & DESTINATION STRINGS | |
//............................................................................ | |
for(ch_cnt=0;ch_cnt<STRSZ;ch_cnt++) | |
{if((*(dst_str+ch_cnt)) != (*(src_str+ch_cnt))) | |
// compare the 2 strings(source & dest) | |
{ while(1) // in case of mismatch | |
{P1OUT = 0x00 ; dly250ms() ; // flash forever 00 - 0f , 4 / second | |
P1OUT = 0x0f ; dly250ms() ; } } // on P1 (4 LEDs) | |
else {P1OUT = ~ch_cnt ; // if coincidence,display counter on LEDs | |
dly250ms() ; // 4 bytes /second for a visual control | |
} } // repeat till the end of the string | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
while(1) // as final sign of sucess, display | |
{ for(ch_cnt=0;ch_cnt<16;ch_cnt++) // on LEDs (infinetelly) a counter | |
{ P1OUT = ~ch_cnt ; dly250ms() ; } } // 4 bytes / second | |
} // END MAIN | |
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬ | |
// LIST OF ERROR MESSAGES | |
//............................................................................. | |
// error_01 = WRSR-DEVADR error_02 = WRSR-WRSR cmnd error_03 = wr to SREG | |
// error_04 = WREN-DEVADR error_05 = WREN-WREN cmnd | |
// error_06 = WRITE-DEVADR error_07 = WRITE-WRITE cmnd error_08 = WRITE-address | |
// error_09 = WRITE-(n-1)DB error_10 = WRITE last data byte ( or random byte ) | |
// error_11 = READ-DEVADR error_12 = READ-READ cmnd error_13 = READ-address | |
// error_14 = READ-(n-1)DB error_15 = READ last byte ( or random byte ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment