I was compiling the SPI from library by including the .o files inside the app.mk e.g. following lines added *APP_OBJS ?= main.o $(APP).o $(VARIANT).o wiring_digital.o wiring_digital_pinMode.o ellduino_Serial.o ellduino_spi.o SPIClass.o spiStruct.o* *VPATH += $(TOP)cores/arduelli $(TOP)variants/$(VARIANT) $(TOP)libraries/SPI* Also, I splitted the wiring_digital.h and wiring_digital_pinmode.h into there own source (.c) files to avoid multiple declaration, because the SPIClass.h is also including the wiring_digital.h using the digitalWrite and pinMode functions. The files are attached to the e-mail. Still I am getting following error: *ellduino_spi.o: In function `SPIClass::begin(unsigned char) const':* */home/asif/Ell-i-Working-Directory/Ell-i-Software-Development/Runtime/stm32/build/../libraries/SPI/./SPIClass.h:81: undefined reference to `digitalWrite'* *ellduino_spi.o: In function `SPIClass::activate_ss(unsigned char)':* */home/asif/Ell-i-Working-Directory/Ell-i-Software-Development/Runtime/stm32/build/../libraries/SPI/./SPIClass.h:183: undefined reference to `digitalWrite'* *ellduino_spi.o: In function `SPIClass::deactivate_ss(unsigned char)':* */home/asif/Ell-i-Working-Directory/Ell-i-Software-Development/Runtime/stm32/build/../libraries/SPI/./SPIClass.h:184: undefined reference to `digitalWrite'* Any good ideas? On Thu, Jul 3, 2014 at 1:52 PM, Asif Sardar <engr.asif.sardar@xxxxxxxxxxxxxx > wrote: > Ok. I will update you the status tomorrow evening. If there are issues I > need to ask, I will inform you by then. > > > On Thu, Jul 3, 2014 at 1:42 PM, Pekka Nikander <pekka.nikander@xxxxxx> > wrote: > >> Asif, >> >> Sounds very good. I would need it by Wednesday morning, if possible. >> Sooner would be better, of course, but realistically I won't have real >> time to test the ENCx24J600 code before that. Having SPI more-or-less >> working in the emulator would make things easier to test. >> >> Depending on your progress, we could have a telco on that on e.g. Tuesday >> morning, to see what's been done. And of course continue with email here. >> >> --Pekka >> >> On 2014–07–03, at 13:36 , Asif Sardar <engr.asif.sardar@xxxxxxxxxxxxxx> >> wrote: >> >> > Hello, >> > >> > Yes, it has been done for emulator. Atleast, I can see the .o object >> file for SPI under Runtime/build folder. I have to make a C interface for >> the SPI in library/SPI/ellduino_spi.h & .c files, just like I did >> modification for the serial communication in attached files. Such >> modification is required because the ctypes module cannot access the class >> member functions directly through the shared library. >> > >> > I can try testing them with emulator! When does it needed? >> > >> > BR, >> > Asif. >> > >> > >> > On Thu, Jul 3, 2014 at 1:14 PM, Pekka Nikander <pekka.nikander@xxxxxx> >> wrote: >> > The emulator has some SPI done, see SPIemu.h, SPI.cpp. I don't >> remember what is the status. It is probably just on the physical layer, >> most probably the library is not compiled in, but I just don't remember and >> don't have time to check right now. >> > >> > --pekka >> > >> > On 2014–07–03, at 12:51 , Asif Sardar <engr.asif.sardar@xxxxxxxxxxxxxx> >> wrote: >> > >> > > Hello, >> > > >> > > Yes. The SPI test cases are ready. I have seen in runtime that SPI >> has interface already e.g. begin(), end(), setdatamode() etc.But, I didn't >> see it in emulator. >> > > >> > > BR, >> > > Asif. >> > > >> > > >> > > On Thu, Jul 3, 2014 at 12:43 PM, Pekka Nikander < >> pekka.nikander@xxxxxx> wrote: >> > > Otso, >> > > >> > > FYI: I've started writing the ENCx24J600 driver. Looks simple and >> straightforward, just work. I'll make it separate from the ENC28J60 >> driver, as it will most probably be smaller (smaller flash footprint) than >> the ENC28J60 driver, if done right. >> > > >> > > My current estimate is that I'll have first version ready by Monday >> or Tuesday. It may or may not be complete, but in any case should be good >> enough for testing on Wednesday. As usual, I will most probably run out of >> time before we'll get it fully tested, though.... >> > > >> > > Asif, >> > > >> > > What's the situation with SPI library test cases? Do we have any yet? >> > > >> > > --Pekka >> > > >> > > >> > > >> > > >> > > -- >> > > With Best Regards, >> > > Asif Sardar. >> > > +358 43 8265795 >> > >> > >> > >> > >> > -- >> > With Best Regards, >> > Asif Sardar. >> > +358 43 8265795 >> > <ellduino_Serial.c><ellduino_Serial.h> >> >> > > > -- > > > > *With Best Regards,Asif Sardar.+358 43 8265795 <%2B358%2043%208265795>* > -- *With Best Regards,Asif Sardar.+358 43 8265795*
#include "arduelli_gpio.h" #include "ellduino_gpio.h" // XXX replace with variant_gpio.h #ifdef EMULATOR //extern "C" { int digitalRead(pin_t pin) { return GPIOPIN[pin].gpio_port->IDR & GPIOPIN[pin].gpio_mask? 1: 0; } //} // extern "C" { void digitalWrite(pin_t pin, uint32_t val) { if (val) { GPIOPIN[pin].gpio_port->BSRR = GPIOPIN[pin].gpio_mask; uint32_t value = 0; value &= ~(GPIOPIN[pin].gpio_mask >> 16); value |= (GPIOPIN[pin].gpio_mask & 0xffff); GPIOPIN[pin].gpio_port->ODR = value; GPIOPIN[pin].gpio_port->IDR = value; } else { GPIOPIN[pin].gpio_port->BRR = GPIOPIN[pin].gpio_mask; uint32_t value = 0; value &= ~(GPIOPIN[pin].gpio_mask); GPIOPIN[pin].gpio_port->ODR = value; GPIOPIN[pin].gpio_port->IDR = value; //parent_.IDR.value_ = parent_.ODR.value_; } } //} #else static inline int digitalRead(pin_t pin) { return GPIOPIN[pin].gpio_port->IDR & GPIOPIN[pin].gpio_mask? 1: 0; } static inline void digitalWrite(pin_t pin, uint32_t val) { if (val) GPIOPIN[pin].gpio_port->BSRR = GPIOPIN[pin].gpio_mask; else GPIOPIN[pin].gpio_port->BRR = GPIOPIN[pin].gpio_mask; } #endif
/* * Copyright (c) 2013-2014 ELL-i co-operative * * This file is part of ELL-i software. * * ELL-i software is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ELL-i software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ELL-i software. If not, see <http://www.gnu.org/licenses/>. */ /** * @author Pekka Nikander <pekka.nikander@xxxxxxxxx> 2013-2014 */ #ifndef _WIRING_DIGITAL_H_ # define _WIRING_DIGITAL_H_ //#include "arduelli_gpio.h" //#include "ellduino_gpio.h" // XXX replace with variant_gpio.h /************************************** * Arduino APIs */ #include "wiring_digital_pinMode.h" #ifdef __cplusplus extern "C" { #endif int digitalRead(pin_t pin); void digitalWrite(pin_t pin, uint32_t val); #ifdef __cplusplus } #endif /* //To avoid multiple definitions in other files, I split it to //source file -> wiring_digital.c #ifdef EMULATOR extern "C" { //static inline int digitalRead(pin_t pin) { return GPIOPIN[pin].gpio_port->IDR & GPIOPIN[pin].gpio_mask? 1: 0; } } extern "C" { //static inline void digitalWrite(pin_t pin, uint32_t val) { if (val) { GPIOPIN[pin].gpio_port->BSRR = GPIOPIN[pin].gpio_mask; uint32_t value = 0; value &= ~(GPIOPIN[pin].gpio_mask >> 16); value |= (GPIOPIN[pin].gpio_mask & 0xffff); GPIOPIN[pin].gpio_port->ODR = value; GPIOPIN[pin].gpio_port->IDR = value; } else { GPIOPIN[pin].gpio_port->BRR = GPIOPIN[pin].gpio_mask; uint32_t value = 0; value &= ~(GPIOPIN[pin].gpio_mask); GPIOPIN[pin].gpio_port->ODR = value; GPIOPIN[pin].gpio_port->IDR = value; //parent_.IDR.value_ = parent_.ODR.value_; } } } #else extern "C" { //static inline int digitalRead(pin_t pin) { return GPIOPIN[pin].gpio_port->IDR & GPIOPIN[pin].gpio_mask? 1: 0; } } extern "C" { //static inline void digitalWrite(pin_t pin, uint32_t val) { if (val) GPIOPIN[pin].gpio_port->BSRR = GPIOPIN[pin].gpio_mask; else GPIOPIN[pin].gpio_port->BRR = GPIOPIN[pin].gpio_mask; } } #endif */ #endif//_WIRING_DIGITAL_H_
#include "wiring_digital_pinMode.h" //extern "C" { //static inline void pinMode(pin_t pin, const enum pin_mode mode) { const uint32_t pin_shift = (GPIOPIN[pin].gpio_pin * 2); switch (mode) { case INPUT: /* High impedance: push up/down register bits zero */ GPIOPIN[pin].gpio_port->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << pin_shift); break; case INPUT_PULLUP: { /* Pull-up: push up/down register bits 01 */ register uint32_t pupdr = GPIOPIN[pin].gpio_port->PUPDR; pupdr |= (GPIO_PUPDR_PUPDR0_0 << pin_shift); pupdr &= ~(GPIO_PUPDR_PUPDR0_1 << pin_shift); GPIOPIN[pin].gpio_port->PUPDR = pupdr; break; } case INPUT_PULLDOWN: { /* Pull-down: push up/down register bits 10 */ register uint32_t pupdr = GPIOPIN[pin].gpio_port->PUPDR; pupdr &= ~(GPIO_PUPDR_PUPDR0_0 << pin_shift); pupdr |= (GPIO_PUPDR_PUPDR0_1 << pin_shift); GPIOPIN[pin].gpio_port->PUPDR = pupdr; break; } case OUTPUT: break; } switch (mode) { case OUTPUT: { /* Output mode: mode register bits 01 */ register uint32_t moder = GPIOPIN[pin].gpio_port->MODER; moder |= (GPIO_MODER_MODER0_0 << pin_shift); moder &= ~(GPIO_MODER_MODER0_1 << pin_shift); GPIOPIN[pin].gpio_port->MODER = moder; break; } case INPUT: case INPUT_PULLUP: case INPUT_PULLDOWN: /* Input mode: mode register bits zero */ GPIOPIN[pin].gpio_port->MODER &= ~(GPIO_MODER_MODER0 << pin_shift); } } //}
/* * Copyright (c) 2013-2014 ELL-i co-operative * * This file is part of ELL-i software. * * ELL-i software is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ELL-i software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ELL-i software. If not, see <http://www.gnu.org/licenses/>. */ /** * @author Pekka Nikander <pekka.nikander@xxxxxxxxx> 2013-2014 */ /** * Arduino pinMode * * Configuration records each GPIO pin as input or output, with the desired pullups. */ #if defined(ARDUELLI_FEATURE_STATIC_PINMODE) /* * Static, data driven version of the Arduino pinMode() API. * * This version attempts to cut the amount of generated code through * assembling couple a static data structures and then calling * SystemInitMaskAndValue() with the static data structures as the * argument. The rationale is that if the compiler is smart enough, * it is able to compute the static data structure contents at compile * time and assemble the data structures at compile time. * * Unfortunately, GCC 4.7.1 is not quite smart enough. It manages to * use constant propagation to compute all of the initialisation * values at compile time, but it still fails to generate the actual * structs at compile time. Instead, it generates explicit code that * initialises the data structures at run time. Hence, with gcc (and * therefore by default) we don't use this version. * * XXX Test with LLVM to see if it manages to do it right. */ # define DEFINE_pinMode(pin, mode) \ static const \ SystemInitRecordMaskAndValue GPIO_PIN_MODE_Records[] = { \ { \ .init_r_address = (volatile preg32_t *const)( \ (volatile char *const)GPIOPIN[pin].gpio_port \ + ((char *const)&GPIOA->MODER - (char *const)GPIOA)), \ .init_r_mask = ~(GPIO_MODER_MODER ## pin), \ .init_r_value = GPIO_pin_mode_moder_values[mode], \ }, { \ .init_r_address = (volatile preg32_t *const)( \ (volatile char *const)GPIOPIN[pin].gpio_port \ + ((char *const)&GPIOA->PUPDR - (char *const)GPIOA)), \ .init_r_mask = ~(GPIO_PUPDR_PUPDR ## pin), \ .init_r_value = GPIO_pin_mode_pupdr_values[mode], \ } \ } # define INIT_pinMode(pin, mode) \ StaticInitMaskAndValue(COUNT_OF(GPIO_PIN_MODE_Records), \ GPIO_PIN_MODE_Records) /** * XXX TBD */ # define pinMode(pin, mode) { \ DEFINE_pinMode(pin, mode); \ INIT_pinMode(pin, mode); \ } while (0) #else /** * Arduino pinMode API. * @param pin Pin whose mode to change. * @param mode The new mode for pin. * * Dynamic, sequential, inlined version of the Arduiono pinMode() API. * * With GCC, generates fair but not optimal code. */ //To avoid multiple definitions in other files, I split it to //source file -> wiring_digital_pinMode.c #include "arduelli_gpio.h" #include "ellduino_gpio.h" #ifdef __cplusplus extern "C" { #endif void pinMode(pin_t pin, const enum pin_mode mode); #ifdef __cplusplus } #endif /* extern "C" { //static inline void pinMode(pin_t pin, const enum pin_mode mode) { const uint32_t pin_shift = (GPIOPIN[pin].gpio_pin * 2); switch (mode) { case INPUT: // High impedance: push up/down register bits zero GPIOPIN[pin].gpio_port->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << pin_shift); break; case INPUT_PULLUP: { // Pull-up: push up/down register bits 01 register uint32_t pupdr = GPIOPIN[pin].gpio_port->PUPDR; pupdr |= (GPIO_PUPDR_PUPDR0_0 << pin_shift); pupdr &= ~(GPIO_PUPDR_PUPDR0_1 << pin_shift); GPIOPIN[pin].gpio_port->PUPDR = pupdr; break; } case INPUT_PULLDOWN: { // Pull-down: push up/down register bits 10 register uint32_t pupdr = GPIOPIN[pin].gpio_port->PUPDR; pupdr &= ~(GPIO_PUPDR_PUPDR0_0 << pin_shift); pupdr |= (GPIO_PUPDR_PUPDR0_1 << pin_shift); GPIOPIN[pin].gpio_port->PUPDR = pupdr; break; } case OUTPUT: break; } switch (mode) { case OUTPUT: { // Output mode: mode register bits 01 register uint32_t moder = GPIOPIN[pin].gpio_port->MODER; moder |= (GPIO_MODER_MODER0_0 << pin_shift); moder &= ~(GPIO_MODER_MODER0_1 << pin_shift); GPIOPIN[pin].gpio_port->MODER = moder; break; } case INPUT: case INPUT_PULLUP: case INPUT_PULLDOWN: // Input mode: mode register bits zero GPIOPIN[pin].gpio_port->MODER &= ~(GPIO_MODER_MODER0 << pin_shift); } } } */ #endif
# # Copyright (c) 2013-2014 ELL-i co-operative # # Compile and link an application # TOP ?=../ MAKEDIR ?= $(TOP)make/ # # Define the variant to build for # VARIANT ?= ellduino # # Set up the compilation environment, identical to the Arduino IDE, # and include system lib building; we depend on system libraries # include $(MAKEDIR)$(PLATFORM).mk include $(MAKEDIR)system_libs_inc.mk include $(MAKEDIR)libs_inc.mk # # Define the app name # APP ?= sketch # # Define app library objects. Add new objects here. # #ellduino_Serial.o shall be made automatically like ellduino_timer.o and other .o files APP_OBJS ?= main.o $(APP).o $(VARIANT).o wiring_digital.o wiring_digital_pinMode.o \ ellduino_Serial.o ellduino_spi.o SPIClass.o spiStruct.o # # Rules # VPATH += $(TOP)cores/arduelli $(TOP)variants/$(VARIANT) $(TOP)libraries/SPI all: $(APP) $(APP).hex libemulator.so clean:: rm -f $(APP) rm -f $(APP).hex rm -f $(APP).lst rm -f $(APP_OBJS) rm -f $(PRE_OBJS) rm -f $(POST_OBJS) rm -f make.map rm -f libemulator.so rm -f *.o $(APP): $(APP_OBJS) $(SYSTEM_LIBS) $(PRE_OBJS) $(POST_OBJS) $(LD) $(LDFLAGS) -o $@ $(PRE_OBJS) $(APP_OBJS) $(LIBS) $(POST_OBJS) # # Define rules for producing .hex files # .PHONY: .hex %.hex: % $(ELF2HEX) $(EHFLAGS) $< $@ libemulator.so: $(SYSTEM_LIBS) $(PRE_OBJS) $(POST_OBJS) $(LD) $(LDFLAGS) $(SHAREDFLAGS) -o $@ $(PRE_OBJS) $(APP_OBJS) $(LIBS) $(POST_OBJS)
/* * Copyright (c) 2014 ELL-i co-operative * * This file is part of ELL-i software. * * ELL-i software is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ELL-i software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ELL-i software. If not, see <http://www.gnu.org/licenses/>. */ /** * @author Pekka Nikander <pekka.nikander@xxxxxxxxx> 2014 * * @brief The Arduino library SPI class */ #ifndef _SPI_CLASS_H_ #define _SPI_CLASS_H_ #include <stm32f0xx.h> #include <spiStruct.h> #include <ellduino_gpio.h> // XXX To be placed into the variant.h! #include <arduelli_thread.h> // XXX TBD -- is this the right file name? #include <wiring_digital.h> #include <TinyMap.h> #ifndef BOARD_SPI_DEFAULT_SS #define BOARD_SPI_DEFAULT_SS 10 /* XXX */ #endif enum SPITransferMode { SPI_CONTINUE, SPI_LAST }; enum SPIBitOrder { MSBFIRST = !SPI_CR1_LSBFIRST, LSBFIRST = SPI_CR1_LSBFIRST, }; enum SPIClockDivider { SPI_CLOCK_DIV2 = !SPI_CR1_BR_2 | !SPI_CR1_BR_1 | !SPI_CR1_BR_0, SPI_CLOCK_DIV4 = !SPI_CR1_BR_2 | !SPI_CR1_BR_1 | SPI_CR1_BR_0, SPI_CLOCK_DIV8 = !SPI_CR1_BR_2 | SPI_CR1_BR_1 | !SPI_CR1_BR_0, SPI_CLOCK_DIV16 = !SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0, SPI_CLOCK_DIV32 = SPI_CR1_BR_2 | !SPI_CR1_BR_1 | !SPI_CR1_BR_0, SPI_CLOCK_DIV64 = SPI_CR1_BR_2 | !SPI_CR1_BR_1 | SPI_CR1_BR_0, SPI_CLOCK_DIV128 = SPI_CR1_BR_2 | SPI_CR1_BR_1 | !SPI_CR1_BR_0, SPI_CLOCK_DIV256 = SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0, }; enum SPIDataMode { SPI_MODE0 = !SPI_CR1_CPHA | !SPI_CR1_CPOL, SPI_MODE1 = SPI_CR1_CPHA | !SPI_CR1_CPOL, SPI_MODE2 = !SPI_CR1_CPHA | SPI_CR1_CPOL, SPI_MODE3 = SPI_CR1_CPHA | SPI_CR1_CPOL, }; /** * Type for mapping Arduino PIN numbers to SPI CR1 register values. */ typedef TinyMap<uint8_t,uint32_t,7> Pin2Int7; //XXX TODO: Figure out a better implementation for setClock class SPIClass { public: const struct SPI &spi_; constexpr SPIClass(const SPI &spi, Pin2Int7 &ssPinCR1) : spi_(spi), ssPinCR1_(ssPinCR1) {}; void begin(const uint8_t ss_pin = BOARD_SPI_DEFAULT_SS) const { digitalWrite(ss_pin, 1); /* Avoid glitch */ pinMode(ss_pin, OUTPUT); spi_master_begin(&spi_); ssPinCR1_[ss_pin] = 0 | ! SPI_CR1_CPHA /* Data at first edge */ | ! SPI_CR1_CPOL /* Clock low when idle */ | SPI_CR1_MSTR /* Master mode */ | SPI_CR1_BR_1 /* Clock divider 8 */ | SPI_CR1_SPE /* SPI enabled */ | ! SPI_CR1_LSBFIRST /* MSB first */ | SPI_CR1_SSI /* Internal NSS high, needed for master mode */ | SPI_CR1_SSM /* Software Slave management enabled */ | ! SPI_CR1_RXONLY /* 0: Full duplex */ | ! SPI_CR1_CRCL /* 0: N/A (8-bit CRC length) */ | ! SPI_CR1_CRCNEXT /* 0: Transmit TX buffer, not CERC */ | ! SPI_CR1_CRCEN /* 0: CRC disabled */ | SPI_CR1_BIDIOE /* 1: Output enabled */ | ! SPI_CR1_BIDIMODE /* 0: 2-Line (uni)directional data */ ; }; void end(const uint8_t ss_pin) const { pinMode(ss_pin, INPUT /* XXX DEFAULT */); }; void end(void) const { /* XXX Semantic inconsistency with begin(void) */ spi_master_end(&spi_); } void setBitOrder(const SPIBitOrder bitOrder) const { setBitOrder(BOARD_SPI_DEFAULT_SS, bitOrder); } void setBitOrder(const uint8_t ss_pin, const SPIBitOrder bitOrder) const { ssPinCR1_[ss_pin] &= ~SPI_CR1_LSBFIRST; ssPinCR1_[ss_pin] |= bitOrder; } uint32_t setClockDivider(const SPIClockDivider clockDivider) const { return setClockDivider(BOARD_SPI_DEFAULT_SS, clockDivider); } uint32_t setClockDivider(const uint8_t ss_pin, const SPIClockDivider clockDivider) const { uint32_t oldValue = ssPinCR1_[ss_pin] & SPI_CR1_BR; ssPinCR1_[ss_pin] &= ~SPI_CR1_BR; ssPinCR1_[ss_pin] |= clockDivider; return oldValue; } uint32_t setClock(const uint32_t hertz) const { return setClock(BOARD_SPI_DEFAULT_SS, hertz); } uint32_t setClock(const uint8_t ss_pin, const uint32_t hertz) const { uint32_t outputHertz = SystemCoreClock>>1; uint8_t wantedDivider = 0; SPIClockDivider wantedDividerEnum; if (hertz<outputHertz) { for (wantedDivider=1; wantedDivider < 7; wantedDivider++){ outputHertz>>=1; if (hertz >= outputHertz) break; } } //XXX There should be a better way than typecasting. wantedDividerEnum = static_cast<SPIClockDivider>(wantedDivider<<3); setClockDivider(ss_pin, wantedDividerEnum); return outputHertz; } void setDataMode(SPIDataMode dataMode) const { setDataMode(BOARD_SPI_DEFAULT_SS, dataMode); } void setDataMode(uint8_t ss_pin, SPIDataMode dataMode) const { ssPinCR1_[ss_pin] &= ~(SPI_CR1_CPHA | SPI_CR1_CPOL); ssPinCR1_[ss_pin] |= dataMode; } uint8_t transfer(uint8_t data, SPITransferMode mode = SPI_LAST) const { return transfer(BOARD_SPI_DEFAULT_SS, data, mode); } uint8_t transfer(uint8_t ss_pin, uint8_t data, SPITransferMode mode = SPI_LAST) const { return transfer(ss_pin, &data, 1, mode); } uint8_t transfer(uint8_t ss_pin, uint8_t data[], uint8_t len, SPITransferMode mode = SPI_LAST) const { activate_ss(ss_pin); const uint32_t cr1 = ssPinCR1_[ss_pin]; len = spi_transfer(&spi_, cr1, data, len); if (mode == SPI_LAST) deactivate_ss(ss_pin); return len; }; private: Pin2Int7 &ssPinCR1_; static inline void activate_ss(uint8_t ss_pin) { digitalWrite(ss_pin, 0); }; static inline void deactivate_ss(uint8_t ss_pin) { digitalWrite(ss_pin, 1); }; }; #endif//_SPI_CLASS_H_
/* * Copyright (c) 2014 ELL-i co-operative. * * ELL-i software is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ELL-i software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ELL-i software. If not, see * <http://www.gnu.org/licenses/>. */ /* * Authors: Pekka Nikander <pekka.nikander@xxxxxxxxx> 2014 */ #ifndef _ELLDUINO_SPI_H_ # define _ELLDUINO_SPI_H_ # include <SPIClass.h> # include <system_init.h> /** * Declarations for externally visible SPI init records. * * STM32F0 has SPI ports 1 and 2. */ SPI_INIT_DEFAULT(1); SPI_INIT_DEFAULT(2); #define BOARD_SPI_DEFAULT_SS 10 /* XXX: Should be D10 but that is not defined yet */ extern Pin2Int7 spimap1, spimap2; static const struct SPI __SPI1struct = DEFINE_SPI_STRUCT(1, A, 15, 0, B, 4, 0, B, 5, 0, B, 3, 0); static const struct SPI __SPI2struct = DEFINE_SPI_STRUCT(2, B, 12, 0, B, 14, 0, B, 15, 0, B, 13, 0); static const class SPIClass SPI (__SPI1struct, spimap1); static const class SPIClass SPI_2(__SPI2struct, spimap2); ///****************************************************************************************/// ///Adding interface for the robotframework to access class member functions. ///****************************************************************************************/// #ifdef EMULATOR extern "C" { void begin(const uint8_t ss_pin); void end(const uint8_t ss_pin); void setBitOrder(const uint8_t ss_pin, const SPIBitOrder bitOrder); uint32_t setClockDivider(const uint8_t ss_pin, const SPIClockDivider clockDivider); void setDataMode(uint8_t ss_pin, SPIDataMode dataMode); uint8_t transfer(uint8_t ss_pin, uint8_t data); } #endif #endif//_ELLDUINO_SPI_H_