mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Update SPI peripheral to accept writes to FIFO always. Worked on this together with Naiche and Rose.
This commit is contained in:
		
							parent
							
								
									4a1abb1d17
								
							
						
					
					
						commit
						9ac889e3e8
					
				@ -91,28 +91,28 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count) {
 | 
			
		||||
    while((r = spi_dummy()) != SD_DATA_TOKEN);
 | 
			
		||||
 | 
			
		||||
    crc = 0;
 | 
			
		||||
    n = 512;
 | 
			
		||||
    do {
 | 
			
		||||
      uint8_t x = spi_dummy();
 | 
			
		||||
      *p++ = x;
 | 
			
		||||
      crc = crc16(crc, x);
 | 
			
		||||
    } while (--n > 0);
 | 
			
		||||
 | 
			
		||||
    /* n = 512/8; */
 | 
			
		||||
    /* n = 512; */
 | 
			
		||||
    /* do { */
 | 
			
		||||
    /*   // Send 8 dummy bytes (fifo should be empty) */
 | 
			
		||||
    /*   for (j = 0; j < 8; j++) { */
 | 
			
		||||
    /*     spi_sendbyte(0xff); */
 | 
			
		||||
    /*   } */
 | 
			
		||||
 | 
			
		||||
    /*   // Reset counter. Process bytes AS THEY COME IN. */
 | 
			
		||||
    /*   for (j = 0; j < 8; j++) { */
 | 
			
		||||
    /*     while (!(read_reg(SPI_IP) & 2)) {} */
 | 
			
		||||
    /*     uint8_t x = spi_readbyte(); */
 | 
			
		||||
    /*   uint8_t x = spi_dummy(); */
 | 
			
		||||
    /*   *p++ = x; */
 | 
			
		||||
    /*   crc = crc16(crc, x); */
 | 
			
		||||
    /*   } */
 | 
			
		||||
    /* } while(--n > 0); */
 | 
			
		||||
    /* } while (--n > 0); */
 | 
			
		||||
 | 
			
		||||
    n = 512/8;
 | 
			
		||||
    do {
 | 
			
		||||
      // Send 8 dummy bytes (fifo should be empty)
 | 
			
		||||
      for (j = 0; j < 8; j++) {
 | 
			
		||||
        spi_sendbyte(0xff);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Reset counter. Process bytes AS THEY COME IN.
 | 
			
		||||
      for (j = 0; j < 8; j++) {
 | 
			
		||||
        while (!(read_reg(SPI_IP) & 2)) {}
 | 
			
		||||
        uint8_t x = spi_readbyte();
 | 
			
		||||
        *p++ = x;
 | 
			
		||||
        crc = crc16(crc, x);
 | 
			
		||||
      }
 | 
			
		||||
    } while(--n > 0);
 | 
			
		||||
    
 | 
			
		||||
    // Read CRC16 and check
 | 
			
		||||
    crc_exp = ((uint16_t)spi_dummy() << 8);
 | 
			
		||||
 | 
			
		||||
@ -148,8 +148,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
    // APB access
 | 
			
		||||
    assign Entry = {PADDR[7:2],2'b00};  //  32-bit word-aligned accesses
 | 
			
		||||
    assign Memwrite = PWRITE & PENABLE & PSEL;  // Only write in access phase
 | 
			
		||||
    // JACOB: This shouldn't behave this way
 | 
			
		||||
    assign PREADY = TransmitInactive; // Tie PREADY to transmission for hardware interlock
 | 
			
		||||
    assign PREADY = Entry == SPI_TXDATA | Entry == SPI_RXDATA | TransmitInactive; // Tie PREADY to transmission for hardware interlock
 | 
			
		||||
 | 
			
		||||
    // Account for subword read/write circuitry
 | 
			
		||||
    // -- Note SPI registers are 32 bits no matter what; access them with LW SW.
 | 
			
		||||
@ -188,11 +187,15 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
                    SPI_DELAY0:  Delay0 <= {Din[23:16], Din[7:0]};
 | 
			
		||||
                    SPI_DELAY1:  Delay1 <= {Din[23:16], Din[7:0]};
 | 
			
		||||
                    SPI_FMT:     Format <= {Din[19:16], Din[2]};                    
 | 
			
		||||
                    SPI_TXDATA:  if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0];
 | 
			
		||||
                    SPI_TXMARK:  TransmitWatermark <= Din[2:0];
 | 
			
		||||
                    SPI_RXMARK:  ReceiveWatermark <= Din[2:0];
 | 
			
		||||
                    SPI_IE:      InterruptEnable <= Din[1:0];
 | 
			
		||||
                endcase
 | 
			
		||||
 | 
			
		||||
            if (Memwrite)
 | 
			
		||||
                case(Entry)
 | 
			
		||||
                    SPI_TXDATA:  if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0];
 | 
			
		||||
                endcase
 | 
			
		||||
            /* verilator lint_off CASEINCOMPLETE */
 | 
			
		||||
 | 
			
		||||
            // According to FU540 spec: Once interrupt is pending, it will remain set until number 
 | 
			
		||||
@ -268,11 +271,12 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
 | 
			
		||||
    always_ff @(posedge PCLK)
 | 
			
		||||
        if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0;
 | 
			
		||||
        else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == 8'h48) & ~TransmitFIFOWriteFull & TransmitInactive);
 | 
			
		||||
        // else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == 8'h48) & ~TransmitFIFOWriteFull & TransmitInactive);
 | 
			
		||||
        else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull);
 | 
			
		||||
 | 
			
		||||
    always_ff @(posedge PCLK)
 | 
			
		||||
        if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0;
 | 
			
		||||
        else ReceiveFIFOReadIncrement <= ((Entry == 8'h4C) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement);
 | 
			
		||||
        else ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement);
 | 
			
		||||
    
 | 
			
		||||
    // Tx/Rx FIFOs
 | 
			
		||||
    spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitShiftEmpty, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0],
 | 
			
		||||
@ -301,6 +305,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
        if (~PRESETn) begin 
 | 
			
		||||
                        state <= CS_INACTIVE;
 | 
			
		||||
                        FrameCount <= 4'b0;
 | 
			
		||||
                        SPICLK <= SckMode[1];
 | 
			
		||||
        end else if (SCLKenable) begin
 | 
			
		||||
            /* verilator lint_off CASEINCOMPLETE */
 | 
			
		||||
            case (state)
 | 
			
		||||
@ -311,21 +316,32 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
                        InterCSCount <= 9'b10;
 | 
			
		||||
                        InterXFRCount <= 9'b1;
 | 
			
		||||
                        if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty) & ((|(Delay0[7:0])) | ~SckMode[0])) state <= DELAY_0;
 | 
			
		||||
                        else if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty)) state <= ACTIVE_0;
 | 
			
		||||
                        else if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty)) begin
 | 
			
		||||
                          state <= ACTIVE_0;
 | 
			
		||||
                          SPICLK <= ~SckMode[1];
 | 
			
		||||
                        end
 | 
			
		||||
                        end
 | 
			
		||||
                DELAY_0: begin
 | 
			
		||||
                        CS_SCKCount <= CS_SCKCount + 9'b1;
 | 
			
		||||
                        if (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1)) state <= ACTIVE_0;
 | 
			
		||||
                        if (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1)) begin
 | 
			
		||||
                          state <= ACTIVE_0;
 | 
			
		||||
                          SPICLK <= ~SckMode[1];
 | 
			
		||||
                        end
 | 
			
		||||
                        end
 | 
			
		||||
                ACTIVE_0: begin 
 | 
			
		||||
                        FrameCount <= FrameCount + 4'b1;
 | 
			
		||||
                        SPICLK <= SckMode[1];
 | 
			
		||||
                        state <= ACTIVE_1;
 | 
			
		||||
                        end
 | 
			
		||||
                ACTIVE_1: begin
 | 
			
		||||
                        InterXFRCount <= 9'b1;
 | 
			
		||||
                        if (FrameCount < Format[4:1]) state <= ACTIVE_0;
 | 
			
		||||
                        if (FrameCount < Format[4:1]) begin
 | 
			
		||||
                          state <= ACTIVE_0;
 | 
			
		||||
                          SPICLK <= ~SckMode[1];
 | 
			
		||||
                        end
 | 
			
		||||
                        else if ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty)) begin
 | 
			
		||||
                            state <= ACTIVE_0;
 | 
			
		||||
                            SPICLK <= ~SckMode[1];
 | 
			
		||||
                            CS_SCKCount <= 9'b1;
 | 
			
		||||
                            SCK_CSCount <= 9'b10;
 | 
			
		||||
                            FrameCount <= 4'b0;
 | 
			
		||||
@ -349,8 +365,10 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
                        FrameCount <= 4'b0;
 | 
			
		||||
                        InterCSCount <= 9'b10;
 | 
			
		||||
                        InterXFRCount <= InterXFRCount + 9'b1;
 | 
			
		||||
                        if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & ~TransmitFIFOReadEmptyDelay) state <= ACTIVE_0;
 | 
			
		||||
                        else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE;
 | 
			
		||||
                        if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & ~TransmitFIFOReadEmptyDelay) begin
 | 
			
		||||
                          state <= ACTIVE_0;
 | 
			
		||||
                          SPICLK <= ~SckMode[1];
 | 
			
		||||
                        end else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE;
 | 
			
		||||
                        end
 | 
			
		||||
            endcase
 | 
			
		||||
            /* verilator lint_off CASEINCOMPLETE */
 | 
			
		||||
@ -360,11 +378,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
 | 
			
		||||
 | 
			
		||||
    assign DelayMode = SckMode[0] ? (state == DELAY_1) : (state == ACTIVE_1 & ReceiveShiftFull);
 | 
			
		||||
    assign ChipSelectInternal = (state == CS_INACTIVE | state == INTER_CS | DelayMode & ~|(Delay0[15:8])) ? ChipSelectDef : ~ChipSelectDef;
 | 
			
		||||
    assign SPICLK = (state == ACTIVE_0) ? ~SckMode[1] : SckMode[1];
 | 
			
		||||
    // assign preSPICLK = (state == ACTIVE_0) ? ~SckMode[1] : SckMode[1];
 | 
			
		||||
    assign Active = (state == ACTIVE_0 | state == ACTIVE_1);
 | 
			
		||||
    assign SampleEdge = SckMode[0] ? (state == ACTIVE_1) : (state == ACTIVE_0);
 | 
			
		||||
    assign ZeroDelayHoldMode = ((ChipSelectMode == 2'b10) & (~|(Delay1[7:4])));
 | 
			
		||||
    assign TransmitInactive = ((state == INTER_CS) | (state == CS_INACTIVE) | (state == INTER_XFR) | (ReceiveShiftFullDelayPCLK & ZeroDelayHoldMode));
 | 
			
		||||
    assign TransmitInactive = ((state == INTER_CS) | (state == CS_INACTIVE) | (state == INTER_XFR) | (ReceiveShiftFullDelayPCLK & ZeroDelayHoldMode) | ((state == ACTIVE_1) & ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty) & (FrameCount == 4'd8))));
 | 
			
		||||
    assign Active0 = (state == ACTIVE_0);
 | 
			
		||||
 | 
			
		||||
  // Signal tracks which edge of sck to shift data
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user