source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/libraries/SPI/SPI.cpp@ 224

Last change on this file since 224 was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
3 * SPI Master library for arduino.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of either the GNU General Public License version 2
7 * or the GNU Lesser General Public License version 2.1, both as
8 * published by the Free Software Foundation.
9 */
10
11#include "SPI.h"
12#include "wiring_digital.h"
13#include "assert.h"
14#include "variant.h"
15#include <Arduino.h>
16
17SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
18{
19 assert(p_sercom != NULL );
20 _p_sercom = p_sercom;
21
22 _uc_pinMiso = uc_pinMISO;
23 _uc_pinSCK = uc_pinSCK;
24 _uc_pinMosi = uc_pinMOSI;
25}
26
27void SPIClass::begin()
28{
29 // PIO init
30 pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
31 pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
32 pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
33
34 // Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first.
35 _p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST);
36 _p_sercom->initSPIClock(SERCOM_SPI_MODE_0, 4000000);
37
38 _p_sercom->enableSPI();
39}
40
41
42void SPIClass::beginSlave()
43{
44 // PIO init
45 pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
46 pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
47 pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
48
49 // Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first.
50 _p_sercom->initSPIslave(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST);
51
52 _p_sercom->enableSPI();
53}
54
55void SPIClass::end()
56{
57 _p_sercom->resetSPI();
58}
59
60
61void SPIClass::beginTransaction(SPISettings settings)
62 {
63 SercomDataOrder bitOrder;
64 SercomSpiClockMode SpiClockMode;
65
66 interruptSave = intStatus();
67 noInterrupts();
68
69
70 if(settings.bit_order==LSBFIRST) bitOrder = LSB_FIRST;
71 else if(settings.bit_order==MSBFIRST) bitOrder = MSB_FIRST;
72 else;
73
74 if(settings.data_mode==SPI_MODE0) SpiClockMode = SERCOM_SPI_MODE_0;
75 else if(settings.data_mode==SPI_MODE1) SpiClockMode = SERCOM_SPI_MODE_1;
76 else if(settings.data_mode==SPI_MODE2) SpiClockMode = SERCOM_SPI_MODE_2;
77 else if(settings.data_mode==SPI_MODE3) SpiClockMode = SERCOM_SPI_MODE_3;
78 else;
79
80 end();
81
82 pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
83 pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
84 pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
85
86 _p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, bitOrder);
87 _p_sercom->initSPIClock(SpiClockMode, settings.interface_clock);
88
89 _p_sercom->enableSPI();
90 inTransactionFlag=1;
91 }
92
93void SPIClass::endTransaction(void)
94{
95 inTransactionFlag=0;
96 interrupts();
97}
98
99void SPIClass::setBitOrder(BitOrder order)
100{
101 if(order == LSBFIRST)
102 _p_sercom->setDataOrderSPI(LSB_FIRST);
103 else
104 _p_sercom->setDataOrderSPI(MSB_FIRST);
105}
106
107void SPIClass::setDataMode(uint8_t mode)
108{
109 switch(mode)
110 {
111 case SPI_MODE0:
112 _p_sercom->setClockModeSPI(SERCOM_SPI_MODE_0);
113 break;
114
115 case SPI_MODE1:
116 _p_sercom->setClockModeSPI(SERCOM_SPI_MODE_1);
117 break;
118
119 case SPI_MODE2:
120 _p_sercom->setClockModeSPI(SERCOM_SPI_MODE_2);
121 break;
122
123 case SPI_MODE3:
124 _p_sercom->setClockModeSPI(SERCOM_SPI_MODE_3);
125 break;
126
127 default:
128 break;
129 }
130}
131
132void SPIClass::setClockDivider(uint16_t div)
133{
134 _p_sercom->setBaudrateSPI(div);
135}
136
137byte SPIClass::transfer(uint8_t data)
138{
139 //Writing the data
140 _p_sercom->writeDataSPI(data);
141
142 //Read data
143 return _p_sercom->readDataSPI();
144}
145
146byte SPIClass::read()
147{
148 return _p_sercom->readDataSPI();
149}
150
151void SPIClass::usingInterrupt(uint8_t intNum)
152{
153 uint8_t irestore;
154 uint32_t mask;
155
156 irestore=intStatus();
157 noInterrupts();
158 if(intNum > 13)
159 {
160 //Interrupts();
161 return;
162 }
163 else
164 {
165 //Pio *pio=g_APinDescription[intNum].ulPort;
166 mask=g_APinDescription[intNum].ulPin;
167 interruptMode=1;
168 interruptMask=mask;
169 }
170 if (irestore) interrupts();
171}
172
173void SPIClass::write(uint8_t data)
174{
175 //Writing the data
176 _p_sercom->writeDataSPI(data);
177}
178
179void SPIClass::transfer(void *data, size_t count)
180{
181 uint8_t *p;
182 //int i=0;
183 //Serial.println("dentro transfer");
184 if(count==0) return;
185 p=(uint8_t *)data;
186 _p_sercom->writeDataSPI(*p); //scrittura primo dato
187
188 while(--count > 0)
189 {
190 //Serial.println("dentro while");
191 uint8_t out=*(p+1); //copio in out il prossimo dato
192 uint8_t in = _p_sercom->readDataSPI(); //leggo dato da SPI
193 //Serial.println("UNO");
194 //while(!(SERCOM4->SPI.INTFLAG.bit.RXC)); // controllo trasferimento //vedere se necessario
195 //Serial.println("DUE");
196 //Serial.println(out);
197 _p_sercom->writeDataSPI(out); //scrivo il out su SPI
198 *p++=in; //metto in p il dato letto da spi
199 }
200 while(!(SERCOM4->SPI.INTFLAG.bit.TXC)); // controllo trasferimrnto
201 //Serial.print("*p: ");
202 //Serial.println(*p);
203 *p = _p_sercom->readDataSPI();
204
205
206
207}
208
209uint16_t SPIClass::transfer16(uint16_t data)
210{
211 union{
212 uint16_t value;
213 struct{
214 uint8_t lsb;
215 uint8_t msb;
216 };
217 }in, out;
218
219 in.value = data;
220
221 if(SERCOM4->SPI.CTRLA.bit.DORD==0)
222 {
223 _p_sercom->writeDataSPI(in.msb);
224 while(!(SERCOM4->SPI.INTFLAG.bit.TXC));
225 out.msb = _p_sercom->readDataSPI();
226 //while(!(SERCOM4->SPI.INTFLAG.bit.RXC));
227 _p_sercom->writeDataSPI(in.lsb);
228 while(!(SERCOM4->SPI.INTFLAG.bit.TXC));
229 out.lsb = _p_sercom->readDataSPI();
230 }
231
232 else
233 {
234 _p_sercom->writeDataSPI(in.lsb);
235 while(!(SERCOM4->SPI.INTFLAG.bit.TXC));
236 out.lsb = _p_sercom->readDataSPI();
237 //while(!(SERCOM4->SPI.INTFLAG.bit.RXC));
238 _p_sercom->writeDataSPI(in.msb);
239 while(!(SERCOM4->SPI.INTFLAG.bit.TXC));
240 out.msb = _p_sercom->readDataSPI();
241 }
242
243 return out.value;
244}
245
246void SPIClass::attachInterrupt() {
247 // Should be enableInterrupt()
248}
249
250void SPIClass::detachInterrupt() {
251 // Should be disableInterrupt()
252}
253
254SPIClass SPI(&sercom4, 18, 20, 21);
Note: See TracBrowser for help on using the repository browser.