diff --git a/SPI.c b/SPI.c index 224d7d4..16ad8ad 100644 --- a/SPI.c +++ b/SPI.c @@ -1,65 +1,90 @@ -#include -#include "SPI.h" - -uchar SPI_CS; - -int SPIInit(){ - - UCA0CTL1 = UCSWRST; - - // setup A0 for SPI - UCA0CTL0 = SPI_Mode3 | UCMSB | UCMST | (0x10 << 1) | UCSYNC; - UCA0CTL1 |= UCSSEL_2; - UCA0BR1 = 0; //TODO: set corect frequency - UCA0BR0 = 4; - - - // config port - //set SEL to USCI (0b01); MOSI (pin 1), MISO (pin 2), CLK (pin 4) - P1SEL |= BIT1 | BIT2 | BIT4; - P1SEL2 |= BIT1 | BIT2 | BIT4; - - - UCA0CTL1 &= ~UCSWRST; - - // enable interrupts - IE2 |= UCA0TXIE; - IFG2 &= ~UCA0TXIFG; - - // set initial values for vars - SPI_packetC = 0; - SPI_CS = 0; - - __enable_interrupt(); - - return 0; -} - -void SPISend(){ - P1OUT &= ~SPI_CS; - UCA0TXBUF = SPI_packet[SPI_packetC]; -} - -void SPIInitSend(uchar cs, enum SPI_Mode mode){ - while(SPI_CS != 0) - //TODO: search for a more power effient way for a delay - __delay_cycles (16000); - - UCA0CTL0 |= mode; - UCA0CTL0 &= ~mode ^ 0xC0; - SPI_CS = cs; -} - -#pragma vector = USCIAB0TX_VECTOR -__interrupt void ISR_EUSCI_A0(){ - SPI_packet[SPI_packetC] = UCA0RXIFG; - if(SPI_packetC == 4){ - P1OUT |= SPI_CS; - SPI_packetC = 0; - IFG2 &= ~UCA0TXIFG; - SPI_CS = 0; - }else{ - SPI_packetC++; - UCA0TXBUF = SPI_packet[SPI_packetC]; - } -} +#include +#include "SPI.h" + +uchar SPI_CS = 0; + +int SPIInit(){ + + UCA0CTL1 = UCSWRST; + + // setup A0 for SPI + UCA0CTL0 = UCMSB | UCMST | (0x10 << 1) | UCSYNC; + UCA0CTL1 |= UCSSEL_2; + UCA0BR1 = 0; + UCA0BR0 = 16; // 1 MHz + + + // config port + //set SEL to USCI (0b01); MOSI (pin 1), MISO (pin 2), CLK (pin 4) + P1SEL |= BIT1 | BIT2 | BIT4; + P1SEL2 |= BIT1 | BIT2 | BIT4; + + + UCA0CTL1 &= ~UCSWRST; + + // enable interrupts + // IE2 |= UCA0TXIE; + // IFG2 &= ~UCA0TXIFG; + + // set initial values for vars + SPI_packetC = 0; + SPI_CS = 0; + + __enable_interrupt(); + + return 0; +} + +//TODO: add clock freqency configuration +/* + * do some configuration before sending the data. + * + * @arg uchar cs: the bit of port 1 connected to the chip select pin of target device + * @arg enum SPI_Mode: the SPI modus (clock pase and polarity) + * @arg enum SPI_clock: the clock freqency + */ +void SPIInitSend(uchar cs, enum SPI_Mode mode, enum SPI_Clock clk){ + //TODO: add a clock as powerefficent delay + while(SPI_CS != 0); // wait for last transmit to be done + + // set clock frequency + UCA0BR0 = clk; + + // set SPI mode + UCA0CTL0 &= 0x3F; // set mode bits to 0 + UCA0CTL0 |= mode; + + // save chip select + SPI_CS = cs; +} + +//TODO: make it asyncronily with interupt. +/* + * Send the packet stored in SPI_packet. it start from SPI_packetC to the last byte + */ +void SPISend(){ + P1OUT &= ~SPI_CS; // select slave + + while(SPI_packetC < 5){ + // send one byte + UCA0TXBUF = SPI_packet[SPI_packetC]; + + //TODO: fix the delay! it's to short with low data speeds + if(UCA0BR0 > 4) + // if de frequency lower than 4 MHz do a manual delay. this is a workaround for the to short delay + // this works down to 1 MHz + __delay_cycles(129); + else + while(UCB0STAT & UCBUSY); // wait for SPI TX/RX to finish + + // save recieved data + SPI_packet[SPI_packetC] = UCA0RXIFG; + + // increase counter for next byte + SPI_packetC++; + } + + SPI_packetC = 0; // recet counter + P1OUT |= SPI_CS; // deselect slave + SPI_CS = 0; +} diff --git a/SPI.h b/SPI.h index 8578609..f9ed216 100644 --- a/SPI.h +++ b/SPI.h @@ -1,22 +1,23 @@ -/* - * SPI.c - * - * Created on: 4 mei 2020 - * Author: mreenen - */ - -#ifndef SPI_C_ -#define SPI_C_ - -#include "typedefExtention.h" - -enum SPI_Mode {SPI_Mode0=0b00<<6, SPI_Mode1=0b10<<6, SPI_Mode2=0b11<<6, SPI_Mode3=0b01<<6}; - -uchar SPI_packet[5]; -char SPI_packetC; - -int SPIInit(); -void SPISend(); -void SPIInitSend(uchar cs, enum SPI_Mode mode); - -#endif /* SPI_C_ */ +/* + * SPI.c + * + * Created on: 4 mei 2020 + * Author: mreenen + */ + +#ifndef SPI_C_ +#define SPI_C_ + +#include "typedefExtention.h" + +enum SPI_Mode {SPI_Mode0=0b00<<6, SPI_Mode1=0b10<<6, SPI_Mode2=0b11<<6, SPI_Mode3=0b01<<6}; +enum SPI_Clock {SPI_Clock_1MHz=16, SPI_Clock_2MHz=8, SPI_Clock_4MHz=4, SPI_Clock_8MHz=2}; + +uchar SPI_packet[5]; +char SPI_packetC; + +int SPIInit(); +void SPISend(); +void SPIInitSend(uchar cs, enum SPI_Mode mode, enum SPI_Clock clk); + +#endif /* SPI_C_ */ diff --git a/motionController.c b/motionController.c index 836c09e..fbfcad9 100644 --- a/motionController.c +++ b/motionController.c @@ -88,7 +88,7 @@ void MC_write(uchar addr, ulong data) { char i; // wait for SPI bus to be available - SPIInitSend(MC_CS, SPI_Mode3); + SPIInitSend(MC_CS, SPI_Mode3, SPI_Clock_1MHz); // set write bit to write addr &= ~0x01; @@ -109,7 +109,7 @@ ulong MC_read(unsigned char addr) { ulong data; // wait for SPI bus to be available - SPIInitSend(MC_CS, SPI_Mode3); + SPIInitSend(MC_CS, SPI_Mode3, SPI_Clock_1MHz); // set write bit to read addr |= 0x01; @@ -119,7 +119,7 @@ ulong MC_read(unsigned char addr) { SPISend(); // wait for SPI bus to be available - SPIInitSend(MC_CS, SPI_Mode3); + SPIInitSend(MC_CS, SPI_Mode3, SPI_Clock_1MHz); // set write bit to read addr |= 0x01; diff --git a/motorDriver.c b/motorDriver.c index 96454eb..bb876f8 100644 --- a/motorDriver.c +++ b/motorDriver.c @@ -1,124 +1,124 @@ -/* - * motorDriver.c - * - * Created on: 4 mei 2020 - * Author: mreenen - */ - -#include -#include "typedefExtention.h" -#include "SPI.h" -#include "motorDriver.h" - -const uchar MD_CS = BIT3; - -// register 0x00 GCINF -#define MD_GCONF 0X00 -#define MD_GCONF_singgelMotor 0x00000001 -#define MD_GCONF_stepdir1Enable 0x00000002 -#define MD_GCONF_stepdir2Enable 0x00000004 -#define MD_GCONF_motor1Revers 0x00000010 -#define MD_GCONF_motor1Revers 0x00000010 -#define MD_GCONF_lockGCONF 0x00000020 - -// register 0x01 GSTAT -#define MD_GSTAT 0X01 - -// register 0x30, 0x50 IHOLD_IRUN -#define MD_IHIR1 0x30 -#define MD_IHIR2 0x50 -#define MD_IHIR_iHold 0 -#define MD_IHIR_iRun 8 -#define md_IHIR_iHoldDelay 16ul - -// register 0x6C, 7C CHOPCONF -#define MD_CC1 0X6C -#define MD_CC2 0X7C -#define MD_CC_shortProtection 0x40000000 -#define MD_CC_doubbleEdge 0x20000000 -#define MD_CC_16ustapI 0x10000000 -#define MD_CC_mres 24 // 4 bits; 1/(2^x / 2^8) microstappen -#define MD_CC_vsens 0x00020000 -#define MD_CC_tbl 15 // 3 bits? -#define MD_CC_cmh BIT14 -#define MD_CC_rndtf 0x00002000 -#define MD_CC_disfdcc 0x00001000 -#define MD_CC_fd3 BTI11 -#define MD_CC_hend 7 // 4 bits -#define MD_CC_hstrt 4 // 3 bits -#define MD_CC_toff 0 // 4 bits - -// bool md_checkError(){ -// unsigned long stat = md_read(MD_GSTAT); -// if(stat != 0){ -// if(stat == 0x1){ // only a recet has occert -// // restart the motor driver -// md_setup(); -// }else{ // one of the motorst stopt due to short or overheated or a undervoltage in chargepump -// // wait a while for checking again -// delay(1000); -// md_checkError(); -// } -// return true; -// } -// return false; -// } - -void MD_write(uchar addr, ulong data) { - char i; - - // wait for SPI bus to be available - SPIInitSend(MD_CS, SPI_Mode3); - - // set write bit to write - addr |= 0x80; - SPI_packet[0] = addr; - - // save data to packet buffer - for(i=4; i>0; i--){ - SPI_packet[i] = data; - data >>= 8; - } - - SPISend(SPI_Mode3); -} - - -unsigned long MD_read(uchar addr) { - char i; - ulong data; - - // wait for SPI bus to be available - SPIInitSend(MD_CS, SPI_Mode3); - - // set write bit to read - addr &= ~0x80; - SPI_packet[0] = addr; - - SPISend(SPI_Mode3); - - // wait for SPI bus to be available - SPIInitSend(MD_CS, SPI_Mode3); - - SPI_packet[0] = addr; - SPISend(SPI_Mode3); - - // read data - for(i=2; i<5; i++){ - data |= (ulong) SPI_packet[i]; - data <<= 8; - } - - return data; -} - -void MDInit(){ - P1DIR |= MD_CS; // set MD_CS (pin 3) as output - P1OUT |= MD_CS; // set MD_CS high - - MD_write(MD_GCONF, MD_GCONF_stepdir2Enable | MD_GCONF_stepdir1Enable); - MD_write(MD_CC1, 3ul< +#include "typedefExtention.h" +#include "SPI.h" +#include "motorDriver.h" + +const uchar MD_CS = BIT3; + +// register 0x00 GCINF +#define MD_GCONF 0X00 +#define MD_GCONF_singgelMotor 0x00000001 +#define MD_GCONF_stepdir1Enable 0x00000002 +#define MD_GCONF_stepdir2Enable 0x00000004 +#define MD_GCONF_motor1Revers 0x00000010 +#define MD_GCONF_motor1Revers 0x00000010 +#define MD_GCONF_lockGCONF 0x00000020 + +// register 0x01 GSTAT +#define MD_GSTAT 0X01 + +// register 0x30, 0x50 IHOLD_IRUN +#define MD_IHIR1 0x30 +#define MD_IHIR2 0x50 +#define MD_IHIR_iHold 0 +#define MD_IHIR_iRun 8 +#define md_IHIR_iHoldDelay 16ul + +// register 0x6C, 7C CHOPCONF +#define MD_CC1 0X6C +#define MD_CC2 0X7C +#define MD_CC_shortProtection 0x40000000 +#define MD_CC_doubbleEdge 0x20000000 +#define MD_CC_16ustapI 0x10000000 +#define MD_CC_mres 24 // 4 bits; 1/(2^x / 2^8) microstappen +#define MD_CC_vsens 0x00020000 +#define MD_CC_tbl 15 // 3 bits? +#define MD_CC_cmh BIT14 +#define MD_CC_rndtf 0x00002000 +#define MD_CC_disfdcc 0x00001000 +#define MD_CC_fd3 BTI11 +#define MD_CC_hend 7 // 4 bits +#define MD_CC_hstrt 4 // 3 bits +#define MD_CC_toff 0 // 4 bits + +// bool md_checkError(){ +// unsigned long stat = md_read(MD_GSTAT); +// if(stat != 0){ +// if(stat == 0x1){ // only a recet has occert +// // restart the motor driver +// md_setup(); +// }else{ // one of the motorst stopt due to short or overheated or a undervoltage in chargepump +// // wait a while for checking again +// delay(1000); +// md_checkError(); +// } +// return true; +// } +// return false; +// } + +void MD_write(uchar addr, ulong data) { + char i; + + // wait for SPI bus to be available + SPIInitSend(MD_CS, SPI_Mode3, SPI_Clock_4MHz); + + // set write bit to write + addr |= 0x80; + SPI_packet[0] = addr; + + // save data to packet buffer + for(i=4; i>0; i--){ + SPI_packet[i] = data; + data >>= 8; + } + + SPISend(SPI_Mode3); +} + + +unsigned long MD_read(uchar addr) { + char i; + ulong data; + + // wait for SPI bus to be available + SPIInitSend(MD_CS, SPI_Mode3, SPI_Clock_4MHz); + + // set write bit to read + addr &= ~0x80; + SPI_packet[0] = addr; + + SPISend(SPI_Mode3); + + // wait for SPI bus to be available + SPIInitSend(MD_CS, SPI_Mode3, SPI_Clock_4MHz); + + SPI_packet[0] = addr; + SPISend(SPI_Mode3); + + // read data + for(i=2; i<5; i++){ + data |= (ulong) SPI_packet[i]; + data <<= 8; + } + + return data; +} + +void MDInit(){ + P1DIR |= MD_CS; // set MD_CS (pin 3) as output + P1OUT |= MD_CS; // set MD_CS high + + MD_write(MD_GCONF, MD_GCONF_stepdir2Enable | MD_GCONF_stepdir1Enable); + MD_write(MD_CC1, 3ul<