Forum: Mikrocontroller und Digitale Elektronik MSP430 F2013 Special SPI: P1.7 vs. SDI


von Nicco (Gast)


Lesenswert?

Hallo leute,

Ich weiss nicht ob dies ein Standard ist oder das ein spezial Fall ist:

Ich hab ein F2013, damit soll ich mit ein zweites Bauteil kommunizieren, 
der eine EEPROM beinhaltet. Der SPI Protokoll ist so gesetzt worden:

Write EEPROM:
ich sende (aus MSP430 Sicht) 6 bytes (command, address, 4 data). Falls 
dieses Bauteil die Kommunikation korrekt interpretiert und die EEPROM 
modifiziert wurde, setzt er nach max 12ms sein D_OUT auf 1.

Read EEPROM:
ich sende (aus MSP430 Sicht) 6 bytes (command, address, 
data(irrelevant)). Falls dieses Bauteil die Kommunikation korrekt 
interpretiert, setzt er nach etwa 50u (während 1 Clock) D_OUT auf 1. 
Danach soll der MSP430 noch 33 Clock pulses (1+ 4*8) raus lassen und den 
Daten einlesen (d_OUT von Bauteil, SDI auf MSP430).

Nun mein Problem...
Sobald ich die 6 Bytes gesendet habe, muss ich den P1.7 wieder auf Input 
setzen und warten bis es auf 1 ist (evtl. min einen interrupt). Falls 
ein ReadEEPROM gefagt ist, muss ich P1.7 wieder als SDI setzen.

Ich weiss dass USI überschreibt die Input/Output Port settings  (ich 
nehme mal an mit USICTL0 = USIPE7).
Falls ich dieses wider als Input benützen will, ist es genügend den 
USIPE7 wider auf Null setzen? Muss ich wieder P1DIR und/oder P1SEL 
ändern?

Oder sogar gibt es einen Weg, diesen D_OUT über SPI zu kontrollieren? 
(scheint mir kompliziert, speziell für die 12 ms Wartezeit...)

Danke für alle Tips!

Nicco

von N. Z. (nicco)


Lesenswert?

Hallo zusammen,
ich sehe niemand hat eine Antwort gegeben :(
Naja, mittlerweile hab ich den ganzen Code geschrieben:
1
//--------------------------------------------------------------------------------------------------------
2
//      Software
3
//
4
//      Ver 2.0   test writeEEPROM / rearEEPROM functions
5
//
6
//      Working on a MSP430 F2013 (eZ430 Development Tool
7
//      IAR Kickstart version 4.11
8
//--------------------------------------------------------------------------------------------------------
9
10
//--------------------------------------------------------------------------------------------------------
11
// Include Headers
12
//--------------------------------------------------------------------------------------------------------
13
#include <io430x20x3.h>                                 // Header file for this device
14
#include <intrinsics.h>                                 // Intrinsic functions
15
#include <stdint.h>                                     // Integers of defined sizes
16
17
//--------------------------------------------------------------------------------------------------------
18
// Define Fixed variables
19
//--------------------------------------------------------------------------------------------------------
20
21
#define DI1    P1IN_bit.P1IN_2                 // Digital Input 1 = P1.2 IN                      ***not fixed yet
22
#define D_OUT    P1IN_bit.P1IN_7                 // D_OUT from SL13A (when needed as input)
23
24
#define DI1IE    P1IE_bit.P1IE_2                 // Digital Input 1 = P1.2 IN                      ***not fixed yet
25
#define D_OUTIE          P1IE_bit.P1IE_7                 // D_OUT from SL13A (when needed as input)
26
27
#define DI1IFG    P1IFG_bit.P1IFG_2               // Digital Input 1 = P1.2 IN                      ***not fixed yet
28
#define D_OUTIFG  P1IFG_bit.P1IFG_7               // D_OUT from SL13A (when needed as input)
29
30
#define DI1IES    P1IES_bit.P1IES_2               // Digital Input 1 = P1.2 IN                      ***not fixed yet
31
#define D_OUTIES  P1IES_bit.P1IES_7               // D_OUT from SL13A (when needed as input)
32
33
34
//--------------------------------------------------------------------------------------------------------
35
// Initialize Functions
36
//--------------------------------------------------------------------------------------------------------
37
38
void HW_init(void);
39
void readEEPROM(void);
40
void writeEEPROM(void);
41
42
//--------------------------------------------------------------------------------------------------------
43
// Initialize variables
44
//--------------------------------------------------------------------------------------------------------
45
46
unsigned short ob[6];                                   // Define place for data of Online Block
47
int ICF = 0;                                            // Input Changed Flag
48
int ECF = 0;                                            // EEPROM Changed Flag
49
50
                                  
51
52
//--------------------------------------------------------------------------------------------------------
53
// Main 
54
//--------------------------------------------------------------------------------------------------------
55
56
void main (void)
57
{
58
59
  HW_init();                                            // Initalize Hardware
60
  
61
  readEEPROM();                                        // test write EEPROM
62
  
63
}
64
65
66
//--------------------------------------------------------------------------------------------------------
67
// Define Functions
68
//--------------------------------------------------------------------------------------------------------
69
70
//-------------------------------------------------------------------------------------------Initalisation
71
//Initializes all the ports and setting
72
void HW_init(void){
73
// Setup clocks
74
  WDTCTL = WDTPW | WDTHOLD;                       // stop Watchdog
75
        BCSCTL1 = CALBC1_8MHZ;              // Calibrated range for DCO
76
  DCOCTL = CALDCO_8MHZ;              // Calibrated tap and modulation
77
  BCSCTL3 = LFXT1S_2;                             // ACLK from VLO (12Khz)
78
        BCSCTL2 = DIVS_3;                               // SMCLK = DCO/8 = 1MHz
79
// Configure ports
80
        
81
  P1OUT = 0;                      // pre clear Buffer
82
  P1DIR = BIT5 | BIT6;              // all inputs (initally, then overwrited by SPI)
83
  P1REN = BIT0|BIT1|BIT2|BIT3|BIT4|BIT7;          // Pull resistors on unused pins
84
        
85
  P2SEL = 0;                // Digital i/o rather than crystal
86
        P2OUT = 0;                                      // preclear output buffer
87
  P2DIR = BIT6;                // set P2.6 Output
88
  P2REN = BIT7;                      // Pull resistors on P2.7
89
}
90
91
//---------------------------------------------------------------------------------------------Read EEPROM
92
//reads the online Block on the EEPROM and returns the value
93
void readEEPROM(void){
94
  int i;
95
  ob[0] = 0x41;                                         // read Command code for SPI communication
96
  ob[1] = 0x01;                                         // Address for SPI communication                  **to define!
97
  D_OUTIE = 0;
98
//Init USI  
99
  // Enable SDI, SDO, SCLK, msb first, master, enable output, latch data
100
  USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE | USISWRST;
101
  // Write then read (CPHA = 1 -> CKPH = 0), SPI not I2C, enable interrupt
102
  USICTL1 = USIIE | USIIFG;                             // Can't clear USIIE in reset mode
103
  USICKCTL = USIDIV_0 | USISSEL_3;                      // SCLK = SMCLK, clock idles low (CPOL = CKPL = 0)
104
  USICTL0 &= ~USISWRST;                                 // Release USI from reset
105
  USICTL1 &= ~USIIFG;                      // Avoid unwanted interrupt (clear pending IE)
106
//send request  
107
  for (i=0; i<6; i++){                                  // for 6 times (1 command, 1 address, 4 data)
108
     
109
     USISRL = ob[i];                                    // Write variable value to Shift Register
110
     USICNT = 8;                // Start SPI to transfer 8 bits
111
     __low_power_mode_0();
112
     
113
  }
114
//send 'Execute'  
115
  USICNT = 1;                                           // Start SPI to transfer 1 bit (execute)
116
   __low_power_mode_0();
117
//stop USI  
118
  USICTL1 &= ~USIIE;                                    // disable SPI Interrupts
119
  USICTL0 &= ~USIPE7;                                   // disable SDI -> P1.7 Input
120
//wait Ready
121
  P1IFG = 0;                                            // clear pending interrupts
122
  D_OUTIE = 1;                                          // enable interrupt
123
  D_OUTIES = 0;                                         // Sensitive on rising edge
124
  __low_power_mode_0();                                 // power down until interrupt released
125
  ECF = 0;                                              // clear ECF (changed EEPROM on purpose)
126
//send ACK
127
  D_OUTIE = 0;                                          // disable Port interrupt
128
  USICTL0 |= USIPE7;                                    // enable SDI
129
  USICTL1 |= USIIE;                                     // enable SPI Interrupts
130
  USICNT = 1;                                           // send one clock (USICNT = 1) 
131
  __low_power_mode_0();                                 
132
  
133
  for (i=2; i<6; i++){                                  // for 4 times
134
    USICNT = 8;                                         // send 8 clocks
135
    __low_power_mode_0();                               // wait until done...
136
    ob[i] = USISRL;                                     // ...and save the value
137
  }
138
//stop USI  
139
  //USICTL0 |= USISWRST;              // reset USI (??? needed?)
140
  USICTL1 &= ~USIIE;                                    // disable SPI Interrupts
141
  USICTL0 &= ~USIPE7;                                   // disable SDI -> P1.7 Input
142
//wait for ACK  
143
  P1IFG = 0;                                            // clear pending interrupts
144
  D_OUTIE = 1;                                          // enable interrupt
145
  D_OUTIES = 0;                                         // Sensitive on rising edge
146
  __low_power_mode_0();                                 // power down until interrupt released
147
  ECF = 0;                                              // clear ECF (changed EEPROM on purpose)
148
}
149
//--------------------------------------------------------------------------------------------Write EEPROM
150
//writes the given value on the Online Block of the EEPROM
151
void writeEEPROM(void){
152
  int i;
153
  ob[0] = 0x81;                                         // write Command code for SPI communication
154
  ob[1] = 0x01;                                         // Address for SPI communication                  **to define!
155
  ob[2] = 0x74;                                         // Preload random numbers
156
  ob[3] = 0x36;
157
  ob[4] = 0xF8;
158
  ob[5] = 0xA5;
159
  D_OUTIE = 0;                                          // disable interrupt
160
//Init USI  
161
  // Enable SDI, SDO, SCLK, msb first, master, enable output, latch data
162
  USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE | USISWRST;
163
  // Write then read (CPHA = 1 -> CKPH = 0), SPI not I2C, enable interrupt
164
  USICTL1 = USIIE | USIIFG;                    // Can't clear USIIE in reset mode
165
  USICKCTL = USIDIV_0 | USISSEL_3;                      // SCLK = SMCLK, clock idles low (CPOL = CKPL = 0)
166
  USICTL0 &= ~USISWRST;                      // Release USI from reset
167
  USICTL1 &= ~USIIFG;                      // Avoid unwanted interrupt (clear pending IE)
168
//send request  
169
  for (i=0; i<6; i++){                                  // for 6 times (1 command, 1 address, 4 data)
170
     
171
     USISRL = ob[i];                                    // Write variable value to Shift Register
172
     USICNT = 8;                // Start SPI to transfer 8 bits
173
     __low_power_mode_0();
174
    
175
     
176
  }
177
//send 'Execute'  
178
  USICNT = 1;                        // Start SPI to transfer 1 bit (execute)
179
   __low_power_mode_0();
180
  
181
//stop USI  
182
  //USICTL0 |= USISWRST;              // reset USI (??? needed?)
183
  USICTL1 &= ~USIIE;                                    // disable SPI Interrupts
184
  USICTL0 &= ~USIPE7;                                   // disable SDI -> P1.7 Input
185
//wait for ACK  
186
  P1IFG = 0;                                            // clear pending interrupts
187
  D_OUTIE = 1;                                          // enable interrupt
188
  D_OUTIES = 0;                                         // Sensitive on rising edge
189
  __low_power_mode_0();                                 // power down until interrupt released
190
  ECF = 0;                                              // clear ECF (changed EEPROM on purpose)
191
  return;      
192
}
193
194
195
//--------------------------------------------------------------------------------------------------------
196
// ISR for USI: clear flag and exit
197
//--------------------------------------------------------------------------------------------------------
198
#pragma vector = USI_VECTOR
199
__interrupt void USI_ISR (void)                    
200
{
201
  USICTL1 &= ~USIIFG;              // Clear flag
202
        __low_power_mode_off_on_exit();                 // leave LPM0 on exit 
203
       
204
}
205
206
//--------------------------------------------------------------------------------------------------------
207
// ISR for Inputs on P1
208
//--------------------------------------------------------------------------------------------------------
209
#pragma vector = PORT1_VECTOR
210
__interrupt void PORT1_ISR (void)            // NOT acknowledged automatically
211
{
212
  if(D_OUTIFG){                                         // P1.7 relased
213
        ECF = 1;                                        // set EEPROM Changed Flag
214
  }
215
  else if(DI1IFG){                                      // P1.0 relased  
216
        ob[3] ^= BIT6 ;                                 // toggle bit in ob[]                             ***modify numbers!
217
        DI1IES ^= 1;                                    // Toggle sensitive edge (rising <-> falling)
218
        ICF = 1;                                        // set 'Input Changed Flag'    
219
  }  
220
                                             
221
 
222
223
  do{
224
    P1IFG = 0;                                          // Clear any pending interrupt...
225
  } while(P1IFG != 0);                                  // ...until none remain
226
  
227
  __low_power_mode_off_on_exit();                       // leave LPM0 on exit
228
       
229
}

Solange dies in der Luft ist (ohne zweites Bauteil und mit SDI auf GND 
ausser um ein interrupt auszulösen), funktioniert alles bestens (schöne 
Pegel in Ausgang, und auf Clock).
ABER:

sobald ich den zweiten Bauteil verbinde, geht der Clock auf halbes 
Pegel, anstatt 8 bits, sind es 9, und und und...
Auf den zweiten Bauteil kann man nichts ändern (SPI enable oder 
ähnliches), und soll eigentlich funktionsfähig sein.

Bevor ich weiter gehe, hat jemand vielleicht eine kritik bezüglich mein 
Code? Verbesserungsmöglichkeiten? Fehler mit irgend ein PxREN (sobald 
ein Last gibt, krascht das ganze)...
ICh habe einiges ausprobiert, darum kann es gut sein dass unnötige 
Befehle drin sind...

Danke! Regards...

Nicco

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.