diff --git a/src/energenie/drv/build_mac b/src/energenie/drv/build_mac index 948f30c..95781bd 100755 --- a/src/energenie/drv/build_mac +++ b/src/energenie/drv/build_mac @@ -9,9 +9,9 @@ # build spis_test (soft SPI tester) -##gcc spi_test.c spis.c gpio_sim.c delay_posix.c -##mv a.out spis_test -##chmod u+x spis_test +gcc spi_test.c spis.c gpio_sim.c delay_posix.c +mv a.out spis_test +chmod u+x spis_test # build spih_test (hard SPI tester) diff --git a/src/energenie/drv/gpio_sim.c b/src/energenie/drv/gpio_sim.c index 22d5473..c8ce63e 100644 --- a/src/energenie/drv/gpio_sim.c +++ b/src/energenie/drv/gpio_sim.c @@ -42,7 +42,7 @@ { #if defined(GPIO_DEBUG) //printf("gpio:in:%d\n", g); - OUTS("gpio:in"); + OUTS("gpio:in:"); OUTN(g); NL(); #endif @@ -81,7 +81,7 @@ { #if defined(GPIO_DEBUG) //printf("gpio:low:%d\n", g); - OUTS("gpio:low"); + OUTS("gpio:low:"); OUTN(g); NL(); #endif diff --git a/src/energenie/drv/spi_test.c b/src/energenie/drv/spi_test.c index 4fe2332..56f44ca 100644 --- a/src/energenie/drv/spi_test.c +++ b/src/energenie/drv/spi_test.c @@ -11,9 +11,11 @@ #include #include +#include "system.h" #include "gpio.h" #include "spi.h" +//TODO: printfs will not work on Arduino /***** CONSTANTS *****/ @@ -36,8 +38,8 @@ unsigned char cmd_id2[4] = {0x30, 0x00, 0x02, 0x00}; unsigned char rx[4]; - SPI_CONFIG spiConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, - {0,TSETTLE},{0,THOLD},{0,TFREQ}}; + SPI_CONFIG spiConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0}; + //{0,TSETTLE},{0,THOLD},{0,TFREQ}}; int i; unsigned char id[3]; @@ -45,7 +47,7 @@ /* Init */ printf("init\n"); - //gpio_init(); + //gpio_init(); done by spi_init() spi_init(&spiConfig); diff --git a/src/energenie/drv/spis.c b/src/energenie/drv/spis.c new file mode 100644 index 0000000..5e05a0c --- /dev/null +++ b/src/energenie/drv/spis.c @@ -0,0 +1,155 @@ +/* spis.c D.J.Whale 19/07/2014 + * + * Software SPI driver built on top of gpio + */ + + +/***** INCLUDES *****/ + +#include +#include +#include + +#include "system.h" +#include "spi.h" +#include "gpio.h" +#include "delay.h" + + +/***** MACROS *****/ + +#define CLOCK_ACTIVE() gpio_write(config.sclk, config.cpol?0:1) +#define CLOCK_IDLE() gpio_write(config.sclk, config.cpol?1:0) + +#define SELECTED() gpio_write(config.cs, config.spol?1:0) +#define NOT_SELECTED() gpio_write(config.cs, config.spol?0:1) + +//TODO: Posix specific, won't work on Arduino +#define FAIL(msg) do { \ + fprintf(stderr, "%s", msg); \ + exit(-1); \ +} while (0) + + +/***** VARIABLES *****/ + +static SPI_CONFIG config; + + +void spi_init_defaults(void) +{ +#define CS 7 //CE1 +#define SCLK 11 +#define MOSI 10 +#define MISO 9 + +/* ms */ +#define TSETTLE (1) /* us settle */ +#define THOLD (1) /* us hold */ +#define TFREQ (1) /* us half clock */ + + SPI_CONFIG defaultConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, + TSETTLE, THOLD, TFREQ}; + + spi_init(&defaultConfig); +} + + +void spi_init(SPI_CONFIG* pConfig) +{ + /* It's a standalone library, so init GPIO also */ + gpio_init(); + memcpy(&config, pConfig, sizeof(SPI_CONFIG)); + + //TODO: Implement CPHA1 + if (config.cpha != 0) + { + FAIL("error: CPHA 1 not yet supported"); + } + + gpio_setout(config.sclk); + CLOCK_IDLE(); + + gpio_setout(config.mosi); + gpio_low(config.mosi); + gpio_setin(config.miso); + + gpio_setout(config.cs); + NOT_SELECTED(); +} + + +void spi_finished(void) +{ + gpio_setin(config.mosi); + gpio_setin(config.sclk); + gpio_setin(config.cs); +} + + +void spi_select(void) +{ + SELECTED(); + delayus(config.tSettle); +} + + +void spi_deselect(void) +{ + NOT_SELECTED(); + delayus(config.tSettle); +} + + +int spi_byte(uint8_t txbyte) +{ + uint8_t rxbyte = 0; + uint8_t bitno; + uint8_t bit ; + + //TODO: Implement CPHA1 + + for (bitno=0; bitno<8; bitno++) + { + /* Transmit MSB first */ + bit = ((txbyte & 0x80) != 0x00); + txbyte <<= 1; + gpio_write(config.mosi, bit); + delayus(config.tSettle); + CLOCK_ACTIVE(); + delayus(config.tHold); + delayus(config.tFreq); + + /* Read MSB first */ + bit = gpio_read(config.miso); + rxbyte = (rxbyte<<1) | bit; + + CLOCK_IDLE(); + delayus(config.tFreq); + } + return rxbyte; +} + + +void spi_frame(uint8_t* pTx, uint8_t* pRx, uint8_t count) +{ + uint8_t tx = 0; + uint8_t rx; + + while (count > 0) + { + if (pTx != NULL) + { + tx = *(pTx++); + } + rx = spi_byte(tx); + if (pRx != NULL) + { + *(pRx++) = rx; + } + count--; + } +} + + +/***** END OF FILE *****/ diff --git a/src/energenie/drv/spis_rpi.c b/src/energenie/drv/spis_rpi.c deleted file mode 100644 index 1b82e8a..0000000 --- a/src/energenie/drv/spis_rpi.c +++ /dev/null @@ -1,176 +0,0 @@ -/* spis.c (soft SPI) D.J.Whale 19/07/2014 - */ - - -/***** INCLUDES *****/ - -#include -#include -//#include -#include // Won't work on Arduino -#include - -#include "system.h" -#include "spi.h" -#include "gpio.h" - - -/***** MACROS *****/ - -#define CLOCK_ACTIVE() gpio_write(config.sclk, config.cpol?0:1) -#define CLOCK_IDLE() gpio_write(config.sclk, config.cpol?1:0) - -#define SELECTED() gpio_write(config.cs, config.spol?1:0) -#define NOT_SELECTED() gpio_write(config.cs, config.spol?0:1) - - -/***** VARIABLES *****/ - -static SPI_CONFIG config; - - -/* Based on code suggested by Gordon Henderson: - * https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c - * - * Note that his trick of using the hardware timer just didn't work, - * and this is the best of a bad bunch. nanosleep() delays at least - * 100uS in some cases. - */ - -//TODO: This is raspberry pi specific -//Put it in a delay.h delay_rpi.h?? - -static void delayus(unsigned int us) -{ - struct timeval tNow, tLong, tEnd; - - gettimeofday(&tNow, NULL); - tLong.tv_sec = us / 1000000; - tLong.tv_usec = us % 1000000; - timeradd(&tNow, &tLong, &tEnd); - - while (timercmp(&tNow, &tEnd, <)) - { - gettimeofday(&tNow, NULL); - } -} - - -void spi_init_defaults(void) -{ -#define CS 7 //CE1 -#define SCLK 11 -#define MOSI 10 -#define MISO 9 - -/* ms */ -#define TSETTLE (1) /* us settle */ -#define THOLD (1) /* us hold */ -#define TFREQ (1) /* us half clock */ - - SPI_CONFIG defaultConfig = {CS, SCLK, MOSI, MISO, SPI_SPOL0, SPI_CPOL0, SPI_CPHA0, - TSETTLE, THOLD, TFREQ}; - - spi_init(&defaultConfig); -} - - -void spi_init(SPI_CONFIG* pConfig) -{ - /* It's a standalone library, so init GPIO also */ - gpio_init(); - memcpy(&config, pConfig, sizeof(SPI_CONFIG)); - - //TODO: Implement CPHA1 - if (config.cpha != 0) - { - fprintf(stderr, "error: CPHA 1 not yet supported"); - exit(-1); - } - - gpio_setout(config.sclk); - CLOCK_IDLE(); - - gpio_setout(config.mosi); - gpio_low(config.mosi); - gpio_setin(config.miso); - - gpio_setout(config.cs); - NOT_SELECTED(); -} - - -void spi_finished(void) -{ - gpio_setin(config.mosi); - gpio_setin(config.sclk); - gpio_setin(config.cs); -} - - -void spi_select(void) -{ - SELECTED(); - delayus(config.tSettle); -} - - -void spi_deselect(void) -{ - NOT_SELECTED(); - delayus(config.tSettle); -} - - -int spi_byte(uint8_t txbyte) -{ - uint8_t rxbyte = 0; - uint8_t bitno; - uint8_t bit ; - - //TODO: Implement CPHA1 - - for (bitno=0; bitno<8; bitno++) - { - /* Transmit MSB first */ - bit = ((txbyte & 0x80) != 0x00); - txbyte <<= 1; - gpio_write(config.mosi, bit); - delayus(config.tSettle); - CLOCK_ACTIVE(); - delayus(config.tHold); - delayus(config.tFreq); - - /* Read MSB first */ - bit = gpio_read(config.miso); - rxbyte = (rxbyte<<1) | bit; - - CLOCK_IDLE(); - delayus(config.tFreq); - } - return rxbyte; -} - - -void spi_frame(uint8_t* pTx, uint8_t* pRx, uint8_t count) -{ - uint8_t tx = 0; - uint8_t rx; - - while (count > 0) - { - if (pTx != NULL) - { - tx = *(pTx++); - } - rx = spi_byte(tx); - if (pRx != NULL) - { - *(pRx++) = rx; - } - count--; - } -} - - -/***** END OF FILE *****/