void NRF24L01_ReadRegisterMulti(uint8_t reg, uint8_t* data, uint8_t count) { NRF24L01_CSN_LOW; SPI_Send(NRF24L01_SPI, NRF24L01_READ_REGISTER_MASK(reg)); SPI_ReadMulti(NRF24L01_SPI, data, NRF24L01_NOP_MASK, count); NRF24L01_CSN_HIGH; }
/***************************************************************************** * Name : * Input: * Output: * Description : * Comments : *****************************************************************************/ void L9952_RefreshWDC(void){ L9952_cr0.bit.trig ^= 0x01; SPI_Send(L9952_cr0.byte, L9952_sr0.byte); }
/****************************************************************************** * Function Name: LCD_SPI_Open * Description : Overwrites the default LCD_SPI_DataSend in the RL78 Glyph * Library. This routine sends a data byte to the LCD along with toggling the LCD * Chip Select Pin. ******************************************************************************/ void LCD_SPI_DataSend(int8_t aData) { SPI_Send(SPI_LCD, (uint8_t *)&aData, 1); }
/***************************************************************************** * Name : * Input: * Output: * Description : * Comments : *****************************************************************************/ void L9952_SwitchToVbatSleep(void){ L9952_cr0.bit.goVbat = 1; SPI_Send(L9952_cr0.byte ,L9952_sr0.byte); }
LBT_Status TDMA_Send(uint8_t dest_address, uint8_t source_address, uint8_t *message, uint8_t length) { uint8_t status; uint8_t state; uint8_t FIFO_Space; uint8_t Old_GDO; uint8_t Old_MSP_RX_Port_IES; uint8_t Old_MSP_RX_Port_IE; uint8_t Old_MSP_RX_Port_Out; LBT_Status return_status; // Configure machine state SPI_Read(GDO_RX, &Old_GDO); // Capture and save the old setting for the GDO pin Old_MSP_RX_Port_IES = MSP_RX_Port_IES; // Save the old interrupt edge select value Old_MSP_RX_Port_IE = MSP_RX_Port_IE; // Save the old interrupt enable value Old_MSP_RX_Port_Out = MSP_RX_Port_OUT; // Save the old value of the GDO pin port MSP_RX_Port_OUT &= ~MSP_RX_Pin; status = SPI_Send(GDO_RX, 0x06); // Set the GDO to assert on preamble start and TX complete state = status & State_Bits; // Mask off the state bits from the status byte if(state != SB_Idle) // If a TX was already in progress. { return_status = Radio_Busy; goto Cleanup; // Yes. A Goddamn goto. } // Load the TX fifo SPI_Send(TXFIFO, length + 2); SPI_Send(TXFIFO, dest_address); SPI_Send(TXFIFO, source_address); status = SPI_Send_Burst(TXFIFO, message, length); // Load the TX fifo FIFO_Space = status & FIFO_Bytes; // Get the space left in the FIFO if(FIFO_Space == 0) // FIFO space remaining of 0 means overflow { return_status = TX_Buffer_Overflow; goto Cleanup; } // Enable interrupt on falling edge MSP_RX_Port_IES |= MSP_RX_Pin; MSP_RX_Port_IE |= MSP_RX_Pin; SPI_Strobe(STX, Get_TX_FIFO); // Tell radio to transmit LPM3; // Sleep until TX is done, interrupt will wake up the return_status = Transmit_Success; // Clear the interrupt and set the GDO pin back to its old function here. n Cleanup: MSP_RX_Port_IFG &= ~MSP_RX_Pin; // Clear interrupt flags before exit MSP_RX_Port_IES = Old_MSP_RX_Port_IES; // Restore the old interrupt edge select value MSP_RX_Port_IE = Old_MSP_RX_Port_IE; // Restore the old interrupt enable value MSP_RX_Port_OUT = Old_MSP_RX_Port_Out; // Restore the old port setting SPI_Send(GDO_RX, Old_GDO); // Set the GDO pin back to its old function return return_status; }
struct Listen_Struct LBT_Listen(uint16_t timeoutPeriod) { uint8_t Old_GDO; uint8_t Old_MSP_RX_Port_IES; uint8_t Old_MSP_RX_Port_IE; uint8_t Old_MSP_RX_Port_Out; uint8_t status; uint8_t state; uint8_t buffer[64]; LBT_Status return_status; struct Listen_Struct retVal; // Flush the RX FIFO SPI_Strobe(SFRX, Get_RX_FIFO); // Configure machine state SPI_Read(GDO_RX, &Old_GDO); // Capture and save the old setting for the GDO pin Old_MSP_RX_Port_IES = MSP_RX_Port_IES; // Save the old interrupt edge select value Old_MSP_RX_Port_IE = MSP_RX_Port_IE; // Save the old interrupt enable value Old_MSP_RX_Port_Out = MSP_RX_Port_OUT; status = SPI_Send(GDO_RX, 0x07); // Set the GDO to assert on pkt recieve with crc OK state = status & State_Bits; // Mask off the state bits from the status byte if(state != SB_Idle) // If a radio is already busy { return_status = Radio_Busy; goto Cleanup; // Yes. A Goddamn goto. } // Set GDO pin to trigger on rising edge for PKT RX MSP_RX_Port_IES &= ~MSP_RX_Port_IE; MSP_RX_Port_IE |= MSP_RX_Port_IE; SPI_Strobe(SRX, Get_RX_FIFO); // Set radio to listen Sleep_Timer(0, timeoutPeriod); SPI_Read_Status(RXBYTES, &status); // Get packet status if(status & OverFlow) // If the buffer is overflowed dump it and don't read the values { return_status = RX_Buffer_Overflow; SPI_Strobe(SFRX, Get_RX_FIFO); goto Cleanup; } // Read the FIFO buffer into the out variable. IF there is no overflow then contents of the RXBYTES register is just the // number of bytes in the RX FIFO. SPI_Read_Burst(RXFIFO, buffer, status); return_status = Message_Recieved; retVal.length = buffer[0] - 5; retVal.address = buffer[1]; retVal.signal = buffer[status - 2]; retVal.Status = return_status; uint8_t i; for(i = 0; i < status - 5; i++) { retVal.payload[i] = buffer[i + 3]; } Cleanup: // Restore old machine state MSP_RX_Port_IE = Old_MSP_RX_Port_IE; // Restore the old interrupt enable value MSP_RX_Port_IFG &= ~MSP_RX_Pin; // Clear interrupt flags before exit MSP_RX_Port_IES = Old_MSP_RX_Port_IES; // Restore the old interrupt edge select value MSP_RX_Port_OUT = Old_MSP_RX_Port_Out; // Restore the old port setting SPI_Send(GDO_RX, Old_GDO); // Set the GDO pin back to its old function return retVal; }
/* * Initialises the MMC into SPI mode and sets block size(512), returns * 0 on success * */ int mmc_init() { DWORD i; /* Generate a data pattern for write block */ for(i=0;i<MMC_DATA_SIZE;i++) { MMCWRData[i] = i; } MMCStatus = 0; IOSET0 = SPI_SEL; /* set SPI SSEL */ /* initialise the MMC card into SPI mode by sending 80 clks on */ /* Use MMCRDData as a temporary buffer for SPI_Send() */ for(i=0; i<10; i++) { MMCRDData[i] = 0xFF; } SPI_Send( MMCRDData, 10 ); IOCLR0 = SPI_SEL; /* clear SPI SSEL */ /* send CMD0(RESET or GO_IDLE_STATE) command, all the arguments are 0x00 for the reset command, precalculated checksum */ MMCCmd[0] = 0x40; MMCCmd[1] = 0x00; MMCCmd[2] = 0x00; MMCCmd[3] = 0x00; MMCCmd[4] = 0x00; MMCCmd[5] = 0x95; SPI_Send( MMCCmd, MMC_CMD_SIZE ); /* if = 1 then there was a timeout waiting for 0x01 from the MMC */ if( mmc_response(0x01) == 1 ) { MMCStatus = IDLE_STATE_TIMEOUT; IOSET0 = SPI_SEL; /* set SPI SSEL */ return MMCStatus; } /* Send some dummy clocks after GO_IDLE_STATE */ IOSET0 = SPI_SEL; /* set SPI SSEL */ SSP_SendRecvByteByte(); IOCLR0 = SPI_SEL; /* clear SPI SSEL */ /* must keep sending command until zero response ia back. */ i = MAX_TIMEOUT; do { /* send mmc CMD1(SEND_OP_COND) to bring out of idle state */ /* all the arguments are 0x00 for command one */ MMCCmd[0] = 0x41; MMCCmd[1] = 0x00; MMCCmd[2] = 0x00; MMCCmd[3] = 0x00; MMCCmd[4] = 0x00; /* checksum is no longer required but we always send 0xFF */ MMCCmd[5] = 0xFF; SPI_Send( MMCCmd, MMC_CMD_SIZE ); i--; } while ( (mmc_response(0x00) != 0) && (i>0) ); /* timeout waiting for 0x00 from the MMC */ if ( i == 0 ) { MMCStatus = OP_COND_TIMEOUT; IOSET0 = SPI_SEL; /* set SPI SSEL */ return MMCStatus; } /* Send some dummy clocks after SEND_OP_COND */ IOSET0 = SPI_SEL; /* set SPI SSEL */ SSP_SendRecvByteByte(); IOCLR0 = SPI_SEL; /* clear SPI SSEL */ /* send MMC CMD16(SET_BLOCKLEN) to set the block length */ MMCCmd[0] = 0x50; MMCCmd[1] = 0x00; /* 4 bytes from here is the block length */ /* LSB is first */ /* 00 00 00 10 set to 16 bytes */ /* 00 00 02 00 set to 512 bytes */ MMCCmd[2] = 0x00; /* high block length bits - 512 bytes */ MMCCmd[3] = 0x02; /* low block length bits */ MMCCmd[4] = 0x00; /* checksum is no longer required but we always send 0xFF */ MMCCmd[5] = 0xFF; SPI_Send( MMCCmd, MMC_CMD_SIZE ); if( (mmc_response(0x00))==1 ) { MMCStatus = SET_BLOCKLEN_TIMEOUT; IOSET0 = SPI_SEL; /* set SPI SSEL */ return MMCStatus; } IOSET0 = SPI_SEL; /* set SPI SSEL */ SSP_SendRecvByteByte(); return 0; }
/* write a block of data based on the length that has been set * in the SET_BLOCKLEN command. * Send the WRITE_SINGLE_BLOCK command out first, check the * R1 response, then send the data start token(bit 0 to 0) followed by * the block of data. The test program sets the block length to 512 * bytes. When the data write finishs, the response should come back * as 0xX5 bit 3 to 0 as 0101B, then another non-zero value indicating * that MMC card is in idle state again. * */ int mmc_write_block(WORD block_number) { WORD varl, varh; BYTE Status; IOCLR0 = SPI_SEL; /* clear SPI SSEL */ /* block size has been set in mmc_init() */ varl=((block_number&0x003F)<<9); varh=((block_number&0xFFC0)>>7); /* send mmc CMD24(WRITE_SINGLE_BLOCK) to write the data to MMC card */ MMCCmd[0] = 0x58; /* high block address bits, varh HIGH and LOW */ MMCCmd[1] = varh >> 0x08; MMCCmd[2] = varh & 0xFF; /* low block address bits, varl HIGH and LOW */ MMCCmd[3] = varl >> 0x08; MMCCmd[4] = varl & 0xFF; /* checksum is no longer required but we always send 0xFF */ MMCCmd[5] = 0xFF; SPI_Send(MMCCmd, MMC_CMD_SIZE ); /* if mmc_response returns 1 then we failed to get a 0x00 response */ if((mmc_response(0x00))==1) { MMCStatus = WRITE_BLOCK_TIMEOUT; IOSET0 = SPI_SEL; /* set SPI SSEL */ return MMCStatus; } /* Set bit 0 to 0 which indicates the beginning of the data block */ MMCCmd[0] = 0xFE; SPI_Send( MMCCmd, 1 ); /* send data, pattern as 0x00,0x01,0x02,0x03,0x04,0x05 ...*/ SPI_Send( MMCWRData, MMC_DATA_SIZE ); /* Send dummy checksum */ /* when the last check sum is sent, the response should come back immediately. So, check the SPI FIFO MISO and make sure the status return 0xX5, the bit 3 through 0 should be 0x05 */ MMCCmd[0] = 0xFF; MMCCmd[1] = 0xFF; SPI_Send( MMCCmd, 2 ); Status = SSP_SendRecvByteByte(); if ( (Status & 0x0F) != 0x05 ) { MMCStatus = WRITE_BLOCK_FAIL; IOSET0 = SPI_SEL; /* set SPI SSEL */ return MMCStatus; } /* if the status is already zero, the write hasn't finished yet and card is busy */ if(mmc_wait_for_write_finish()==1) { MMCStatus = WRITE_BLOCK_FAIL; IOSET0 = SPI_SEL; /* set SPI SSEL */ return MMCStatus; } IOSET0 = SPI_SEL; /* set SPI SSEL */ SSP_SendRecvByteByte(); return 0; }