예제 #1
0
static void chb_frame_read()
{
    U8 i, len, data;

    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send frame read command and read the length.*/
    chb_xfer_byte(CHB_SPI_CMD_FR);
    len = chb_xfer_byte(0);

    /*Check for correct frame length.*/

    // TODO: CHECK FOR THE CRC VALID BIT TO QUALIFY THE FRAME
    // check the length of the frame to make sure the incoming frame
    // doesn't overflow the buffer
    if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH))
    {
        chb_buf_write(len);
        
        for (i=0; i<len; i++)
        {
            data = chb_xfer_byte(0);
            chb_buf_write(data);
        }
    }

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();
}
예제 #2
0
void chb_frame_write(U8 *hdr, U8 hdr_len, U8 *data, U8 data_len)
{
    U8 i, dummy;

    // dont allow transmission longer than max frame size
    if ((hdr_len + data_len) > 127)
    {
        return;
    }

    // initiate spi transaction
    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE(); 

    // send fifo write command
    dummy = chb_xfer_byte(CHB_SPI_CMD_FW);

    // write hdr contents to fifo
    for (i=0; i<hdr_len; i++)
    {
        dummy = chb_xfer_byte(*hdr++);
    }

    // write data contents to fifo
    for (i=0; i<data_len; i++)
    {
        dummy = chb_xfer_byte(*data++);
    }

    // terminate spi transaction
    CHB_SPI_DISABLE(); 
    CHB_LEAVE_CRIT();
}
예제 #3
0
파일: chb_spi.c 프로젝트: Vladican/gsMote
void chb_spi_init()
{
    // configure the SPI slave_select, spi clk, and mosi pins as output. the miso pin
    // is cleared since its an input.
    CHB_SPI_DDIR |= (1<<CHB_SSPIN) | (1<<CHB_MOSI) | (1<<CHB_SCK);
    CHB_SPI_PORT |= (1<<CHB_SSPIN);

    // set to master mode
    // set the clock freq to fck/16
    CHB_CTRL |= (1<<SPI_MASTER_bp) | (1<<SPI_ENABLE_bp) | (1<<SPI_PRESCALER_gp);

    // set the slave select to idle
    CHB_SPI_DISABLE();
}
예제 #4
0
static void chb_frame_read()
{
    U8 i, len, data;

    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send frame read command and read the length.*/
    chb_xfer_byte(CHB_SPI_CMD_FR);
    len = chb_xfer_byte(0);

    // check the length of the frame to make sure its within the correct size limits
    if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH))
    {
        // check to see if there is room to write the frame in the buffer. if not, then drop it
        if (len < (CHB_BUF_SZ - chb_buf_get_len()))
        {
            chb_buf_write(len);

            for (i=0; i<len; i++)
            {
                data = chb_xfer_byte(0);
                chb_buf_write(data);
            }
        }
        else
        {
            // this frame will overflow the buffer. toss the data and do some housekeeping
            pcb_t *pcb = chb_get_pcb();
            char buf[50];

            // read out the data and throw it away
            for (i=0; i<len; i++)
            {
                data = chb_xfer_byte(0);
            }

            // Increment the overflow stat, and print a message.
            pcb->overflow++;

            // grab the message from flash & print it out
            strcpy_P(buf, chb_err_overflow);
            Serial.print(buf);
        }
    }

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();
}
예제 #5
0
void chb_reg_write(U8 addr, U8 val)
{
    /* Add the Register Write command to the address. */
    addr |= 0xC0;

    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send Register address and write register content.*/
    chb_xfer_byte(addr);
    chb_xfer_byte(val);

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();
}
예제 #6
0
static void chb_frame_read()
{
    U8 i, len, data;

    // CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send frame read command and read the length.*/
    chb_xfer_byte(CHB_SPI_CMD_FR);
    len = chb_xfer_byte(0);

    /*Check for correct frame length.*/
    if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH))
    {
        // check to see if there is room to write the frame in the buffer. if not, then drop it
        if (len < (CFG_CHIBI_BUFFERSIZE - chb_buf_get_len()))
        {
            chb_buf_write(len);
            
            for (i=0; i<len; i++)
            {
                data = chb_xfer_byte(0);
                chb_buf_write(data);
            }
        }
        else
        {
            // we've overflowed the buffer. toss the data and do some housekeeping
            chb_pcb_t *pcb = chb_get_pcb();

            // read out the data and throw it away
            for (i=0; i<len; i++)
            {
                data = chb_xfer_byte(0);
            }

            // Increment the overflow stat
            pcb->overflow++;

            // print the error message
            printf(chb_err_overflow);
        }
    }

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();
}
예제 #7
0
U8 chb_reg_read(U8 addr)
{
    U8 val = 0;

    /* Add the register read command to the register address. */
    addr |= 0x80;

    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send Register address and read register content.*/
    val = chb_xfer_byte(addr);
    val = chb_xfer_byte(val);

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();

    return val;
}
예제 #8
0
void chb_sram_write(U8 addr, U8 len, U8 *data)
{    
    U8 i, dummy;

    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send SRAM write command.*/
    dummy = chb_xfer_byte(CHB_SPI_CMD_SW);

    /*Send address where to start writing to.*/
    dummy = chb_xfer_byte(addr);

    for (i=0; i<len; i++)
    {
        dummy = chb_xfer_byte(*data++);
    }

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();
}
예제 #9
0
void chb_sram_read(U8 addr, U8 len, U8 *data)
{
    U8 i, dummy;

    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE();

    /*Send SRAM read command.*/
    dummy = chb_xfer_byte(CHB_SPI_CMD_SR);

    /*Send address where to start reading.*/
    dummy = chb_xfer_byte(addr);

    for (i=0; i<len; i++)
    {
        *data++ = chb_xfer_byte(0);
    }

    CHB_SPI_DISABLE();
    CHB_LEAVE_CRIT();
}
예제 #10
0
void chb_frame_write_raw(U8 *data, U8 data_len)
{
    U8 i;

    // initiate spi transaction
    CHB_ENTER_CRIT();
    CHB_SPI_ENABLE(); 

    // send fifo write command
    chb_xfer_byte(CHB_SPI_CMD_FW);

    // write data contents to fifo
    for (i=0; i<data_len; i++)
    {
        if(i > 127)
            break;
        chb_xfer_byte(*data++);
    }

    // terminate spi transaction
    CHB_SPI_DISABLE(); 
    CHB_LEAVE_CRIT();
}
예제 #11
0
void chb_ISR_Handler (void)
{
    U8 dummy, state, intp_src = 0;
    chb_pcb_t *pcb = chb_get_pcb();

    CHB_ENTER_CRIT();

    /*Read Interrupt source.*/
    CHB_SPI_ENABLE();   

    /*Send Register address and read register content.*/
    dummy = chb_xfer_byte(IRQ_STATUS | CHB_SPI_CMD_RR);
    intp_src = chb_xfer_byte(0);

    CHB_SPI_DISABLE();

    while (intp_src)
    {
        /*Handle the incomming interrupt. Prioritized.*/
        if ((intp_src & CHB_IRQ_RX_START_MASK))
        {
            intp_src &= ~CHB_IRQ_RX_START_MASK;
        }
        else if (intp_src & CHB_IRQ_TRX_END_MASK)
        {
            state = chb_get_state();

            if ((state == RX_ON) || (state == RX_AACK_ON) || (state == BUSY_RX_AACK))
            {
                // get the ed measurement
                pcb->ed = chb_reg_read(PHY_ED_LEVEL);

                // get the crc
                pcb->crc = (chb_reg_read(PHY_RSSI) & (1<<7)) ? 1 : 0;

                // if the crc is not valid, then do not read the frame and set the rx flag
                if (pcb->crc)
                {
                    // get the data
                    chb_frame_read();
                    pcb->rcvd_xfers++;
                    pcb->data_rcv = true;
                }
            }
            else
            {
                pcb->tx_end = true;
            }
            intp_src &= ~CHB_IRQ_TRX_END_MASK;
            while (chb_set_state(RX_STATE) != RADIO_SUCCESS);
        }
        else if (intp_src & CHB_IRQ_TRX_UR_MASK)
        {
            intp_src &= ~CHB_IRQ_TRX_UR_MASK;
            pcb->underrun++;
        }
        else if (intp_src & CHB_IRQ_PLL_UNLOCK_MASK)
        {
            intp_src &= ~CHB_IRQ_PLL_UNLOCK_MASK;
        }
        else if (intp_src & CHB_IRQ_PLL_LOCK_MASK)
        {
            intp_src &= ~CHB_IRQ_PLL_LOCK_MASK;
        }
        else if (intp_src & CHB_IRQ_BAT_LOW_MASK)
        {
            intp_src &= ~CHB_IRQ_BAT_LOW_MASK;
            pcb->battlow++;
        }
        else
        {
        }
    }
    CHB_LEAVE_CRIT();
}