Last active
September 8, 2015 21:13
-
-
Save spirilis/e40e7037300bc00e5f64 to your computer and use it in GitHub Desktop.
take 1 on C++ templated RSPI driver
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
17:10:20 **** Incremental Build of configuration HardwareDebug for project test **** | |
make -j4 all | |
'Scanning and building file: ../src/test.cpp' | |
'Invoking: Scanner and Compiler' | |
rx-elf-gcc -MM -MP -MF "src/test.d" -MT"src/test.o" -MT"src/test.d" -x c++ -nostdinc -ffunction-sections -fno-function-cse -fdata-sections -fsection-anchors -free -flto-compression-level=0 -fno-cse-follow-jumps -fno-jump-tables -fno-guess-branch-probability -fno-move-loop-invariants -I"C:\PROGRA~2\KPIT\GNURXV~1.03-\rx-elf\rx-elf/lib/gcc/rx-elf/4.8-GNURX_v14.03/include" -I"C:\PROGRA~2\KPIT\GNURXV~1.03-\rx-elf\rx-elf/rx-elf/include" -I"C:\Renesas\workspace\test\src" -D__RX_LITTLE_ENDIAN__=1 -DCPPAPP -Os -g2 -g -flto -mlittle-endian-data -mcpu=rx200 -nofpu -fno-exceptions -fno-rtti "../src/test.cpp" | |
../src/test.cpp:22:29: error: cannot declare variable 'SPI' to be of abstract type 'RSPI_RX210<0u>' | |
RSPI_RX210<RSPI_INSTANCE_0> SPI; | |
^ | |
In file included from ../src/test.cpp:20:0: | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:26:7: note: because the following virtual functions are pure within 'RSPI_RX210<0u>': | |
class RSPI_RX210 : public SPIClass { | |
^ | |
In file included from C:\Renesas\workspace\test\src/RSPI_RX210.h:14:0, | |
from ../src/test.cpp:20: | |
C:\Renesas\workspace\test\src/SPI.h:72:22: note: virtual void SPIClass::setClockDivider(int) | |
virtual void setClockDivider(int clockDiv) = 0; | |
^ | |
In file included from ../src/test.cpp:20:0: | |
C:\Renesas\workspace\test\src/RSPI_RX210.h: In instantiation of 'uint8_t RSPI_RX210<rspi_instance>::transfer(uint8_t) [with unsigned int rspi_instance = 0u; uint8_t = unsigned char]': | |
../src/test.cpp:61:20: required from here | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:119:23: error: no match for 'operator=' (operand types are 'volatile st_rspi::<anonymous union>::<anonymous struct>' and 'uint8_t {aka unsigned char}') | |
rspidrv->SPDR.WORD = inb; | |
^ | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:119:23: note: candidate is: | |
In file included from ../src/test.cpp:19:0: | |
../src/iodefine.h:5159:16: note: st_rspi::<anonymous union>::<anonymous struct>& st_rspi::<anonymous union>::<anonymous struct>::operator=(const st_rspi::<anonymous union>::<anonymous struct>&) | |
struct { | |
^ | |
../src/iodefine.h:5159:16: note: no known conversion for argument 1 from 'uint8_t {aka unsigned char}' to 'const st_rspi::<anonymous union>::<anonymous struct>&' | |
In file included from ../src/test.cpp:20:0: | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:122:34: error: invalid cast from type 'volatile st_rspi::<anonymous union>::<anonymous struct>' to type 'uint8_t {aka unsigned char}' | |
return (uint8_t)rspidrv->SPDR.WORD; | |
^ | |
C:\Renesas\workspace\test\src/RSPI_RX210.h: In instantiation of 'uint16_t RSPI_RX210<rspi_instance>::transfer16(uint16_t) [with unsigned int rspi_instance = 0u; uint16_t = short unsigned int]': | |
../src/test.cpp:64:1: required from here | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:148:23: error: no match for 'operator=' (operand types are 'volatile st_rspi::<anonymous union>::<anonymous struct>' and 'uint16_t {aka short unsigned int}') | |
rspidrv->SPDR.WORD = inw; | |
^ | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:148:23: note: candidate is: | |
In file included from ../src/test.cpp:19:0: | |
../src/iodefine.h:5159:16: note: st_rspi::<anonymous union>::<anonymous struct>& st_rspi::<anonymous union>::<anonymous struct>::operator=(const st_rspi::<anonymous union>::<anonymous struct>&) | |
struct { | |
^ | |
../src/iodefine.h:5159:16: note: no known conversion for argument 1 from 'uint16_t {aka short unsigned int}' to 'const st_rspi::<anonymous union>::<anonymous struct>&' | |
In file included from ../src/test.cpp:20:0: | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:151:35: error: invalid cast from type 'volatile st_rspi::<anonymous union>::<anonymous struct>' to type 'uint16_t {aka short unsigned int}' | |
return (uint16_t)rspidrv->SPDR.WORD; | |
^ | |
C:\Renesas\workspace\test\src/RSPI_RX210.h: In instantiation of 'uint16_t RSPI_RX210<rspi_instance>::transfer9(uint16_t) [with unsigned int rspi_instance = 0u; uint16_t = short unsigned int]': | |
../src/test.cpp:64:1: required from here | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:134:23: error: no match for 'operator=' (operand types are 'volatile st_rspi::<anonymous union>::<anonymous struct>' and 'uint16_t {aka short unsigned int}') | |
rspidrv->SPDR.WORD = inw; | |
^ | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:134:23: note: candidate is: | |
In file included from ../src/test.cpp:19:0: | |
../src/iodefine.h:5159:16: note: st_rspi::<anonymous union>::<anonymous struct>& st_rspi::<anonymous union>::<anonymous struct>::operator=(const st_rspi::<anonymous union>::<anonymous struct>&) | |
struct { | |
^ | |
../src/iodefine.h:5159:16: note: no known conversion for argument 1 from 'uint16_t {aka short unsigned int}' to 'const st_rspi::<anonymous union>::<anonymous struct>&' | |
In file included from ../src/test.cpp:20:0: | |
C:\Renesas\workspace\test\src/RSPI_RX210.h:137:35: error: invalid cast from type 'volatile st_rspi::<anonymous union>::<anonymous struct>' to type 'uint16_t {aka short unsigned int}' | |
return (uint16_t)rspidrv->SPDR.WORD; | |
^ | |
src/subdir.mk:38: recipe for target 'src/test.o' failed | |
make: *** [src/test.o] Error 1 | |
17:10:21 Build Finished (took 530ms) | |
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
struct st_rspi { | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPMS:1; | |
unsigned char TXMD:1; | |
unsigned char MODFEN:1; | |
unsigned char MSTR:1; | |
unsigned char SPEIE:1; | |
unsigned char SPTIE:1; | |
unsigned char SPE:1; | |
unsigned char SPRIE:1; | |
} BIT; | |
} SPCR; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SSL0P:1; | |
unsigned char SSL1P:1; | |
unsigned char SSL2P:1; | |
unsigned char SSL3P:1; | |
unsigned char :4; | |
} BIT; | |
} SSLP; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPLP:1; | |
unsigned char SPLP2:1; | |
unsigned char :2; | |
unsigned char MOIFV:1; | |
unsigned char MOIFE:1; | |
unsigned char :2; | |
} BIT; | |
} SPPCR; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char OVRF:1; | |
unsigned char IDLNF:1; | |
unsigned char MODF:1; | |
unsigned char PERF:1; | |
unsigned char :4; | |
} BIT; | |
} SPSR; | |
union { | |
unsigned long LONG; | |
struct { | |
unsigned short H; | |
} WORD; | |
} SPDR; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPSLN:3; | |
unsigned char :5; | |
} BIT; | |
} SPSCR; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPCP:3; | |
unsigned char :1; | |
unsigned char SPECM:3; | |
unsigned char :1; | |
} BIT; | |
} SPSSR; | |
unsigned char SPBR; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPFC:2; | |
unsigned char :2; | |
unsigned char SPRDTD:1; | |
unsigned char SPLW:1; | |
unsigned char :2; | |
} BIT; | |
} SPDCR; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SCKDL:3; | |
unsigned char :5; | |
} BIT; | |
} SPCKD; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SLNDL:3; | |
unsigned char :5; | |
} BIT; | |
} SSLND; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPNDL:3; | |
unsigned char :5; | |
} BIT; | |
} SPND; | |
union { | |
unsigned char BYTE; | |
struct { | |
unsigned char SPPE:1; | |
unsigned char SPOE:1; | |
unsigned char SPIIE:1; | |
unsigned char PTE:1; | |
unsigned char :4; | |
} BIT; | |
} SPCR2; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD0; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD1; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD2; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD3; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD4; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD5; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD6; | |
union { | |
unsigned short WORD; | |
struct { | |
unsigned short CPHA:1; | |
unsigned short CPOL:1; | |
unsigned short BRDV:2; | |
unsigned short SSLA:3; | |
unsigned short SSLKP:1; | |
unsigned short SPB:4; | |
unsigned short LSBF:1; | |
unsigned short SPNDEN:1; | |
unsigned short SLNDEN:1; | |
unsigned short SCKDEN:1; | |
} BIT; | |
} SPCMD7; | |
}; |
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
/* | |
* RSPI_RX210.h | |
* | |
* Created on: Sep 8, 2015 | |
* Author: ebrundick | |
*/ | |
#ifndef RSPI_RX210_H | |
#define RSPI_RX210_H | |
#define NEVER_INLINE __attribute__((noinline)) | |
#define ALWAYS_INLINE __attribute__((inline)) | |
#include <SPI.h> | |
#include <iodefine.h> | |
#define PCLK_CPU 25000000UL | |
enum rspi_instance { | |
RSPI_INSTANCE_0 = 0, | |
}; | |
template < | |
const unsigned int rspi_instance | |
> | |
class RSPI_RX210 : public SPIClass { | |
private: | |
static volatile struct st_rspi *rspidrv; | |
SPISettings _settings, _settings_old; | |
boolean _transaction_semaphore; | |
int _mask_irq; | |
public: | |
NEVER_INLINE | |
RSPI_RX210() { | |
rspidrv = &RSPI0; | |
}; | |
NEVER_INLINE | |
void begin(void) { | |
_mask_irq = 0; | |
rspidrv->SPCR.BYTE = BIT0 | BIT3; // 3-wire SPI, Full-Duplex, no interrupts, Disabled | |
rspidrv->SPPCR.BYTE = BIT5; // MOSI at rest = 0 | |
rspidrv->SPSCR.BYTE = 0x00; // Repeat SPCMD0 continuously | |
configClock(_settings._clock); | |
rspidrv->SPDCR.BYTE = 0x00; // Simple 1-frame buffer mode | |
rspidrv->SPCKD.BYTE = 0x00; // Minimal delay before SCK generation | |
rspidrv->SPCR2.BYTE = 0x00; // No parity | |
configMode(_settings._bitorder, _settings._datamode); // This sets SPCR.SPE = Enabled! | |
// Ready to roll! | |
}; | |
NEVER_INLINE | |
void configClock(uint32_t bitrate) { | |
uint32_t i, div = PCLK_CPU / bitrate; | |
for (i = 0; i < 256; i++) { | |
uint32_t thisbr = PCLK_CPU / (2 * (i+1)); | |
if (thisbr <= bitrate) { | |
rspidrv->SPBR = (uint8_t)thisbr; | |
return; | |
} | |
} | |
rspidrv->SPBR = 255; // SPBR happens not to be bitfielded. | |
}; | |
NEVER_INLINE | |
void configMode(uint8_t bitorder, uint8_t mode) { | |
uint16_t cmd = 0x0000; | |
if (bitorder != MSBFIRST) | |
cmd |= BITC; // RSPI LSB First | |
switch (mode) { | |
case SPI_MODE1: | |
cmd |= BIT0; // CPOL=0, CPHA=1 | |
break; | |
case SPI_MODE2: | |
cmd |= BIT1; // CPOL=1, CPHA=0 | |
break; | |
case SPI_MODE3: | |
cmd |= BIT0 | BIT1; // CPOL=1, CPHA=1 | |
break; | |
default: // SPI mode0 = CPOL=0, CPHA=0 | |
break; | |
} | |
rspidrv->SPCMD0.WORD = cmd; | |
}; | |
NEVER_INLINE | |
void end(void) { | |
rspidrv->SPCR.BYTE = 0x00; // Disable | |
}; | |
NEVER_INLINE | |
void setBitOrder(unsigned int msblsb) { | |
_settings._bitorder = msblsb; | |
rspidrv->SPCR.BIT.SPE = 0; | |
configMode(_settings._bitorder, _settings._datamode); | |
rspidrv->SPCR.BIT.SPE = 1; | |
}; | |
NEVER_INLINE | |
void setDataMode(unsigned int mode) { | |
_settings._datamode = mode; | |
rspidrv->SPCR.BIT.SPE = 0; | |
configMode(_settings._bitorder, _settings._datamode); | |
rspidrv->SPCR.BIT.SPE = 1; | |
} | |
// Data transfer | |
#define RSPI_SPCMD_FRAMESIZE_BITS (BIT8 | BIT9 | BITA | BITB) | |
NEVER_INLINE | |
uint8_t transfer(uint8_t inb) { | |
uint16_t cmd = rspidrv->SPCMD0.WORD; | |
if ( (cmd & RSPI_SPCMD_FRAMESIZE_BITS) != BITA ) { | |
// SPI currently not set to 8-bit mode; change this | |
cmd &= ~RSPI_SPCMD_FRAMESIZE_BITS; | |
cmd |= BITA; // 8 bits per transfer | |
rspidrv->SPCMD0.WORD = cmd; | |
} | |
rspidrv->SPDR.WORD = inb; | |
while (rspidrv->SPSR.BIT.IDLNF) | |
; // Waiting for RSPI to go Idle... | |
return (uint8_t)rspidrv->SPDR.WORD; | |
}; | |
NEVER_INLINE | |
uint16_t transfer9(uint16_t inw) { | |
uint16_t cmd = rspidrv->SPCMD0.WORD; | |
if ( (cmd & RSPI_SPCMD_FRAMESIZE_BITS) != BITB ) { | |
// SPI currently not set to 9-bit mode; change this | |
cmd &= ~RSPI_SPCMD_FRAMESIZE_BITS; | |
cmd |= BITB; // 9 bits per transfer | |
rspidrv->SPCMD0.WORD = cmd; | |
} | |
rspidrv->SPDR.WORD = inw; | |
while (rspidrv->SPSR.BIT.IDLNF) | |
; // Waiting for RSPI to go Idle... | |
return (uint16_t)rspidrv->SPDR.WORD; | |
}; | |
NEVER_INLINE | |
uint16_t transfer16(uint16_t inw) { | |
uint16_t cmd = rspidrv->SPCMD0.WORD; | |
if ( (cmd & RSPI_SPCMD_FRAMESIZE_BITS) != RSPI_SPCMD_FRAMESIZE_BITS ) { | |
// SPI currently not set to 9-bit mode; change this | |
cmd |= RSPI_SPCMD_FRAMESIZE_BITS; // 16 bits per transfer | |
rspidrv->SPCMD0.WORD = cmd; | |
} | |
rspidrv->SPDR.WORD = inw; | |
while (rspidrv->SPSR.BIT.IDLNF) | |
; // Waiting for RSPI to go Idle... | |
return (uint16_t)rspidrv->SPDR.WORD; | |
}; | |
bool hasExtendedAPI(void) { return true; }; | |
NEVER_INLINE | |
bool beginTransaction(SPISettings settings) { | |
// for atomicity in semaphore check | |
__builtin_rx_clrpsw(8); // Disable Global Interrupts | |
if (_transaction_semaphore) { | |
__builtin_rx_setpsw(8); // Enable interrupts | |
return false; | |
} | |
_transaction_semaphore = true; | |
// TODO: Disable masked IRQ if _mask_irq is set to something valid | |
if (_mask_irq != 255) | |
__builtin_rx_setpsw(8); // Enable interrupts | |
_settings_old.copy(_settings); | |
_settings.copy(settings); | |
configClock(_settings._clock); | |
configMode(_settings._bitorder, _settings._datamode); | |
return true; | |
}; | |
NEVER_INLINE | |
void endTransaction(void) { | |
__builtin_rx_clrpsw(8); // Disable Global Interrupts | |
_transaction_semaphore = false; | |
// TODO: Unmask gpio IRQ | |
// Restore SPI settings under PSW(8)=CLR protection in case an IRQ fires which | |
// uses SPI and expects the default SPISettings to be intact. | |
_settings.copy(_settings_old); | |
configClock(_settings._clock); | |
configMode(_settings._bitorder, _settings._datamode); | |
__builtin_rx_setpsw(8); // Enable interrupts | |
}; | |
NEVER_INLINE | |
void usingInterrupt(int pin) { ; }; // TODO | |
}; | |
#endif /* RSPI_RX210_H */ |
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
/***************************************************************/ | |
/* */ | |
/* PROJECT NAME : test */ | |
/* FILE : test.cpp */ | |
/* DESCRIPTION : Main Program */ | |
/* CPU SERIES : RX200 */ | |
/* CPU TYPE : RX210 */ | |
/* */ | |
/* This file is generated by e2 studio. */ | |
/* */ | |
/***************************************************************/ | |
/************************************************************************/ | |
/* File Version: V1.00 */ | |
/* Date Generated: 08/07/2013 */ | |
/************************************************************************/ | |
#include "iodefine.h" | |
#include <RSPI_RX210.h> | |
RSPI_RX210<RSPI_INSTANCE_0> SPI; | |
#ifdef CPPAPP | |
//Initialize global constructors | |
extern "C" void __main() | |
{ | |
static int initialized; | |
if (! initialized) | |
{ | |
typedef void (*pfunc) (); | |
extern pfunc __ctors[]; | |
extern pfunc __ctors_end[]; | |
pfunc *p; | |
initialized = 1; | |
for (p = __ctors_end; p > __ctors; ) | |
(*--p) (); | |
} | |
} | |
#endif | |
int main(void) | |
{ | |
// TODO: add application code here | |
/* P17 = LED0 | |
* P16 = LED1 | |
* P15 = LED2 | |
*/ | |
SPI.begin(); | |
PORT1.PDR.BYTE |= BIT5 | BIT6 | BIT7; | |
PORT1.PMR.BYTE &= ~(BIT5 | BIT6 | BIT7); | |
PORT1.DSCR.BYTE |= BIT5 | BIT6 | BIT7; | |
while (1) { | |
static unsigned int i = 0; | |
PORT1.PODR.BYTE = BIT6; | |
SPI.transfer(0); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment