/****************************************************************************** * * This function reads serial flash ID connected to the SPI interface. * * @param None. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @note None. * ******************************************************************************/ int FlashReadID(void) { u8 Index; int Status; u8 ByteCount = 4; u8 SendBuffer[8]; u8 RecvBuffer[8]; SendBuffer[0] = READ_ID; SendBuffer[1] = 0; SendBuffer[2] = 0; SendBuffer[3] = 0; for(Index=0; Index < ByteCount; Index++) { SendBuffer[4 + Index] = 0x00; } Status = XSpiPs_PolledTransfer(&SpiInstance, SendBuffer, RecvBuffer, (4 + ByteCount)); if (Status != XST_SUCCESS) { return XST_FAILURE; } for(Index=0; Index < ByteCount; Index++) { xil_printf("ID : %0x\r\n", RecvBuffer[4 + Index]); } return XST_SUCCESS; }
void config_oled() { printf("****configuring oled!!!!!!!!!!!!!****\n\r"); XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, init_vector, NULL, 23); XGpioPs_WritePin(&Gpio, dc, 1); printf("****done configuring oled!!!!!!!!!!!!!****\n\r"); }
void blank_oled() { u8 cmd[1]; u8 data[1]; int loop; cmd[0] = (u8) 0xB0; data[0] = (u8) 0x00; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); for(loop=0;loop<128;loop++){ XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, data, NULL, 1); } cmd[0] = (u8) 0xB2; data[0] = (u8) 0x00; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); for(loop=0;loop<128;loop++){ XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, data, NULL, 1); } cmd[0] = (u8) 0xB1; data[0] = (u8) 0x00; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); for(loop=0;loop<128;loop++){ XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, data, NULL, 1); } cmd[0] = (u8) 0xB3; data[0] = (u8) 0x00; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); for(loop=0;loop<128;loop++){ XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, data, NULL, 1); } }
/****************************************************************************** * * This function reads from the serial flash connected to the * SPI interface. * * @param SpiPtr is a pointer to the SPI driver instance to use. * @param Address contains the address to read data from in the flash. * @param ByteCount contains the number of bytes to read. * @param Command is the command used to read data from the flash. SPI * device supports one of the Read, Fast Read commands to read * data from the flash. * * @return None. * * @note None. * ******************************************************************************/ void FlashRead(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command) { /* * Setup the read command with the specified address and data for the * flash */ WriteBuffer[COMMAND_OFFSET] = Command; WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16); WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8); WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF); XSpiPs_PolledTransfer(SpiPtr, WriteBuffer, ReadBuffer, ByteCount + OVERHEAD_SIZE); }
/****************************************************************************** * * This function reads from the serial EEPROM connected to the SPI interface. * * @param SpiPtr is a pointer to the SPI driver component to use. * @param Address contains the address to read data from in the EEPROM. * @param ByteCount contains the number of bytes to read. * @param Buffer is a buffer to read the data into. * * @return None. * * @note None. * ******************************************************************************/ void EepromRead(XSpiPs *SpiPtr, u16 Address, int ByteCount, EepromBuffer Buffer) { /* * Setup the write command with the specified address and data for the * EEPROM */ Buffer[COMMAND_OFFSET] = READ_CMD; Buffer[ADDRESS_MSB_OFFSET] = (u8)((Address & 0xFF00) >> 8); Buffer[ADDRESS_LSB_OFFSET] = (u8)(Address & 0x00FF); /* * Send the read command to the EEPROM to read the specified number * of bytes from the EEPROM, send the read command and address and * receive the specified number of bytes of data in the data buffer */ XSpiPs_PolledTransfer(SpiPtr, Buffer, &Buffer[DATA_OFFSET], ByteCount + OVERHEAD_SIZE); }
int32_t spi_write_and_read(struct spi_desc *desc, uint8_t *data, uint8_t bytes_number) { XSpiPs_SetOptions(&desc->instance, XSPIPS_MASTER_OPTION | XSPIPS_DECODE_SSELECT_OPTION | XSPIPS_FORCE_SSELECT_OPTION | ((desc->mode & SPI_CPOL) ? XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) | ((desc->mode & SPI_CPHA) ? XSPIPS_CLK_PHASE_1_OPTION : 0)); XSpiPs_SetSlaveSelect(&desc->instance, 0xf & ~desc->chip_select); XSpiPs_PolledTransfer(&desc->instance, data, data, bytes_number); return 0; }
/***************************************************************************//** * @brief spi_read *******************************************************************************/ int32_t spi_read(struct spi_device *spi, uint8_t *data, uint8_t bytes_number) { #ifdef _XPARAMETERS_PS_H_ XSpiPs_SetSlaveSelect(&spi_instance, (spi->id_no == 0 ? 0 : 1)); XSpiPs_PolledTransfer(&spi_instance, data, data, bytes_number); #else uint32_t cnt = 0; #ifdef XPAR_AXI_SPI_0_DEVICE_ID uint8_t send_buffer[20]; for(cnt = 0; cnt < bytes_number; cnt++) { send_buffer[cnt] = data[cnt]; } XSpi_Transfer(&spi_instance, send_buffer, data, bytes_number); #else Xil_Out32((spi_instance.BaseAddr + 0x60), 0x1e6); Xil_Out32((spi_instance.BaseAddr + 0x70), 0x000); while(cnt < bytes_number) { Xil_Out32((spi_instance.BaseAddr + 0x68), data[cnt]); Xil_Out32((spi_instance.BaseAddr + 0x60), 0x096); do {usleep(100);} while ((Xil_In32((spi_instance.BaseAddr + 0x64)) & 0x4) == 0x0); Xil_Out32((spi_instance.BaseAddr + 0x60), 0x186); data[cnt] = Xil_In32(spi_instance.BaseAddr + 0x6c); cnt++; } Xil_Out32((spi_instance.BaseAddr + 0x70), 0x001); Xil_Out32((spi_instance.BaseAddr + 0x60), 0x180); #endif #endif return SUCCESS; }
/***************************************************************************//** * @brief spi_write_and_read *******************************************************************************/ int32_t spi_write_and_read(uint8_t ss, uint8_t *data, uint8_t bytes_number) { #ifdef _XPARAMETERS_PS_H_ XSpiPs_SetSlaveSelect(&spi_instance, ss); XSpiPs_PolledTransfer(&spi_instance, data, data, bytes_number); #else uint8_t send_buffer[20]; uint32_t cnt = 0; ss = (1 << ss); XSpi_SetSlaveSelect(&spi_instance, ss); for(cnt = 0; cnt < bytes_number; cnt++) { send_buffer[cnt] = data[cnt]; } XSpi_Transfer(&spi_instance, send_buffer, data, bytes_number); #endif return 0; }
/****************************************************************************** * * * This function erases the sectors in the serial flash connected to the * SPI interface. * * @param SpiPtr is a pointer to the SPI driver instance to use. * * @return None. * * @note None. * ******************************************************************************/ void FlashErase(XSpiPs *SpiPtr) { u8 WriteEnableCmd = { WRITE_ENABLE_CMD }; /* must send 2 bytes */ u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0x0 }; /* must send 2 bytes */ u8 WriteStatusCmd[] = { WRITE_STATUS_CMD, 0x0 }; u8 FlashStatus[3]; /* * Send the write enable command to the flash so that it can be * written to, this needs to be sent as a separate transfer * before the erase */ XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd)); while (1) { XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus, sizeof(ReadStatusCmd)); /* * If the status indicates the write enabled, then stop * waiting; if a value of 0xFF in the status byte is * read from the device and this loop never exits, the * device slave select is possibly incorrect such that * the device status is not being read */ if ((FlashStatus[1] & 0x02) == 0x02) { break; } } /* * Clear write protect bits using write status command to the flash * so that it can be written to, this needs to be sent as a * separate transfer before the erase */ XSpiPs_PolledTransfer(SpiPtr, WriteStatusCmd, NULL, sizeof(WriteStatusCmd)); while (1) { XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus, sizeof(ReadStatusCmd)); /* * If the status indicates the WP bits cleared, then stop * waiting; if a value of 0xFF in the status byte is * read from the device and this loop never exits, the * device slave select is possibly incorrect such that * the device status is not being read */ if ((FlashStatus[1] & 0x1C) == 0x0) { break; } } /* * Send the write enable command to the flash so that it can be * written to, this needs to be sent as a separate transfer * before the erase */ XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd)); while (1) { XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus, sizeof(ReadStatusCmd)); /* * If the status indicates the write enabled, then stop * waiting; if a value of 0xFF in the status byte is * read from the device and this loop never exits, the * device slave select is possibly incorrect such that * the device status is not being read */ if ((FlashStatus[1] & 0x02) == 0x02) { break; } } /* * Performs chip erase. */ WriteBuffer[COMMAND_OFFSET] = CHIP_ERASE_CMD; XSpiPs_PolledTransfer(SpiPtr, WriteBuffer, NULL, 1); /* * Wait for the erase command to the flash to be completed */ while (1) { XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus, sizeof(ReadStatusCmd)); /* * If the status indicates the write is done, then stop * waiting; if a value of 0xFF in the status byte is * read from the device and this loop never exits, the * device slave select is possibly incorrect such that * the device status is not being read */ if ((FlashStatus[1] & 0x01) == 0) { break; } } }
/****************************************************************************** * * * This function writes to the desired address in serial flash connected to * the SPI interface. * * @param SpiPtr is a pointer to the SPI driver instance to use. * @param Address contains the address to write data to in the flash. * @param ByteCount contains the number of bytes to write. * @param Command is the command used to write data to the flash. * * @return None. * * @note None. * ******************************************************************************/ void FlashWrite(XSpiPs *SpiPtr, u32 Address, u32 ByteCount, u8 Command) { u8 WriteEnableCmd = { WRITE_ENABLE_CMD }; u8 WriteDisableCmd = { WRITE_DISABLE_CMD }; u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */ u8 FlashStatus[2]; u32 Temp = 0; u32 TempAddress = Address; u8 TempBuffer[5]; if (Command == WRITE_CMD) { for (Temp = 0; Temp < ByteCount ; Temp++, TempAddress++) { /* * Send the write enable command to the flash so * that it can be written to, this needs to be sent * as a seperate transfer before the write */ XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd)); /* * Setup the write command with the specified address * and data for the flash */ TempBuffer[COMMAND_OFFSET] = Command; TempBuffer[ADDRESS_1_OFFSET] = (u8)((TempAddress & 0xFF0000) >> 16); TempBuffer[ADDRESS_2_OFFSET] = (u8)((TempAddress & 0xFF00) >> 8); TempBuffer[ADDRESS_3_OFFSET] = (u8)(TempAddress & 0xFF); TempBuffer[DATA_OFFSET] = WriteBuffer[DATA_OFFSET + Temp]; /* * Send the write command, address, and data to the * flash to be written, no receive buffer is specified * since there is nothing to receive */ XSpiPs_PolledTransfer(SpiPtr, TempBuffer, NULL, 5); /* * Wait for the write command to the flash to be , * completed it takes some time for the data to be * written */ while (1) { /* * Poll the status register of the flash to * determine when it completes, by sending * a read status command and receiving the * status byte */ XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, FlashStatus, sizeof(ReadStatusCmd)); /* * If the status indicates the write is done, * then stop waiting, if a value of 0xFF in * the status byte is read from the device * and this loop never exits, the device slave * select is possibly incorrect such that the * device status is not being read */ if ((FlashStatus[1] & 0x01) == 0) { break; } } XSpiPs_PolledTransfer(SpiPtr, &WriteDisableCmd, NULL, sizeof(WriteDisableCmd)); } } }
/****************************************************************************** * * * This function writes to the serial EEPROM connected to the SPI interface. * This function is not designed to be a driver to handle all * the conditions of the EEPROM device. The EEPROM contains a 32 byte write * buffer which can be filled and then a write is automatically performed by * the device. All the data put into the buffer must be in the same page of * the device with page boundaries being on 32 byte boundaries. * * @param SpiPtr is a pointer to the SPI driver instance to use. * @param Address contains the address to write data to in the EEPROM. * @param ByteCount contains the number of bytes to write. * @param Buffer is a buffer of data to write from. * * @return None. * * @note None. * ******************************************************************************/ void EepromWrite(XSpiPs *SpiPtr, u16 Address, u8 ByteCount, EepromBuffer Buffer) { u8 WriteEnableCmd = { WRITE_ENABLE_CMD }; u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */ u8 EepromStatus[2]; int DelayCount = 0; /* * Send the write enable command to the SEEPOM so that it can be * written to, this needs to be sent as a seperate transfer before * the write */ XSpiPs_PolledTransfer(SpiPtr, &WriteEnableCmd, NULL, sizeof(WriteEnableCmd)); /* * Setup the write command with the specified address and data for the * EEPROM */ Buffer[COMMAND_OFFSET] = WRITE_CMD; Buffer[ADDRESS_MSB_OFFSET] = (u8)((Address & 0xFF00) >> 8); Buffer[ADDRESS_LSB_OFFSET] = (u8)(Address & 0x00FF); /* * Send the write command, address, and data to the EEPROM to be * written, no receive buffer is specified since there is nothing to * receive */ XSpiPs_PolledTransfer(SpiPtr, Buffer, NULL, ByteCount + OVERHEAD_SIZE); /* * Wait for a bit of time to allow the programming to occur as reading * the status while programming causes it to fail because of noisy power * on the board containing the EEPROM, this loop does not need to be * very long but is longer to hopefully work for a faster processor */ while (DelayCount++ < 10000) { } /* * Wait for the write command to the EEPROM to be completed, it takes * some time for the data to be written */ while (1) { /* * Poll the status register of the device to determine when it * completes by sending a read status command and receiving the * status byte */ XSpiPs_PolledTransfer(SpiPtr, ReadStatusCmd, EepromStatus, sizeof(ReadStatusCmd)); /* * If the status indicates the write is done, then stop waiting, * if a value of 0xFF in the status byte is read from the * device and this loop never exits, the device slave select is * possibly incorrect such that the device status is not being * read */ if ((EepromStatus[1] & 0x03) == 0) { break; } } }
int main() { XSpiPs_Config *SpiConfig_EMIO; XGpioPs_Config *GPIOConfigPtr; //gpio config int delay; u8 cmd[1]; int byte_i, temp; int loop; init_platform(); printf("SPI Demo MicroZed Chronicles\n\r"); SpiConfig_EMIO = XSpiPs_LookupConfig((u16)SPI_EMIO); XSpiPs_CfgInitialize(&SpiInstance_EMIO, SpiConfig_EMIO,SpiConfig_EMIO->BaseAddress); XSpiPs_SetOptions(&SpiInstance_EMIO,XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); XSpiPs_SetClkPrescaler(&SpiInstance_EMIO, XSPIPS_CLK_PRESCALE_256); GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID); XGpioPs_CfgInitialize(&Gpio, GPIOConfigPtr,GPIOConfigPtr->BaseAddr); //set direction and enable output XGpioPs_SetDirectionPin(&Gpio, sig, 1); XGpioPs_SetOutputEnablePin(&Gpio, sig, 1); XGpioPs_SetDirectionPin(&Gpio, res, 1); XGpioPs_SetOutputEnablePin(&Gpio, res, 1); XGpioPs_SetDirectionPin(&Gpio, vdd, 1); XGpioPs_SetOutputEnablePin(&Gpio, vdd, 1); XGpioPs_SetDirectionPin(&Gpio, bat, 1); XGpioPs_SetOutputEnablePin(&Gpio, bat, 1); XGpioPs_SetDirectionPin(&Gpio, dc, 1); XGpioPs_SetOutputEnablePin(&Gpio, dc, 1); XGpioPs_WritePin(&Gpio, sig, 0); XGpioPs_WritePin(&Gpio, res, 0); XGpioPs_WritePin(&Gpio, vdd, 1); XGpioPs_WritePin(&Gpio, bat, 1); XGpioPs_WritePin(&Gpio, dc, 1); XGpioPs_WritePin(&Gpio, vdd, 0); for( delay = 0; delay < DELAY; delay++)//wait {} XGpioPs_WritePin(&Gpio, res, 1); config_oled(); XGpioPs_WritePin(&Gpio, bat, 0); blank_oled();//clear screen //output page 1 for(loop=0;loop<16;loop++){ temp = (line_1[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_0[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB0; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_0, NULL, 128); //output page 2 for(loop=0;loop<16;loop++){ //loop =0; temp = (line_2[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_1[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB1; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_1, NULL, 128); //output page 3 for(loop=0;loop<16;loop++){ //loop =0; temp = (line_3[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_2[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB2; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_2, NULL, 128); //output page 4 for(loop=0;loop<16;loop++){ //loop =0; temp = (line_4[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_3[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB3; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_3, NULL, 128); return 0; }