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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.