UINT8 SD_WriteData(UINT8 pu8DataPointer[], UINT32 u32DataLength) { UINT8 u8R1; UINT8 u8Counter; UINT32 u32Counter; //SPI_SS = ENABLE; SPI_SendByte(0xFE); for(u32Counter = 0; u32Counter < u32DataLength; u32Counter++) SPI_SendByte(pu8DataPointer[u32Counter]); SPI_SendByte(0xFF); // checksum Bytes not needed SPI_SendByte(0xFF); /* Response RHandler (R1) */ u8Counter = SD_WAIT_CYCLES; do { u8R1 = SPI_ReceiveByte(); u8Counter--; } while(((u8R1 & 0x80) != 0) && (u8Counter > 0)); // #001 wait for SD response <> 0xFF //SPI_SS = DISABLE; if(u8Counter == 0) return (SD_FAIL_TIMEOUT); if((u8R1 & 0x1F) != 0x05) return (SD_FAIL_WRITE); // #001 checks if response = 0101 = data accepted while(SPI_ReceiveByte()==0x00) ; // Dummy SPI cycle return(SD_OK); }
//Fetch the next act payload //Return the payload length char NRF24L01_RxPacket(char *payload) { int len; int i; //Get the packet length RADIO_EN_CS(); SPI_SendByte(CMD_RX_PL_WID); len = SPI_ReceiveByte(); RADIO_DIS_CS(); if (len>0 && len<33) { //Read the packet from the RX buffer RADIO_EN_CS(); SPI_SendByte(CMD_R_RX_PAYLOAD); for(i=0;i<len;i++) payload[i] = SPI_ReceiveByte(); RADIO_DIS_CS(); } else { len=0; } //Pulse CE //CE_PULSE(); return len; }
/******************************************************************************* * 函数名 : MCP2515_WriteByte * 描述 : 通过SPI向MCP2515指定地址寄存器写1个字节数据 * 输入 : addr:MCP2515寄存器地址,dat:待写入的数据 * 输出 : 无 * 返回值 : 无 * 说明 : 无 *******************************************************************************/ void MCP2515_WriteByte(unsigned char addr,unsigned char dat) { MCP2515_CS=0; //置MCP2515的CS为低电平 SPI_SendByte(CAN_WRITE); //发送写命令 SPI_SendByte(addr); //发送地址 SPI_SendByte(dat); //写入数据 MCP2515_CS=1; //置MCP2515的CS为高电平 }
UINT8 SD_SendCommand(UINT8 u8SDCommand, UINT32 u32Param, UINT8 pu32Response[], UINT8 u8ResponseLength) { UINT8 u8R1; UINT8 u8Counter; UINT8 buffer[4]; buffer[0] = (UINT8)((u32Param & 0xFF000000) >> 24); buffer[1] = (UINT8)((u32Param & 0x00FF0000) >> 16); buffer[2] = (UINT8)((u32Param & 0x0000FF00) >> 8); buffer[3] = (UINT8)((u32Param & 0x000000FF) >> 0); /* Enable CS */ //SPI_SS = ENABLE; /* Send Start byte */ SPI_SendByte((UINT8)(u8SDCommand | 0x40)); /* Send Argument */ for(u8Counter = 0; u8Counter < 4; u8Counter++) { SPI_SendByte(buffer[u8Counter]); } /* Send CRC */ if((u8SDCommand & 0x02F) == SD_CMD8_SEND_IF_COND) { SPI_SendByte(0x87); } else { SPI_SendByte(0x95); } /* } else if ((u8SDCommand & 0x02F) == SD_CMD1) { SPI_SendByte(0x95); } else { SPI_SendByte(0x01); } */ /* Response RHandler (R1) */ u8Counter = SD_WAIT_CYCLES; do { u8R1 = SPI_ReceiveByte(); //Recibe Respuesta de SD (R1=1byte) u8Counter--; } while(((u8R1 & 0x80) != 0) && (u8Counter > 0)); if(u8Counter == 0) { //SPI_SS = DISABLE; return (SD_FAIL_TIMEOUT); } for (u8Counter = 0; u8Counter < u8ResponseLength; u8Counter++) { pu32Response[u8Counter] = SPI_ReceiveByte(); } /* Disable CS */ //SPI_SS = DISABLE; return (u8R1); }
void AD7794SendReset( void ) { AD7794Select(1); SPI_SendByte(0xFF); SPI_SendByte(0xFF); SPI_SendByte(0xFF); SPI_SendByte(0xFF); SPI_SendByte(0xFF); AD7794Select(0); return; }
/******************************************************************************* * 函数名 : MCP2515_ReadByte * 描述 : 通过SPI从MCP2515指定地址寄器读1个字节数据 * 输入 : addr:MCP2515寄存器地址 * 输出 : 无 * 返回值 : rByte:读取到寄存器的1个字节数据 * 说明 : 无 *******************************************************************************/ unsigned char MCP2515_ReadByte(unsigned char addr) { unsigned char rByte; MCP2515_CS=0; //置MCP2515的CS为低电平 SPI_SendByte(CAN_READ); //发送读命令 SPI_SendByte(addr); //发送地址 rByte=SPI_ReadByte(); //读取数据 MCP2515_CS=1; //置MCP2515的CS为高电平 return rByte; //返回读到的一个字节数据 }
char NRF24L01_WriteReg(char addr, char value) { char status; RADIO_EN_CS(); status = SPI_SendByte(CMD_W_REG | (addr&0x1F)); SPI_SendByte(value); RADIO_DIS_CS(); return value; }
int8_t hwspi_write_block() { uint8_t i; uint16_t k; int16_t in_data; int8_t ret = 1; if (SPI_USE_3B_CMDS && SPI_ADDRESS_LENGTH == 4) { HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_EN4B); HWSPI_CS_HIGH; } HWSPI_WP_HIGH; for (i = 0; i < BUF_SIZE_RW/256; ++i) { // set write enable bit HWSPI_WREN; /* Serial Data Input command */ HWSPI_CS_LOW; if (SPI_USE_3B_CMDS || SPI_ADDRESS_LENGTH == 3) SPI_SendByte(SPI_COMMAND_3B_PAGEPROG); else SPI_SendByte(SPI_COMMAND_4B_PAGEPROG); /* address */ if (SPI_ADDRESS_LENGTH == 4) SPI_SendByte(buf_addr[0]); SPI_SendByte(buf_addr[1]); SPI_SendByte(buf_addr[2] | i); SPI_SendByte(buf_addr[3]); for (k = 0; k < 256; ++k) { if ((in_data = usb_serial_getchar()) != -1) { SPI_SendByte(in_data); } else { ret = -1; break; } } HWSPI_CS_HIGH; // wait for the internal controller to finish the program command SPI_BUSY_WAIT; if (ret == -1) break; if ((maker_code == 0xC2) && (device_code0 == 0x18)) { if (hwspi_security() & SPI_SECURITY_P_FAIL) { ret = 0; } } } HWSPI_WP_LOW; return ret; }
//LSB of returned register is in DataToRead[0] bool AD7794ReadReg( uint8_t reg, uint8_t *DataToRead ) { if( (reg >= 0) && (reg <= 7) ) { AD7794Select(1); SPI_SendByte( AD7794_CR_READ | (reg << 3) ); if( (reg == 0) || (reg == 4) || (reg == 5) ) { //8-bit register *DataToRead = SPI_ReceiveByte(); } else if( (reg == 1) || (reg == 2) ) { //16-bit register DataToRead[1] = SPI_ReceiveByte(); DataToRead[0] = SPI_ReceiveByte(); } else { //16-bit register DataToRead[2] = SPI_ReceiveByte(); DataToRead[1] = SPI_ReceiveByte(); DataToRead[0] = SPI_ReceiveByte(); } AD7794Select(0); return true; } //Invalid register return false; }
//Send a packed in no-ack mode void NRF24L01_TxPacketNoAck(char *payload, char len) { int i; //Send the packet in the TX buffer RADIO_EN_CS(); SPI_SendByte(CMD_W_PAYLOAD_NO_ACK); for(i=0;i<len;i++) SPI_SendByte(payload[i]); RADIO_DIS_CS(); //Pulse CE CE_PULSE(); return; }
int8_t hwspi_erase_chip() { HWSPI_WP_HIGH; // set write enable bit HWSPI_WREN; // block erase setup command HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_CHIP_ERASE); HWSPI_CS_HIGH; // wait for the internal controller to finish the erase command SPI_BUSY_WAIT; HWSPI_WP_LOW; if ((hwspi_status() & (SPI_STATUS_BP0 | SPI_STATUS_BP1 | SPI_STATUS_BP2 | SPI_STATUS_BP3 | SPI_STATUS_SRWD))) { return -1; } if ((maker_code == 0xC2) && (device_code0 == 0x18)) { if (hwspi_security() & (SPI_SECURITY_E_FAIL | SPI_SECURITY_WPSEL)) return 0; } return 1; }
//Set the TX and RX address void NRF24L01_SetAddress(char* address) { int i; RADIO_EN_CS(); SPI_SendByte(CMD_W_REG | REG_TX_ADDR); for(i=0; i<5; i++) SPI_SendByte(address[i]); RADIO_DIS_CS(); RADIO_EN_CS(); SPI_SendByte(CMD_W_REG | REG_RX_ADDR_P0); for(i=0; i<5; i++) SPI_SendByte(address[i]); RADIO_DIS_CS(); }
void handleTxData() { uint8_t ret= 0; if(!(DEVIO_NRF_IRQ & NRF_IRQ_INPUT)) { ret = SPI_SendCommand(CMD_REG_READ + REG_STATUS, DUMMY_BYTE); if(ret & TX_DS) { // TX was acknowledged, clear interrupt flag, set back to PRX SPI_SendCommand(CMD_REG_WRITE + REG_STATUS, TX_DS); NRF_CE_LOW; SPI_SendCommand(CMD_REG_WRITE + REG_CONFIG,PRIM_RX + PWR_UP + EN_CRC + CRCO); NRF_CE_HIGH; } else if (ret & MAX_RT) { // Maximum number of TX retries reached, clear flags, set back to PRX NRF_CE_LOW; SPI_SendCommand(CMD_REG_WRITE + REG_STATUS, MAX_RT); SPI_SendByte(CMD_TX_FLUSH); NRF_CE_LOW; SPI_SendCommand(CMD_REG_WRITE + REG_CONFIG,PRIM_RX + PWR_UP + EN_CRC + CRCO); NRF_CE_HIGH; } } }
void SPI_Write(unsigned char *string) { LED_RED_ON; while(*string) { SPI_SendByte(*string++); } LED_RED_OFF; }
//uint8_t device_code1; uint8_t hwspi_read_id() { HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_REMS); SPI_SendByte(0); SPI_SendByte(0); SPI_SendByte(0); //maker_code = 0xC2; //device_code0 = 0x18; maker_code = SPI_ReceiveByte(); device_code0 = SPI_ReceiveByte(); HWSPI_CS_HIGH; return 1; }
/***************************************************************** 程序名:Write_W5100 输入: 地址,字节数据 输出: 无 返回: 无 说明:将一个字节写入W5100指定的地址 *****************************************************************/ void Write_W5100(unsigned short addr, unsigned char dat) { /* 置W5100的CS为低电平 */ GPIO_ResetBits(GPIOB, W5100_SCS); /* 发送写命令 */ SPI_SendByte(0xf0); /* 发送地址 */ SPI_SendByte(addr/256); SPI_SendByte(addr); /* 写入数据 */ SPI_SendByte(dat); /* 置W5100的CS为高电平 */ GPIO_SetBits(GPIOB, W5100_SCS); }
uint8_t hwspi_status() { uint8_t status; HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_RDSR); status = SPI_ReceiveByte(); HWSPI_CS_HIGH; return status; }
uint8_t hwspi_security() { uint8_t sec; HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_RDSCUR); sec = SPI_ReceiveByte(); HWSPI_CS_HIGH; return sec; }
//Nop command, permit to get the status byte char NRF24L01_Nop() { char status; RADIO_EN_CS(); status = SPI_SendByte(CMD_NOP); RADIO_DIS_CS(); return status; }
char NRF24L01_FlushRx() { char status; RADIO_EN_CS(); status = SPI_SendByte(CMD_FLUSH_RX); RADIO_DIS_CS(); return status; }
char NRF24L01_ReadReg(char addr) { char value; RADIO_EN_CS(); SPI_SendByte(CMD_R_REG | (addr&0x1F)); value = SPI_ReceiveByte(); RADIO_DIS_CS(); return value; }
void initNRF24L(void) { /* Port 2 Directions */ //P2SEL = 0x00; // For now, just set all pins to digital IO. XTAL_TO_GPIO; P2DIR |= DEVIO_P2OUT_NRF_CSN; P2DIR |= DEVIO_P2OUT_NRF_CE; P3DIR &= ~(DEVIO_NRF_IRQ); _delay_cycles(10000); NRF_CE_LOW; // Write TX address to TX address register SPI_SendBuffer( CMD_REG_WRITE + REG_TX_ADDR, NRF_TX_ADDR, NRF_TX_ADDR_WIDTH, NULL); // Write TX address to data pipe 0 address register, ignore return data SPI_SendBuffer( CMD_REG_WRITE + REG_RX_ADDR_P0, NRF_TX_ADDR, NRF_TX_ADDR_WIDTH, NULL); // Enable auto ack on data pipe 0 SPI_SendCommand(CMD_REG_WRITE + REG_ENAA, ENAA_P0); // Enable data pipe 0 SPI_SendCommand(CMD_REG_WRITE + REG_EN_RXADDR, ERX_P0); // Set the retry rate, Wait 500+86uS (0x10) and 10 retries (0x0A) SPI_SendCommand(CMD_REG_WRITE + REG_SETUP_RETR, 0x10 + 0x0A); // Set the RF channel SPI_SendCommand(CMD_REG_WRITE + REG_RF_CHAN, NRF_RF_CHANNEL); // Set the payload width for receiving SPI_SendCommand(CMD_REG_WRITE + REG_RX_PW_P0, PAYLOAD_WIDTH); // Set power and speed SPI_SendCommand(CMD_REG_WRITE + REG_RF_SETUP, RF_PWR_0dBm + RF_DR_2Mbps + LNA_HCURR); // Clear out status flags, clear buffers SPI_SendCommand(CMD_REG_WRITE + REG_STATUS, MAX_RT + RX_DR + TX_DS); SPI_SendByte(CMD_TX_FLUSH); SPI_SendByte(CMD_RX_FLUSH); // Power up, primary receiver, CRC encoding - 2 bytes SPI_SendCommand(CMD_REG_WRITE + REG_CONFIG, PRIM_RX + PWR_UP + EN_CRC + CRCO); NRF_CE_HIGH; _delay_cycles(10000); }
/***************************************************************** 程序名:Read_W5100 输入: 地址 输出: 无 返回: 读取的数据 说明:从W5100指定的地址读取一个字节 *****************************************************************/ unsigned char Read_W5100(unsigned short addr) { unsigned char i; /* 置W5100的CS为低电平 */ GPIO_ResetBits(GPIOB, W5100_SCS); /* 发送读命令 */ SPI_SendByte(0x0f); /* 发送地址 */ SPI_SendByte(addr/256); SPI_SendByte(addr); /* 发送一个哑书记并读取数据 */ i = SPI_SendByte(0); /* 置W5100的CS为高电平 */ GPIO_SetBits(GPIOB, W5100_SCS); return i; }
/******************************************************************************************************************** ** 函数名称: U8_T SD_SendCmd() Name: U8_T SD_SendCmd() ** 功能描述: 向卡发送命令,并取得响应 Function: send command to the card,and get a response ** 输 入: U8_T cmd : 命令字 Input: U8_T cmd : command byte U8_T *param : 命令参数,长度为4字节 U8_T *param : command parameter,length is 4 bytes U8_T resptype : 响应类型 U8_T resptype: response type U8_T *resp : 响应,长度为1-5字节 U8_T *resp : response,length is 1-5 bytes ** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code ********************************************************************************************************************/ U8_T SD_SendCmd(U8_T cmd, U8_T *param, U8_T resptype, U8_T *resp) { S8_T i; U8_T tmp,rlen; SPI_CS_Assert(); SPI_SendByte((cmd & 0x3F) | 0x40); /* 发送命令头和命令字 send command header and word */ for (i = 3; i >= 0; i--) SPI_SendByte(param[i]); /* 发送参数 send parameters */ if(cmd == CMD8) SPI_SendByte(CMD8_CRC); else if(cmd == CMD0) SPI_SendByte(0x95); /* CRC校验码,只用于第1个命令 CRC,only used for the first command */ else SPI_SendByte(0x00); rlen = 0; switch (resptype) /* 根据不同的命令,得到不同的响应长度 */ { /* according various command,get the various response length */ case R1: case R1B: rlen = 1; break; case R2: rlen = 2; break; case R3: case R7: rlen = 5; break; default: SPI_SendByte(0xFF); SPI_CS_Deassert(); return SD_ERR_CMD_RESPTYPE; /* 返回命令响应类型错误 return error of command response type */ break; } i = 0; do /* 等待响应,响应的开始位为0 */ { /* Wait for a response,a response is a start bit(zero) */ tmp = SPI_RecByte(); i++; }while (((tmp & 0x80) != 0) && (i < SD_CMD_TIMEOUT)); if (i >= SD_CMD_TIMEOUT) { SPI_CS_Deassert(); return SD_ERR_CMD_TIMEOUT; /* 返回命令超时 return response timeout of command */ } for (i = rlen - 1; i >= 0; i--) { resp[i] = tmp; tmp = SPI_RecByte(); /* 循环的最后发送8clock at the last recycle,clock out 8 clock */ } SPI_CS_Deassert(); return SD_NO_ERR; /* 返回执行成功 return perform sucessfully */ }
UINT8 SD_WriteSector(UINT32 u32SD_Block, UINT8 * pu8DataPointer) { UINT16 u16Counter; UINT8 SD_response; __RESET_WATCHDOG(); /* feeds the dog */ SPI_SS = ENABLE; if(!gSDCard.SDHC) u32SD_Block <<= SD_BLOCK_SHIFT; if(SD_SendCommand(SD_CMD24_WRITE_BLOCK, u32SD_Block, NULL, 0) != SD_OK) { SPI_SS = DISABLE; return (SD_FAIL_WRITE); } SPI_SendByte(0xFE); for(u16Counter = 0; u16Counter < SD_BLOCK_SIZE; u16Counter++) SPI_SendByte(*pu8DataPointer++); SPI_SendByte(0xFF); // checksum Bytes not needed SPI_SendByte(0xFF); SD_response=0xFF; while (SD_response == 0xFF) SD_response = SPI_ReceiveByte(); if((SD_response & 0x0F) != 0x05) { SPI_SS=DISABLE; return (SD_FAIL_WRITE); } while(SPI_ReceiveByte()==0x00) ; // Dummy SPI cycle (void) SPI_ReceiveByte(); SPI_SS = DISABLE; return (SD_OK); }
uint8_t hwspi_read_block() { uint16_t i; uint8_t sreg; if (SPI_USE_3B_CMDS && SPI_ADDRESS_LENGTH == 4) { HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_EN4B); HWSPI_CS_HIGH; } /* Save global interrupt flag and disable interrupts */ sreg = SREG; cli(); HWSPI_CS_LOW; if (SPI_USE_3B_CMDS || SPI_ADDRESS_LENGTH == 3) SPI_SendByte(SPI_COMMAND_3B_READ); else SPI_SendByte(SPI_COMMAND_4B_READ); /* address */ if (SPI_ADDRESS_LENGTH == 4) SPI_SendByte(buf_addr[0]); SPI_SendByte(buf_addr[1]); SPI_SendByte(buf_addr[2]); SPI_SendByte(buf_addr[3]); for (uint8_t k = 0; k < SPI_BLOCK_SIZE / BUF_SIZE_RW; ++k) { for (i = 0; i < BUF_SIZE_RW; ++i) { buf_rw[i] = SPI_ReceiveByte(); } usb_serial_write(buf_rw, BUF_SIZE_RW); } uint16_t rest = SPI_BLOCK_SIZE - ((SPI_BLOCK_SIZE / BUF_SIZE_RW) * BUF_SIZE_RW); for (i = 0; i < rest; ++i) { buf_rw[i] = SPI_ReceiveByte(); } HWSPI_CS_HIGH; usb_serial_write(buf_rw, rest); /* Restore global interrupt flag */ SREG = sreg; return 1; }
void SPI_Read(unsigned char *readBuffer) { unsigned char rxByte = 0; char rxCount = MAX_RX_BYTES - 1; LED_GREEN_ON; do { // read until ending character is received rxByte = SPI_SendByte(0); *readBuffer++ = rxByte; if(rxCount-- <= 0) { return; } } while(rxByte != ENDING_CHARACTER_DATA); LED_GREEN_OFF; }
int8_t hwspi_erase_block() { if (SPI_USE_3B_CMDS && SPI_ADDRESS_LENGTH == 4) { HWSPI_CS_LOW; SPI_SendByte(SPI_COMMAND_EN4B); HWSPI_CS_HIGH; } HWSPI_WP_HIGH; // set write enable bit HWSPI_WREN; /* block erase setup command */ HWSPI_CS_LOW; if (SPI_USE_3B_CMDS || SPI_ADDRESS_LENGTH == 3) SPI_SendByte(SPI_COMMAND_3B_BLOCK_ERASE_64K); else SPI_SendByte(SPI_COMMAND_4B_BLOCK_ERASE_64K); /* block address */ if (SPI_ADDRESS_LENGTH == 4) SPI_SendByte(buf_addr[0]); SPI_SendByte(buf_addr[1]); SPI_SendByte(buf_addr[2]); SPI_SendByte(buf_addr[3]); HWSPI_CS_HIGH; // wait for the internal controller to finish the erase command SPI_BUSY_WAIT; HWSPI_WP_LOW; if ((hwspi_status() & (SPI_STATUS_BP0 | SPI_STATUS_BP1 | SPI_STATUS_BP2 | SPI_STATUS_BP3 | SPI_STATUS_SRWD))) { return -1; } if ((maker_code == 0xC2) && (device_code0 == 0x18)) { if (hwspi_security() & (SPI_SECURITY_E_FAIL | SPI_SECURITY_WPSEL)) return 0; } return 1; }
//MSB of register is sent first, MSB should be in DataToWrite[0] bool AD7794WriteReg( uint8_t reg, uint8_t *DataToWrite) { if( (reg == 1) || (reg == 2) || (reg == 5) || (reg == 6) || (reg == 7) ) { //Mask the mode register if(reg == 1) { //The masked bits of the mode register must always be zero DataToWrite[1] &= AD7794_CR_REG_MODE_MASK_H; DataToWrite[0] &= AD7794_CR_REG_MODE_MASK_L; } //Send data AD7794Select(1); SPI_SendByte( AD7794_CR_WRITE | (reg << 3) ); if(reg == 5) { //8-bit write SPI_SendByte(DataToWrite[0]); } else if( (reg == 1) || (reg == 2) ) { //16-bit write SPI_SendByte(DataToWrite[1]); SPI_SendByte(DataToWrite[0]); } else { //24-bit write SPI_SendByte(DataToWrite[2]); SPI_SendByte(DataToWrite[1]); SPI_SendByte(DataToWrite[0]); } AD7794Select(0); return true; } //Invalid register return false; }
void ISR_SPI1_INT0(void) { unsigned long vector = spiREG1->INTVECT0; if(((vector & INTVECT) >> 1) == 0x14L) { /* The pending interrupt is a "Transmit Buffer Empty" interrupt */ if(SPI_TX_Buffer_Remove_place != SPI_TX_Buffer_Add_place) { SPI_SendByte(SPI_TX_Buffer[SPI_TX_Buffer_Remove_place].Data, SPI_TX_Buffer[SPI_TX_Buffer_Remove_place].Channel, SPI_TX_Buffer[SPI_TX_Buffer_Remove_place].HoldCS); SPI_TX_Buffer_Remove_place++; if(SPI_TX_Buffer_Remove_place >= SPI_TX_BUFFER_SIZE) { SPI_TX_Buffer_Remove_place = 0; } } else { SPI_TransmitInterrupt1(OFF); } } }