Skip to content

Commit 28e1428

Browse files
committed
initial commit
0 parents  commit 28e1428

File tree

6 files changed

+1164
-0
lines changed

6 files changed

+1164
-0
lines changed

flash.cpp

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include "flash.h"
2+
3+
void waitBusy() {
4+
SET(CS_FLASH, LOW);
5+
SPI.transfer(0x05); //read status register
6+
while (SPI.transfer(0) & 0x01)
7+
;
8+
SET(CS_FLASH, HIGH);
9+
}
10+
11+
void SPI_Setup() {
12+
OUT(SS); // prevent SPI from entering slave mode
13+
SET(SS, HIGH);
14+
IN(MISO);
15+
16+
SPI.begin();
17+
SPI.setClockDivider(SPI_CLOCK_DIV2);
18+
SPI.setDataMode(SPI_MODE0);
19+
SPI.setBitOrder(MSBFIRST);
20+
}
21+
22+
void eraseFlash() {
23+
SPI_Setup();
24+
25+
SET(CS_FLASH, LOW);
26+
SPI.transfer(0x06); // Write mode
27+
SET(CS_FLASH, HIGH);
28+
29+
SET(CS_FLASH, LOW);
30+
SPI.transfer(0x01); // Write status reg
31+
SPI.transfer(0x00); // Disable protection
32+
SET(CS_FLASH, HIGH);
33+
34+
SET(CS_FLASH, LOW);
35+
SPI.transfer(0x06); // Write mode
36+
SET(CS_FLASH, HIGH);
37+
38+
SET(CS_FLASH, LOW);
39+
SPI.transfer(0x60); // Full chip erase
40+
SET(CS_FLASH, HIGH);
41+
42+
waitBusy(); // Wait for operation to finish
43+
44+
SPI.end();
45+
}
46+
47+
void writeByteFlash(uint32_t address, uint8_t b) {
48+
SPI_Setup();
49+
50+
waitBusy(); // wait for other writes
51+
52+
SET(CS_FLASH, LOW);
53+
SPI.transfer(0x06); // Write mode
54+
SET(CS_FLASH, HIGH);
55+
56+
SET(CS_FLASH, LOW);
57+
SPI.transfer(0x02); // Single write
58+
SPI.transfer(address >> 16);
59+
SPI.transfer(address >> 8);
60+
SPI.transfer(address);
61+
SPI.transfer(b);
62+
SET(CS_FLASH, HIGH);
63+
64+
SPI.end();
65+
}
66+
67+
void waitHardwareBusy() {
68+
SET(CS_FLASH, LOW);
69+
delayMicroseconds(1); // change to 1
70+
while (digitalRead(MISO) == 0)
71+
;
72+
SET(CS_FLASH, HIGH);
73+
}
74+
75+
void writeFlash(uint32_t startAddress, uint8_t *data, uint16_t length) {
76+
if (length < 2) {
77+
if (length == 1)
78+
writeByteFlash(startAddress, data[0]);
79+
return;
80+
}
81+
82+
uint16_t pos;
83+
84+
SPI_Setup();
85+
86+
waitBusy();
87+
88+
SET(CS_FLASH, LOW);
89+
SPI.transfer(0x70); // Hardware EOW detection
90+
SET(CS_FLASH, HIGH);
91+
92+
SET(CS_FLASH, LOW);
93+
SPI.transfer(0x06); // Write Enable
94+
SET(CS_FLASH, HIGH);
95+
96+
SET(CS_FLASH, LOW);
97+
SPI.transfer(0xAD); // Auto-increment write
98+
SPI.transfer(startAddress >> 16);
99+
SPI.transfer(startAddress >> 8);
100+
SPI.transfer(startAddress);
101+
SPI.transfer(data[0]);
102+
SPI.transfer(data[1]);
103+
SET(CS_FLASH, HIGH);
104+
105+
waitHardwareBusy();
106+
107+
for (pos = 2; pos <= length - 2; pos += 2) {
108+
SET(CS_FLASH, LOW);
109+
SPI.transfer(0xAD); // Auto-increment write
110+
SPI.transfer(data[pos]);
111+
SPI.transfer(data[pos + 1]);
112+
SET(CS_FLASH, HIGH);
113+
114+
waitHardwareBusy();
115+
}
116+
117+
SET(CS_FLASH, LOW);
118+
SPI.transfer(0x04); // Write Disable
119+
SET(CS_FLASH, HIGH);
120+
121+
SET(CS_FLASH, LOW);
122+
SPI.transfer(0x80); // Disable hardware EOW detection
123+
SET(CS_FLASH, HIGH);
124+
125+
if (pos < length)
126+
writeByteFlash(startAddress + pos, data[pos]);
127+
128+
}
129+
130+
void readFlash(volatile uint8_t* buffer, uint32_t address, uint16_t count) {
131+
SPI_Setup();
132+
133+
SET(CS_FLASH, LOW);
134+
SPI.transfer(0x03);
135+
SPI.transfer(address >> 16);
136+
SPI.transfer(address >> 8);
137+
SPI.transfer(address);
138+
139+
for (uint16_t c = 0; c < count; c++)
140+
buffer[c] = SPI.transfer(0);
141+
SET(CS_FLASH, HIGH);
142+
143+
SPI.end();
144+
}
145+
146+
147+
148+

flash.h

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
/*
3+
* flash.h
4+
*
5+
* Created on: Jan 17, 2014
6+
* Author: Justin Rajewski
7+
*/
8+
9+
#ifndef FLASH_H_
10+
#define FLASH_H_
11+
12+
#include "ring_buffer.h"
13+
#include "hardware.h"
14+
15+
void SPI_Setup(void);
16+
17+
/*
18+
* eraseFlash()
19+
* This will erase the entire flash
20+
* memory. This must be called before writing
21+
* to it to ensure it is in the erased state.
22+
*/
23+
void eraseFlash(void);
24+
25+
/*
26+
* writeByteFlash(address, byte)
27+
* This writes one byte to the address
28+
* specified.
29+
*/
30+
void writeByteFlash (uint32_t, uint8_t);
31+
32+
/*
33+
* writeFlash(address, data, length)
34+
* This will write a block of data of size length
35+
* to the flash starting at the address specified.
36+
*
37+
* The starting address MUST be an even number as
38+
* writes are performed in pairs. If an odd number
39+
* is given the actual start address will be the
40+
* address one earlier.
41+
*/
42+
void writeFlash(uint32_t, uint8_t*, uint16_t);
43+
44+
/*
45+
* readFlash(data, address, length)
46+
* This reads the flash memory and stores the
47+
* values into data. Data must be an array
48+
* of size length or more.
49+
*/
50+
void readFlash(volatile uint8_t*, uint32_t, uint16_t);
51+
52+
#endif /* FLASH_H_ */
53+

fpga.ino

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
inline void enableDataBus() {
2+
FPGA_BUS_DDR = 0xFF;
3+
}
4+
5+
void initLoad() {
6+
SET(INIT, HIGH);
7+
SET(CCLK, LOW);
8+
SET(PROGRAM, LOW);
9+
enableDataBus();
10+
}
11+
12+
void startLoad() {
13+
SET(CCLK, LOW);
14+
SET(PROGRAM, LOW);
15+
delay(1);
16+
SET(PROGRAM, HIGH);
17+
while (!VALUE(INIT));
18+
}
19+
20+
void sendByte(uint8_t b) {
21+
FPGA_BUS_PORT = b;
22+
SET(CCLK, HIGH);
23+
SET(CCLK, LOW);
24+
}
25+
26+
void sendExtraClocks() {
27+
FPGA_BUS_PORT = 0xff;
28+
for (int i = 0; i < 10; i++) {
29+
SET(CCLK, HIGH);
30+
SET(CCLK, LOW);
31+
}
32+
}
33+
34+
void loadFromFlash() {
35+
uint32_t lastAddr = 0;
36+
37+
initLoad();
38+
startLoad();
39+
40+
readFlash(loadBuffer, 0, 5);
41+
42+
if (loadBuffer[0] != 0xaa){
43+
return;
44+
}
45+
46+
for (uint8_t k = 0; k < 4; k++) {
47+
lastAddr |= (uint32_t) loadBuffer[k + 1] << (k * 8);
48+
}
49+
50+
uint32_t curAddr = 5;
51+
52+
while (curAddr + 256 < lastAddr) {
53+
readFlash(loadBuffer, curAddr, 256);
54+
enableDataBus();
55+
for (uint16_t i = 0; i < 256; i++) {
56+
sendByte(loadBuffer[i]);
57+
}
58+
curAddr += 256;
59+
}
60+
61+
if (curAddr < lastAddr) {
62+
uint8_t rem = lastAddr - curAddr;
63+
readFlash(loadBuffer, curAddr, rem);
64+
enableDataBus();
65+
for (uint8_t i = 0; i < rem; i++) {
66+
sendByte(loadBuffer[i]);
67+
}
68+
}
69+
70+
sendExtraClocks();
71+
}

hardware.h

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#ifndef HARDWARE_H_
2+
#define HARDWARE_H_
3+
4+
#include <avr/io.h>
5+
#include <avr/wdt.h>
6+
#include <avr/power.h>
7+
#include <avr/interrupt.h>
8+
#include <stdint.h>
9+
#include <stdbool.h>
10+
11+
#include "Arduino.h"
12+
#include <SPI.h>
13+
14+
#define FPGA_BUS_PORT PORTB
15+
#define FPGA_BUS_DDR DDRB
16+
#define FPGA_BUS_PIN PINB
17+
#define FPGA_BUS_MASK 0xFF
18+
#define FPGA_BUS_OFFSET 0
19+
20+
#define ADC_BUS_PORT PORTB
21+
#define ADC_BUS_DDR DDRB
22+
#define ADC_BUS_PIN PINB
23+
#define ADC_BUS_MASK 0xF0
24+
#define ADC_BUS_OFFSET 4
25+
26+
#define CCLK_N 3
27+
#define CS_FLASH_N 2
28+
#define INIT_N 30
29+
#define TX_BUSY_N 30
30+
#define DONE_N 5
31+
#define PROGRAM_N 13
32+
33+
#define CCLK_PORT PORTD
34+
#define CCLK_DDR DDRD
35+
#define CCLK_BIT PD0
36+
#define CCLK_PIN PIND
37+
38+
#define CS_FLASH_PORT PORTD
39+
#define CS_FLASH_DDR DDRD
40+
#define CS_FLASH_BIT PD1
41+
#define CS_FLASH_PIN PIND
42+
43+
#define INIT_PORT PORTD
44+
#define INIT_DDR DDRD
45+
#define INIT_BIT PD5
46+
#define INIT_PIN PIND
47+
48+
#define TX_BUSY_PORT PORTD
49+
#define TX_BUSY_DDR DDRD
50+
#define TX_BUSY_BIT PD5
51+
#define TX_BUSY_PIN PIND
52+
53+
#define DONE_PORT PORTC
54+
#define DONE_DDR DDRC
55+
#define DONE_BIT PC6
56+
#define DONE_PIN PINC
57+
58+
#define PROGRAM_PORT PORTC
59+
#define PROGRAM_DDR DDRC
60+
#define PROGRAM_BIT PC7
61+
#define PROGRAM_PIN PINC
62+
63+
#define MISO_PORT PORTB
64+
#define MISO_DDR DDRB
65+
#define MISO_BIT PB3
66+
#define MISO_PIN PINB
67+
68+
#define SS_PORT PORTB
69+
#define SS_DDR DDRB
70+
#define SS_BIT PB0
71+
#define SS_PIN PINB
72+
73+
#define SET(p, v) p ## _PORT = (p ## _PORT & ~(1 << p ## _BIT)) | (v << p ## _BIT)
74+
#define VALUE(p) (p ## _PIN & (1 << p ## _BIT))
75+
#define OUT(p) p ## _DDR |= (1 << p ## _BIT)
76+
#define IN(p) p ## _DDR &= ~(1 << p ## _BIT)
77+
78+
#define LINESTATE_DTR 1
79+
80+
#endif /* HARDWARE_H_ */

0 commit comments

Comments
 (0)