/***************************************************************************
* EM430F6137RF900 + CMR3000 + SCA3100 viestien lähetys.
* Tämä puoli hoitaa viestien keräämisen antureilta ja lähettää arvot radion
* kautta toiselle laudalle. Laudassa on kiinni anturit CMR300 ja SCA3100. Kun radio-
* linkki on muodostettu lautojen välille syttyy vihreä ledi. Tämän jälkeen ohjelma jää
* odottamaan uutta tietoa antureilta. Anturien arvot luetaan aina kun CMR3000-anturi
* antaa keskeytyksen (interrupt), kun tiedot ovat valmiit. Tämän jälkeen luetaan anturien
* rekistereistä x, y ja z akselien arvot. Jokaisesta akselista luetaan LSB
* (vähiten merkitsevät) ja MSB (eniten merkitsevät) arvot. Arvot lähetetään
* radion kautta toiselle laudalle. Punainen ledi menee aina päälle kun uusi
* arvo antureilta on valmiina ja menee pois päältä kun viesti on lähetetty
* radion kautta eteenpäin.
*
* Anturien liitännät lautaan:
*
* Liitännät molemmissa antureissa:
*
* AVSS/DVSS = CON9 pin 1
* AVDD/DVDD = CON9 pin 5
* MISO = PORT1 pin 6
* MOSI = PORT1 pin 7
* SCK = PORT1 pin 8
*
* CMR3000:
* CSB = PORT2 pin 8
* INT = PORT2 pin 5
*
* SCA3100:
* CSB = PORT2 pin 7
*/
// LIBRARIES
#include "bsp.h"
#include "mrfi.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "cc430x613x.h"
#include "bsp_leds.h"
// SPI delays
#define XTAL 16000000L
#define TICKSPERMS (XTAL / 1000 / 5 - 1)
#define TICKSPERUS (TICKSPERMS / 1000)
#define SPICLOCK 600 //SPI clock = 500kHz
#define SPIFRAMEDELAY ((1000 / SPICLOCK) * 6) // SPI interframe delay [us] = 6 * Tsck
#define SPICSBDELAY ((1000 / SPICLOCK) / 2) // SCK -> CSB delay [us] = 0.5 * Tsck
static void linkTo(void);
static uint8_t sRxCallback(linkID_t);
static linkID_t sLinkID1 = 0;
#define SPIN_ABOUT_A_SECOND NWK_DELAY(1000)
char mode=0;
// PORT DEFINITIONS
#define PORT_CSB_OUT P2OUT
#define PORT_CSB_DIR P2DIR
//CMR3000 DEFINE
#define CMR3000_PORT_INT_IN P2IN
#define CMR3000_PORT_INT_OUT P2OUT
#define CMR3000_PORT_INT_DIR P2DIR
#define CMR3000_PORT_INT_IE P2IE
#define CMR3000_PORT_INT_IES P2IES
#define CMR3000_PORT_INT_IFG P2IFG
#define CMR3000_PORT_INT_VECTOR PORT2_VECTOR
#define CMR3000_PIN_INT BIT4
//CMR300 AXIS REG
#define CMR3000_X_LSB 0x0C
#define CMR3000_X_MSB 0x0D
#define CMR3000_Y_LSB 0x0E
#define CMR3000_Y_MSB 0x0F
#define CMR3000_Z_LSB 0x010
#define CMR3000_Z_MSB 0x11
#define CMR3000_PIN_CSB BIT7
//CMR3000 muuttujat
unsigned short CMR3000_x_msb;
unsigned short CMR3000_x_lsb;
short CMR3000_x_value;
unsigned short CMR3000_y_msb;
unsigned short CMR3000_y_lsb;
short CMR3000_y_value;
unsigned short CMR3000_z_msb;
unsigned short CMR3000_z_lsb;
short CMR3000_z_value;
unsigned char CMR3000_Data;
#define CTRL 0x02
#define RESET 0x80 // Set device in reset
#define INT_LEVEL_LOW 0x40 // INT active high
#define I2C_DIS 0x10 // I2C disabled
#define MODE_80 0x06 // Measurement mode BW=80 Hz
// SCA3100 init
// SCA3100 AXIS REG
#define SCA3100_X_LSB 0x04
#define SCA3100_X_MSB 0x05
#define SCA3100_Y_LSB 0x06
#define SCA3100_Y_MSB 0x07
#define SCA3100_Z_LSB 0x08
#define SCA3100_Z_MSB 0x09
#define SCA3100_PIN_CSB BIT6
//SCA3100 muuttujat
unsigned short SCA3100_x_msb;
unsigned short SCA3100_x_lsb;
short SCA3100_x_value;
unsigned short SCA3100_y_msb;
unsigned short SCA3100_y_lsb;
short SCA3100_y_value;
unsigned short SCA3100_z_msb;
unsigned short SCA3100_z_lsb;
short SCA3100_z_value;
//SPI init
#define TX_BUFFER UCA0TXBUF
#define RX_BUFFER UCA0RXBUF
#define SPI_CTL0 UCB0CTL0
#define SPI_CTL1 UCB0CTL1
#define SPI_BR0 UCB0BR0
#define SPI_BR1 UCB0BR1
//CMR3000 FUNCTION PROTOTYPES
unsigned char CMR3000_ReadRegister(unsigned char Address);
unsigned char CMR3000_WriteRegister(unsigned char Address, unsigned char Data);
//SCA3100 FUNKTION PROTOTYPES
unsigned char SCA3100_ReadRegister(unsigned char Address);
//COMMON FUNKTION PROTOTYPES
unsigned short realValues(unsigned short values);
void wait_ms(unsigned short ms);
void wait_us(unsigned short us);
void Init_CMR3000_SCA3100();
void Init_CMR3000();
void Init_SCA3100();
void Read_CMR3000_SCA3100();
void Read_CMR3000();
void Read_SCA3100();
// Tehdään tarvittavat alustukset ja muodostetaan linkki toiseen lautaan
void main(void)
{
BSP_Init(); // laudan alustus
SMPL_Init(sRxCallback); // radion ja SimpliciTI protokollan alustus
wait_ms(100);
while(1)
{
linkTo(); // muodostetaan yhteys toisen laudan kanssa ja jäädään odottamaan CMR3000 anturin interruptia
}
}
// Antureiden alustus
void Init_CMR3000_SCA3100()
{
WDTCTL = WDTPW+WDTHOLD; // sammuta watchdog timer
UCSCTL5 |= DIVS_3;
PMAPPWD = 0x02D52; // hanki kirjoitusoikeudet porttitaulukon registereihin
P1MAP6 = PM_UCA0SIMO; // UCA0SIMO lähtö P1.6 (portti 1, pinni 6)
P1MAP5 = PM_UCA0SOMI; // UCA0SOMI lähtö P1.5 (portti 1, pinni 5)
P1MAP7 = PM_UCA0CLK; // UCA0CLK lähtö P1.7 (portti 1, pinni 7)
P2REN |= BIT4; // ota käyttöön sisäinen vastus P2.2 Enable P1.4 internal resistance
P2OUT |= BIT4; // Set P1.4 as pull-Up resistance
P2IE |= BIT4; // interrupt päällä P1.4
P2IES |= BIT4; // P1.4 Hi/Lo edge
P2IFG &= ~BIT4; // P1.4 IFG cleared
PORT_CSB_DIR |= CMR3000_PIN_CSB;
PORT_CSB_OUT |= CMR3000_PIN_CSB; // otetaan CMR3000 pois käytöstä
PORT_CSB_DIR |= SCA3100_PIN_CSB;
PORT_CSB_OUT |= SCA3100_PIN_CSB; // otetaan SCA3100 pois käytöstä
P1DIR |= BIT5 + BIT6 + BIT7; // asettaa portin 1, pinnit 6, 7 ja 8 lähdöiksi
P1SEL |= BIT5 + BIT6 + BIT7; // avaa portin 1, pinnit 6, 7 ja 8
UCA0CTL1 |= UCSWRST; // Resetoi USCI moduulin
UCA0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; // valitaan: UCMST = masterin valinta, UCSYNC = valitaan SPI mode,
// UCCKPH = kellon vaihe 0x80, UCMSB = MSB ensin
UCA0MCTL = 0; // ei modulointia
UCA0CTL1 |= UCSSEL1; // SMCLK, USCI 0 Clock Source Select 1
SPI_BR0 = 0x04; // Low byte of division factor for baud rate (500kHz)
SPI_BR1 = 0x00; // High byte of division factor for baud rate
UCA0CTL1 &= ~UCSWRST; // alustetaan USCI
}
void Init_CMR3000()
{
WDTCTL = WDTPW+WDTHOLD; // sammuta watchdog timer
UCSCTL5 |= DIVS_3;
PMAPPWD = 0x02D52; // hanki kirjoitusoikeudet porttitaulukon registereihin
P1MAP6 = PM_UCA0SIMO; // UCA0SIMO lähtö P1.6 (portti 1, pinni 6)
P1MAP5 = PM_UCA0SOMI; // UCA0SOMI lähtö P1.5 (portti 1, pinni 5)
P1MAP7 = PM_UCA0CLK; // UCA0CLK lähtö P1.7 (portti 1, pinni 7)
P2REN |= BIT4; // ota käyttöön sisäinen vastus P2.2 Enable P1.4 internal resistance
P2OUT |= BIT4; // Set P1.4 as pull-Up resistance
P2IE |= BIT4; // interrupt päällä P1.4
P2IES |= BIT4; // P1.4 Hi/Lo edge
P2IFG &= ~BIT4; // P1.4 IFG cleared
PORT_CSB_DIR |= CMR3000_PIN_CSB;
PORT_CSB_OUT |= CMR3000_PIN_CSB; // otetaan CMR3000 pois käytöstä
P1DIR |= BIT5 + BIT6 + BIT7; // asettaa portin 1, pinnit 6, 7 ja 8 lähdöiksi
P1SEL |= BIT5 + BIT6 + BIT7; // avaa portin 1, pinnit 6, 7 ja 8
UCA0CTL1 |= UCSWRST; // Resetoi USCI moduulin
UCA0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; // valitaan: UCMST = masterin valinta, UCSYNC = valitaan SPI mode,
// UCCKPH = kellon vaihe 0x80, UCMSB = MSB ensin
UCA0MCTL = 0; // ei modulointia
UCA0CTL1 |= UCSSEL1; // SMCLK, USCI 0 Clock Source Select 1
SPI_BR0 = 0x04; // Low byte of division factor for baud rate (500kHz)
SPI_BR1 = 0x00; // High byte of division factor for baud rate
UCA0CTL1 &= ~UCSWRST; // alustetaan USCI
}
void Init_SCA3100()
{
WDTCTL = WDTPW+WDTHOLD; // sammuta watchdog timer
UCSCTL5 |= DIVS_3;
PMAPPWD = 0x02D52; // hanki kirjoitusoikeudet porttitaulukon registereihin
P1MAP6 = PM_UCA0SIMO; // UCA0SIMO lähtö P1.6 (portti 1, pinni 6)
P1MAP5 = PM_UCA0SOMI; // UCA0SOMI lähtö P1.5 (portti 1, pinni 5)
P1MAP7 = PM_UCA0CLK; // UCA0CLK lähtö P1.7 (portti 1, pinni 7)
PORT_CSB_DIR |= SCA3100_PIN_CSB;
PORT_CSB_OUT |= SCA3100_PIN_CSB; // otetaan SCA3100 pois käytöstä
P1DIR |= BIT5 + BIT6 + BIT7; // asettaa portin 1, pinnit 6, 7 ja 8 lähdöiksi
P1SEL |= BIT5 + BIT6 + BIT7; // avaa portin 1, pinnit 6, 7 ja 8
UCA0CTL1 |= UCSWRST; // Resetoi USCI moduulin
UCA0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; // valitaan: UCMST = masterin valinta, UCSYNC = valitaan SPI mode,
// UCCKPH = kellon vaihe 0x80, UCMSB = MSB ensin
UCA0MCTL = 0; // ei modulointia
UCA0CTL1 |= UCSSEL1; // SMCLK, USCI 0 Clock Source Select 1
SPI_BR0 = 0x04; // Low byte of division factor for baud rate (500kHz)
SPI_BR1 = 0x00; // High byte of division factor for baud rate
UCA0CTL1 &= ~UCSWRST; // alustetaan USCI
}
// Linkin muodostin. Tässä laitetaan samalla CMR3000 anturi 80Hz modeen
static void linkTo()
{
//uint8_t len, tid;
while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) // odotetaan että linkki lautojen välille on muodostettu
{
SPIN_ABOUT_A_SECOND;
}
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); // käynnistää radio
while(1)
{
if(mode == 0x31 || mode == 0x32)
{
if(mode == 0x31)
{
Init_CMR3000_SCA3100(); // alustaa SPI:n antureille
}
if(mode == 0x32)
{
Init_CMR3000();
}
wait_ms(10);
BSP_TURN_ON_LED1();
CMR3000_Data = CMR3000_WriteRegister(CTRL, RESET); // resetoi cmr3000 anturi
wait_ms(20); // odotetaan että resetointi valmis
CMR3000_Data = CMR3000_WriteRegister(CTRL, I2C_DIS | MODE_80); // laitetaan I2C pois päältä ja 80hz mittaus mode vielä kerran varmuuden vuoksi päällle
wait_ms(20);
__bis_SR_register(LPM4_bits + GIE); // mennään virransäästötilaan, mutta sallii yleiset interruptit
while (1) // jäädään odottamaan CMR3000 anturin interruptia
{
if(mode != 0x31 || mode != 0x32)
{
break;
}
}
}
if(mode == 0x33)
{
Init_SCA3100();
wait_ms(10);
while(1)
{
Read_SCA3100();
if(mode != 0x33)
{
break;
}
}
}
}
}
static uint8_t sRxCallback(linkID_t port)
{
uint8_t msg[3], len;
// tarkistetaan otetaan vastaan oikealta laitteelta
if (port == sLinkID1)
{
// vastaanotetaan viesti
if ((SMPL_SUCCESS == SMPL_Receive(sLinkID1, msg, &len))) //
{
mode = msg[0];
//tähän voidaan laittaa jotakin mitä halutaan tehdä kun viesti saapui takaisin toiselta laudalta, jos on tarvetta
return 1;
}
}
return 0;
}
//CMR3000 anturin keskeytys funktio.
#pragma vector=CMR3000_PORT_INT_VECTOR
__interrupt void Port_INT_ISR(void)
{
CMR3000_Data = CMR3000_WriteRegister(CTRL, I2C_DIS | MODE_80); // laitetaan I2C pois päältä ja 80hz mittaus mode vielä kerran varmuuden vuoksi päällle
if (CMR3000_PORT_INT_IN & CMR3000_PIN_INT) // kun uusi uuden arvot ovat valmiita, luetaan molempien antureiden arvot
{
if(mode == 0x31)
{
Read_CMR3000_SCA3100(); // antureiden arvojen luku
}
if(mode == 0x32)
{
Read_CMR3000(); // antureiden arvojen luku
}
}
}
// CMR3000 anturin rekistereiden luku
unsigned char CMR3000_ReadRegister(unsigned char Address)
{
unsigned char Result;
Address <<= 2; // shiftataan osoitetta vasemmalle kahdella
PORT_CSB_OUT &= ~CMR3000_PIN_CSB; // valitaan CMR3000 anturi
Result = RX_BUFFER; // pyyhitään interrupt lippu lukemalla RX bufferi
TX_BUFFER = Address; // kirjoitetaan osoite TX bufferiin
while (!(UCA0IFG&UCRXIFG)); // odotetaan että uusi tieto on kirjoitettu RX bufferiin
Result = RX_BUFFER; // pyyhitään interrupt lippu lukemalla RX bufferi
TX_BUFFER = 0; // kirjoitetaan TX bufferiin arvo 0
while (!(UCA0IFG&UCRXIFG)); // odotetaan että uusi tieto on kirjoitettu RX bufferiin
Result = RX_BUFFER; // luetaan RX bufferi
wait_us(SPICSBDELAY);
PORT_CSB_OUT |= CMR3000_PIN_CSB; // otetaan CMR3000 pois käytöstä
wait_us(SPIFRAMEDELAY);
return Result; // palautetaan RX bufferista saatu data
}
// CMR3000 anturin rekistereihin kirjoitus
unsigned char CMR3000_WriteRegister(unsigned char Address, unsigned char Data)
{
unsigned char Result;
Address <<= 2; // shiftataan osoitetta vasemmalle kahdella
Address |= 0x02; // asetetaan toinen bitti ykköseksi, tekee siitä silloin kirjoittavan
PORT_CSB_OUT &= ~CMR3000_PIN_CSB; // valitaan CMR3000 anturi
Result = RX_BUFFER; // pyyhitään interrupt lippu lukemalla RX bufferi
TX_BUFFER = Address; // kirjoitetaan osoite TX bufferiin
while (!(UCA0IFG&UCRXIFG)); // odotetaan että uusi tieto on kirjoitettu RX bufferiin
Result = RX_BUFFER; // pyyhitään interrupt lippu lukemalla RX bufferi
TX_BUFFER = Data; // kirjoitetaan haluttu tieto TX bufferiin
while (!(UCA0IFG&UCRXIFG)); // pyyhitään interrupt lippu lukemalla RX bufferi
Result = RX_BUFFER; // luetaan RX bufferi
wait_us(SPICSBDELAY);
PORT_CSB_OUT |= CMR3000_PIN_CSB; // otetaan CMR3000 pois käytöstä
wait_us(SPIFRAMEDELAY);
return Result;
}
// SCA3100 anturin rekistereiden luku
unsigned char SCA3100_ReadRegister(unsigned char Address)
{
unsigned char Result;
Address <<= 2; // shiftataan osoitetta vasemmalle kahdella
PORT_CSB_OUT &= ~SCA3100_PIN_CSB; // valitaan SCA3100 anturi
Result = RX_BUFFER; // pyyhitään interrupt lippu lukemalla RX bufferi
TX_BUFFER = Address; // kirjoitetaan osoite TX bufferiin r
while (!(UCA0IFG&UCRXIFG)); // odotetaan että uusi tieto on kirjoitettu RX bufferiin
Result = RX_BUFFER; // pyyhitään interrupt lippu lukemalla RX bufferi
TX_BUFFER = 0; // kirjoitetaan TX bufferiin arvo 0
while (!(UCA0IFG&UCRXIFG)); // odotetaan että uusi tieto on kirjoitettu RX bufferiin
Result = RX_BUFFER; // luetaan RX bufferi
wait_us(SPICSBDELAY);
PORT_CSB_OUT |= SCA3100_PIN_CSB; // otetaan SCA3100 pois käytöstä
wait_us(SPIFRAMEDELAY);
return Result; // palautetaan RX bufferista saatu data
}
// Lukufunktio antureiden rekistereille
// Tähän tullaan aina kun CMR3000-anturi lähettää interruptin
// SCA3100:ssa ei ole interrupteja vaan dataa voidaan lukea koko ajan
void Read_CMR3000_SCA3100()
{
uint8_t msg[12];
BSP_TURN_ON_LED2(); // ledi päälle kun uusi tieto on valmis
// luetaan CMR3000, jokaisesta akselista luetaan LSB(vähiten merkitsevät) ja MSB(eniten merkitsevät) arvot
// molemmat LSB ja MSB ovat 8bit kokoisia
CMR3000_x_lsb = CMR3000_ReadRegister(CMR3000_X_LSB);
CMR3000_x_msb = CMR3000_ReadRegister(CMR3000_X_MSB);
CMR3000_y_lsb = CMR3000_ReadRegister(CMR3000_Y_LSB);
CMR3000_y_msb = CMR3000_ReadRegister(CMR3000_Y_MSB);
CMR3000_z_lsb = CMR3000_ReadRegister(CMR3000_Z_LSB);
CMR3000_z_msb = CMR3000_ReadRegister(CMR3000_Z_MSB);
// luetaan SCA3100, jokaisesta axelista luetaan LSB(vähiten merkitsevät) ja MSB(eniten merkitsevät) arvot
// molemmat LSB ja MSB ovat 8bit kokoisia
SCA3100_x_lsb = SCA3100_ReadRegister(SCA3100_X_LSB);
SCA3100_x_msb = SCA3100_ReadRegister(SCA3100_X_MSB);
SCA3100_y_lsb = SCA3100_ReadRegister(SCA3100_Y_LSB);
SCA3100_y_msb = SCA3100_ReadRegister(SCA3100_Y_MSB);
SCA3100_z_lsb = SCA3100_ReadRegister(SCA3100_Z_LSB);
SCA3100_z_msb = SCA3100_ReadRegister(SCA3100_Z_MSB);
// tallennetaan arvot viestin muuttujiksi,
msg[0] = SCA3100_x_msb;
msg[1] = SCA3100_x_lsb;
msg[2] = SCA3100_y_msb;
msg[3] = SCA3100_y_lsb;
msg[4] = SCA3100_z_msb;
msg[5] = SCA3100_z_lsb;
msg[6] = CMR3000_x_msb;
msg[7] = CMR3000_x_lsb;
msg[8] = CMR3000_y_msb;
msg[9] = CMR3000_y_lsb;
msg[10] = CMR3000_z_msb;
msg[11] = CMR3000_z_lsb;
SMPL_Send(sLinkID1, msg, sizeof(msg)); // läheteetään arvot toiselle laudalle radion kautta
BSP_TURN_OFF_LED2();
wait_ms(15);
}
void Read_CMR3000()
{
uint8_t msg[6];
BSP_TURN_ON_LED2(); // ledi päälle kun uusi tieto on valmis
// luetaan CMR3000, jokaisesta akselista luetaan LSB(vähiten merkitsevät) ja MSB(eniten merkitsevät) arvot
// molemmat LSB ja MSB ovat 8bit kokoisia
CMR3000_x_lsb = CMR3000_ReadRegister(CMR3000_X_LSB);
CMR3000_x_msb = CMR3000_ReadRegister(CMR3000_X_MSB);
CMR3000_y_lsb = CMR3000_ReadRegister(CMR3000_Y_LSB);
CMR3000_y_msb = CMR3000_ReadRegister(CMR3000_Y_MSB);
CMR3000_z_lsb = CMR3000_ReadRegister(CMR3000_Z_LSB);
CMR3000_z_msb = CMR3000_ReadRegister(CMR3000_Z_MSB);
msg[0] = CMR3000_x_msb;
msg[1] = CMR3000_x_lsb;
msg[2] = CMR3000_y_msb;
msg[3] = CMR3000_y_lsb;
msg[4] = CMR3000_z_msb;
msg[5] = CMR3000_z_lsb;
SMPL_Send(sLinkID1, msg, sizeof(msg)); // läheteetään arvot toiselle laudalle radion kautta
BSP_TURN_OFF_LED2();
wait_ms(15);
}
void Read_SCA3100()
{
uint8_t msg[6];
BSP_TURN_ON_LED2(); // ledi päälle kun uusi tieto on valmis
// luetaan CMR3000, jokaisesta akselista luetaan LSB(vähiten merkitsevät) ja MSB(eniten merkitsevät) arvot
// molemmat LSB ja MSB ovat 8bit kokoisia
// luetaan SCA3100, jokaisesta axelista luetaan LSB(vähiten merkitsevät) ja MSB(eniten merkitsevät) arvot
// molemmat LSB ja MSB ovat 8bit kokoisia
SCA3100_x_lsb = SCA3100_ReadRegister(SCA3100_X_LSB);
SCA3100_x_msb = SCA3100_ReadRegister(SCA3100_X_MSB);
SCA3100_y_lsb = SCA3100_ReadRegister(SCA3100_Y_LSB);
SCA3100_y_msb = SCA3100_ReadRegister(SCA3100_Y_MSB);
SCA3100_z_lsb = SCA3100_ReadRegister(SCA3100_Z_LSB);
SCA3100_z_msb = SCA3100_ReadRegister(SCA3100_Z_MSB);
// tallennetaan arvot viestin muuttujiksi,
msg[0] = SCA3100_x_msb;
msg[1] = SCA3100_x_lsb;
msg[2] = SCA3100_y_msb;
msg[3] = SCA3100_y_lsb;
msg[4] = SCA3100_z_msb;
msg[5] = SCA3100_z_lsb;
SMPL_Send(sLinkID1, msg, sizeof(msg)); // läheteetään arvot toiselle laudalle radion kautta
BSP_TURN_OFF_LED2();
wait_ms(15);
}
void wait_ms(unsigned short ms)
{
unsigned short a, b;
for (a = ms; a > 0; a--)
for (b = TICKSPERMS; b > 0; b--)
asm(" nop");
}
void wait_us(unsigned short us)
{
unsigned short a;
us *= TICKSPERUS;
for (a = us; a > 0; a--)
asm(" nop");
}
|