Esempio n. 1
0
/** @brief Read a Data Byte from the RFM01 FIFO over SPI
  
The RF01 has two modes of reading the FIFO. If the FIFO level is set to 1 then
FIFO data available is read out from a dedicated pin, and the FIFO bit(s) can be
read from the SDO pin. Alternatively a status read bit 1 will indicate the FIFO
threshold exceeded and data can be read out following the remainder of the status
word. The latter mode is used here to allow bytewise reception.

A status command (all zeros) is sent to the RFM01 to initiate a databyte read.
The first 16 bits read out are status bits, followed by some data bits.
When the FIFO fills to the trigger point FIFO_TRIGGER, the top status bit
(first one transmitted) of the status word is set and can be tested.

The data is available before the SCK pulse, and is read first.

Normally FIFO_TRIGGER should be 8 to retrieve a single byte. It should not be
close to 16 which is the maximum limit of the FIFO buffer. If FIFO_TRIGGER
is less than 8 then only FIFO_TRIGGER bits are retrieved.

Data is read MSB first.

Return:     Full status word if no data ready, or received data byte in lower byte
            along with upper byte of status word.
*/
uint16_t readDataByte()
{
	uint8_t n = 16;
	uint16_t rfm01Status = 0;	     			/* Holds the RF01 status word */
	uint16_t result = 0;						/* Holds the received data and status */
	cbi(CS_PORT,nSEL);	                        /* Set CS LOW */
	while(n--)                                  /* Start reading in the status word */
	{
		rfm01Status <<= 1;                       /* Shift left for next bit received */
		rfm01Status |= ((inb(SPI_PIN) >> SDO) & 1);  /* add received bit to status */
		writeSPI(0);						    /* Write 0 via SPI for status command */
	}
    lastRfm01Status = rfm01Status;
    if ((rfm01Status & 0x8000) != 0)             /* Check if FFIT is activated */
    {
        n = FIFO_TRIGGER;
        if (n > 8) n = 8;                       /* Limit number read to a byte */
	    while(n--)						        /* Continue to send zeros to get data */
	    {
		    result <<= 1;                       /* Shift left for next bit received */
		    result |= ((inb(SPI_PIN) >> SDO) & 1);  /* add received bit to result */
		    writeSPI(0);						/* Write 0 via SPI for status command */
	    }
        result |= (rfm01Status & 0xFF00);        /* return upper byte of status word with result */
    }
Esempio n. 2
0
int sendSDCmd ( unsigned char c, unsigned a)
// c command code
// a bte address of data block
{
	int i, r;
	
	//enable SD card
	enableSD();
	
	// send a command packet (6 bytes)
	writeSPI( c | 0x40);	//send command
	writeSPI( a>>24);		//msb of the address
	writeSPI( a>>16);
	writeSPI( a>>8);
	writeSPI( a);			//lsb
	
	writeSPI(0x95);			//send CMD0 CRC
	
	// now wait for a response, allow to 8 bytes delay
	for( i=0; i<8; i++)
	{
		r=readSPI();
		if ( r != 0xFF)
			break;
	}	
	return ( r);
	
	// NOTE SDCS is still low!
} // sendSDCmd
Esempio n. 3
0
void UniversalAdapter::setCursor(uint8_t col, uint8_t row)
{
    SPIFrame sf(this); // asserts cs on entry and deasserts on exit
    wait_until_ready();
    uint8_t cmd = SET_CURSOR | 1;
    uint8_t rc = (row << 5) | (col & 0x1F);
    writeSPI(cmd);
    writeSPI(rc);
}
Esempio n. 4
0
// a        LBA of sector requested
// p        pointer to sector buffer
// returns  TRUE if successful
int writeSECTOR(LBA a, char *p)
{
	unsigned r, i;

	// 0. check Write Protect
	if (getWP())
		return FAIL;

	// 1. send WRITE command
	r = sendSDCmd(WRITE_SINGLE, (a << 9));
	if (r == 0)    // check if command was accepted
	{
		// 2. send data
		writeSPI(DATA_START);

		// send 512 bytes of data
		for(i=0; i<512; i++)
		writeSPI(*p++);

		// 3. send dummy CRC
		clockSPI();
		clockSPI();

		// 4. check if data accepted
		r = readSPI();
		if ((r & 0xf) == DATA_ACCEPT)
		{
			#ifdef WRITE_LED
			digitalwrite(WRITE_LED, 0);
			#endif

			// 5. wait for write completion
			for(i=0; i<W_TIMEOUT; i++)
			{
				r = readSPI();
				if (r != 0 )
					break;
			}
			#ifdef WRITE_LED
			digitalwrite(WRITE_LED, 1);
			#endif
		} // accepted
		else
		{
			r = FAIL;
		}
	} // command accepted

	// 6. disable the card
	disableSD();

	return (r);      // return TRUE if successful
} // writeSECTOR
Esempio n. 5
0
void UniversalAdapter::write(const char *line, int len)
{
    SPIFrame sf(this); // asserts cs on entry and deasserts on exit
    wait_until_ready();
    if(len > 31) {
        // this is the limit the UPA can handle in one frame (31 bytes)
        len = 31;
    }
    uint8_t cmd = LCD_WRITE | (len & 0x1F);
    writeSPI(cmd);
    for (int i = 0; i < len; ++i) {
        writeSPI(*line++);
    }
}
int writeDAC(float voltage){
    float vref = 3.3;
    short hex;
    //xil_printf("\nValue2 = %f", voltage);
    // saturate voltage at -10V and +10V
    if(voltage > 10){
        voltage = 10;
    }else if(voltage < -10){
        voltage = -10;
    }
    //-------------------------------------------------

    // scale voltage from -10V --- +10V to 0V --- +3.3V
    voltage /= 6.0; // gain of op amp
    voltage += 1.65; // offset voltage;
    if(voltage > 3.2){
        voltage = 3.2;
    }else if(voltage <0){
        voltage = 0;
    }
    //-------------------------------------------------

    // convert voltage to hex
    hex = (voltage/vref) * 4096;

    hex |= DAC_CONFIG_BITS; // add configuration bits
    //-------------------------------------------------

    //xil_printf("\nDAC Value = %x", hex);
    writeSPI(SPI_MODE_DAC_16, hex, DAC); // write to DAC and change DAC chip select
    return (hex & (~0xF000));
}
Esempio n. 7
0
void UniversalAdapter::wait_until_ready()
{
    while(this->busy_pin->get() != 0) {
        // poll adapter for more room
        wait_ms(100);
        writeSPI(POLL);
    }
}
Esempio n. 8
0
/** @brief Write a Command to the RFM01 over SPI
  
A command is clocked out to the RFM01 one bit at a time.
All RF01 commands are 16 bit but the second parameter is kept for code
compatibility with the other RF chips.
At the same time a result is clocked back in one bit at a time. The result
is returned as a 16 bit word.

Each bit of output status is available before the clock pulse. After
the last clock pulse the first FIFO data is presented.

For the RFM01 receiver module the returned result is meaningless except
for the status read command which is 16 bits.

Parameter:  16 or 8 bit command
Parameter:  length of command (8 or 16)
Return:     Value returned from the SPI interface 
*/
uint16_t writeCMD(uint16_t command, uint8_t n)
{
	if (n < 16)                                 /* For 8 bit commands */
        command <<= (16-n);                     /* Shift command byte to upper byte */
	uint16_t result = 0;						/* Holds the received SDI */
	cbi(CS_PORT,nSEL);	                        /* Set CS LOW */
	while(n--)									/* Send All Bits MSB First */
	{
		result <<= 1;                           /* Shift left for next bit to receive */
		result |= ((inb(SPI_PIN) >> SDO) & 1);  /* add received bit to result */
		if (command & 0x8000)
			writeSPI(1);						/* Write 1 via SDI */
		else
			writeSPI(0);						/* Write 0 via SDI */
		command <<= 1;							/* Shift left for next bit to send */
	}
	sbi(CS_PORT,nSEL);							/* CS HIGH - Finished Sending Command */
    return result;
}
Esempio n. 9
0
void UniversalAdapter::init()
{
    {
        SPIFrame sf(this); // asserts cs on entry and deasserts on exit
        // send an init command
        writeSPI(INIT_ADAPTER);
    }
    // give adapter time to init
    wait_ms(100);
}
Esempio n. 10
0
// c    command code
// a    byte address of data block
int sendSDCmd(unsigned char c, unsigned a)
{
	int i, r;

	// enable SD card
	// CS low
	enableSD();

	// send a comand packet (6 bytes)
	writeSPI(c | 0x40);    // send command
	writeSPI(a>>24);       // msb of the address
	writeSPI(a>>16);
	writeSPI(a>>8);
	writeSPI(a);           // lsb

	writeSPI(0x95);        // send CMD0 CRC

	// now wait for a response, allow for up to 8 bytes delay
	for(i=0; i<8; i++)
	{
		r = readSPI();
		if (r != 0xFF)
			break;
	}
	return (r);

	/* return response
	FF - timeout
	00 - command accepted
	01 - command received, card in idle state after RESET

	other codes:
	bit 0 = Idle state
	bit 1 = Erase Reset
	bit 2 = Illegal command
	bit 3 = Communication CRC error
	bit 4 = Erase sequence error
	bit 5 = Address error
	bit 6 = Parameter error
	bit 7 = Always 0
	*/
	// NOTE CSCD is still low!
} // sendSDCmd
Esempio n. 11
0
// Sets the indicator leds
void UniversalAdapter::setLed(int led, bool onoff)
{
    SPIFrame sf(this); // asserts cs on entry and deasserts on exit
    if(onoff) {
        switch(led) {
            case LED_FAN_ON: ledBits    |= 1; break; // on
            case LED_HOTEND_ON: ledBits |= 2; break; // on
            case LED_BED_ON: ledBits    |= 4; break; // on
        }
    } else {
        switch(led) {
            case LED_FAN_ON: ledBits    &= ~1; break; // off
            case LED_HOTEND_ON: ledBits &= ~2; break; // off
            case LED_BED_ON: ledBits    &= ~4; break; // off
        }
    }
    uint8_t cmd = SET_LEDS | 1;
    wait_until_ready();
    writeSPI(cmd);
    writeSPI(ledBits);
}
Esempio n. 12
0
/**
 * Reads a single Databyte from the SPI Interface.
 */
uint8_t readSPI(void)
{
	writeSPI(0xFF);
	return SPDR;
}
Esempio n. 13
0
unsigned char transferSPI(unsigned char data) {
    writeSPI(data); 				                //write data and wait and of transmit
    return readSPI(); 						        //get the data from SPI
}
Esempio n. 14
0
void writeDAC(unsigned int a) {
    writeSPI((a)&0x0FFF);
    DAC_LOAD = 0;
    Nop();Nop();
    DAC_LOAD = 1;
}
Esempio n. 15
0
uint8_t readSPI_xx(USART_t & src) {
	writeSPI(src, 0xff);							// Write clock
	return src.DATA;								// Read received data
}
Esempio n. 16
0
void UniversalAdapter::clear()
{
    SPIFrame sf(this); // asserts cs on entry and deasserts on exit
    wait_until_ready();
    writeSPI(LCD_CLEAR);
}
Esempio n. 17
0
// cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms)
void UniversalAdapter::buzz(long duration, uint16_t freq)
{
    SPIFrame sf(this); // asserts cs on entry and deasserts on exit
    wait_until_ready();
    writeSPI(BUZZ);
}
Esempio n. 18
0
uint8_t UniversalAdapter::sendReadCmd(uint8_t cmd)
{
    writeSPI(cmd);
    return writeSPI(0);
}
int main()
{
  //Step 1: Enable the SSI module using the RCGCSSI register [pg. 321]
  //I am using SSI2
  SYSCTL->RCGCSSI =  (1<<2);
  
  //Step 2: Enable the clock to the appropriate GPIO module via the RCGCGPIO register [pg. 315]
  //I am using Port B which is represented by bit 1
  SYSCTL->RCGCGPIO = (1<<1);
  
  //Step 3: Set the GPIO AFSEL bits for the appropriate pins [pg. 632]
  //I am using PB 4,5,6,7
  //GPIOB->AFSEL |= (1<<4)|(1<<6)|(1<<7)|(1<<5);
  GPIOB->AFSEL |= (1<<4)|(1<<6)|(1<<7);
  //To take control of the CS pin. First disable the alternate function of the pin
  GPIOB->AFSEL &= ~(1<<5);
  
  //Step 4: Configure the PMCn fields in the GPIOPCTL register to assign the SSI signals to the appropriate pins
  //A pin may have several alternate functions, here I select which alternate function I need
  //The SSI2 functions for pin PB 4,5,6,7 are located at 2 see Table 21-5 [pg. 1143]
  GPIOB->PCTL |= (2<<16)|(2<<20)|(2<<24)|(2<<28);
  
  //Pins will be used as digital pins => I must enable them. SSI IS A DIGITAL SIGNAL
  GPIOB->DEN |= (1<<4)|(1<<6)|(1<<7)|(1<<5);
  GPIOB->DIR |= (1<<5);
  
  //For each of the fram formats, the SSI is configured using the following steps:
  //Step 1: Ensure that the SSE bit in the SSICR1 register is clear before making any configuration changes.
  SSI2->CR1 &= ~(1<<1);
  
  //Step 2: Select whether the SSI is a master or slave
  SSI2->CR1 = 0x00000000;
  
  //Step 3: Configure the SSI clock source by writing to the SSICC register
  SSI2->CC =0x00;
  
  //Step 4: Configure the clock prescale divisor by writing the SSICPSR register
  SSI2->CPSR = 10; //WHY 1.6mHZ
  
  //Step 5: Write the SSICR0 register with the following configuration
  SSI2->CR0 = (0x7<<0);
  
  //BOTTOM TWO LINES ARE FOR MODE 1,1. REMOVE THEM IF YOU WANT TO CHOOSE MODE 0,0
  //SSI2->CR0 |= (1<<6);
  //SSI2->CR0 |= (1<<7);
  
  //Step 6: Optionally, configure the uDMA channel and enable the DMA options(s) in the SSIDMACTL register
  
  //Step 7: Enalbe the SSI by setting the SSE bit in the SSICR1 register
  SSI2->CR1 |= (1<<1);
  
  GPIOB->DATA |= (1<<5);
  GPIOB->DATA &= ~(1<<5); // SS/CS low, begin transmission
  
  writeSPI(0x40); //slave addrss. Here I also mention that I want to write
  writeSPI(0x00); //IODIR address
  writeSPI(0x00); //LEDs are off
  
  for(int i = 0; i < 60; i++);
  GPIOB->DATA |= (1<<5); // SS/CS high, end transmission
  
  while(1)
  {
    GPIOB->DATA &= ~(1<<5); // SS/CS Low, begin transmission
    
    writeSPI(0x40); //slave addrss. Here I also mention that I want to write
    writeSPI(0x09); //GPIO address
    writeSPI(leds++); //set pins as outputs
    
    for(int i = 0; i < 60; i++);
    GPIOB->DATA |= (1<<5); // SS/CS High, end transmission
     
    for(int i = 0; i < 100000; i++);
  }
  
  return 0;
}