Comments (20)
Thanks for the great project!
With the standard 328a processor, I was able to get the boot time down to 8 hours, 18 minutes with the following changes:
spi.c:
// set SPI params
// SPCR |= ((uint8_t) (initParams >> 8)) | (1 << SPE);
// SPSR |= ((uint8_t) initParams);
SPCR = ((uint8_t) (initParams >> 8)) | (1 << SPE);
SPSR = ((uint8_t) initParams);
sdcard.c
//SPI_init(SPI_MASTER | SPI_2X_FOSC_2 | SPI_MODE_0);
// works! SPI_init(SPI_MASTER | SPI_2X_FOSC_8 | SPI_MODE_0);
SPI_init(SPI_MASTER | SPI_FOSC_4 | SPI_MODE_0);
Next up I plan to port the code to an Atmega1280 so I can increase the number of cache buffers with the extra RAM.
Cheers!
Mark Jungwirth
from arv32-opt.
Is it correct if I add a line
SPI_init(SPI_MASTER | SPI_2X_FOSC_2 | SPI_MODE_0);
after the lineSD_readOCR(res);
in the filesdcard.c
, as described here?
At first glance this is the correct thing to do, however looking at the code https://github.com/raspiduino/arv32-opt/blob/f831c56cb7dc86fe63289bde70ce3d3ea5242d68/spi.c#L20C1-L21C36 there is a binary OR made instead of a plain write to SPCR and SPSR. This could make a mess depending on the constants as bits that may need to be cleared won't be cleared. You have to check carefully or change this code i think.
from arv32-opt.
I should have changed it to
=
instead of|=
, right?
Yes, exactly. =
is an assignment, |=
is a logical OR between the current value inside the register and the new one.
For the speed issue i am not sure, i think you should fix sdcard.c and then test again. And if possible check the real clock speed of the SPI-bus with an oscilloscope or logic analyzer.
from arv32-opt.
Thank you for your tips! I will check it out soon!
from arv32-opt.
Is it correct if I add a line SPI_init(SPI_MASTER | SPI_2X_FOSC_2 | SPI_MODE_0);
after the line SD_readOCR(res);
in the file sdcard.c
, as described here?
from arv32-opt.
In the library greiman/SdFat
, the clock speed is upped to max after CMD58 is sent here, which would also match what your SD_readOCR()
does -- maybe it helps to compare? It also does a spiStop()
just before that though.
from arv32-opt.
Is it correct if I add a line
SPI_init(SPI_MASTER | SPI_2X_FOSC_2 | SPI_MODE_0);
after the lineSD_readOCR(res);
in the filesdcard.c
, as described here?
I have tried this, and it actually worked! I increased the clock to 8 MHz, and the average speed got up to 1100Hz. But the emulator will hang if I connect pin 9 to GND (to check speed), for some reason. If I just leave it there and don't check the speed, it will work.
At start:
Peak speed(?):
from arv32-opt.
But the emulator will hang if I connect pin 9 to GND (to check speed), for some reason
Did you release pin 9 again? There is a loop in your code that will wait until pin 9 is high again: https://github.com/raspiduino/arv32-opt/blob/f9d3f5ff05c057cd85f6ce3f32edb875d328cb75/main.c#L301C13-L301C44
from arv32-opt.
But the emulator will hang if I connect pin 9 to GND (to check speed), for some reason
Did you release pin 9 again? There is a loop in your code that will wait until pin 9 is high again: https://github.com/raspiduino/arv32-opt/blob/f9d3f5ff05c057cd85f6ce3f32edb875d328cb75/main.c#L301C13-L301C44
Yes, I released it. That's weird. I think maybe because my SD card is damaged, sometime it also unreadable. I will try switching to another SD card.
from arv32-opt.
There is a related issue #5 which also occurs when the SPI clock is 8MHz. Changed it back to 1MHz solved the problem, but I don't know why it will hang at 8MHz
from arv32-opt.
I am afraid your commit a3a42ad did not change the SPI frequency to 8MHz (Fosc/2) but only to 250kHz (Fosc/64). This is because as i said you are doing an binary OR instead of a plain write to SPCR and SPSR.
I just simulated this with some code, carefuly compare the results of this code with the datasheet of the 328P:
#include <stdio.h>
#include <stdint.h>
#define SPE 6
#define SPI_MASTER 0b0001000000000000
#define SPI_SLAVE 0b0000000000000000
#define SPI_FOSC_4 0b0000000000000000
#define SPI_FOSC_8 0b0000010100000000
#define SPI_FOSC_16 0b0000000100000000
#define SPI_FOSC_64 0b0000001000000000
#define SPI_FOSC_128 0b0000001100000000
#define SPI_2X_FOSC_2 0b0000000000000001
#define SPI_2X_FOSC_8 0b0000000100000001
#define SPI_2X_FOSC_32 0b0000001000000001
#define SPI_2X_FOSC_64 0b0000001100000001
#define SPI_INTERRUPTS 0b1000000000000000
#define SPI_MODE_0 0b0000000000000000
#define SPI_MODE_1 0b0000010000000000
#define SPI_MODE_2 0b0000100000000000
#define SPI_MODE_3 0b0000110000000000
#define SPI_DEFAULT SPI_MASTER | SPI_FOSC_128 | SPI_MODE_0
int main(void)
{
uint16_t initParams;
uint8_t SPCR=0;
uint8_t SPSR=0;
initParams=SPI_DEFAULT;
SPCR |= ((uint8_t) (initParams >> 8)) | (1 << SPE);
SPSR |= ((uint8_t) initParams);
printf("SPCR: 0x%02X\n", SPCR);
printf("SPSR: 0x%02X\n", SPSR);
printf("\n");
initParams=SPI_MASTER | SPI_2X_FOSC_2 | SPI_MODE_0;
SPCR |= ((uint8_t) (initParams >> 8)) | (1 << SPE);
SPSR |= ((uint8_t) initParams);
printf("SPCR: 0x%02X\n", SPCR);
printf("SPSR: 0x%02X\n", SPSR);
return 0;
}
However i am not sure this explains the instability/problems you are encountering. :( But in any case i would suggest fixing sdcard.c (by removing the OR) and try again with max speed. If this does not work maybe you have some electrical issue (signal integrity, ...)? Can you check with a scope?
from arv32-opt.
did not change the SPI frequency to 8MHz (Fosc/2) but only to 250kHz (Fosc/64).
But if that's true, then I don't understand why the effective emulated speed is even higher than the speed when I run with 1MHz SPI clock.
This is because as i said you are doing an binary OR instead of a plain write to SPCR and SPSR.
Stupid me. I should have changed it to =
instead of |=
, right?
I'm not really good at plain AVR C registers tho, sorry for that.
from arv32-opt.
I just do that and the SD read failed 10 times in a row. I will try again later, probably my SD card problem.
from arv32-opt.
I will see if i have a SD card somewhere and try myself if time allows.
from arv32-opt.
Line 17 in 3c6f041
That's not correct! If you want a pullup (which shouldn't be needed btw) you must write a '1' to PINx PORTx. Here you are setting MISO as an output so the SD card and the AVR will "fight" against each other!
EDIT: correction :(
from arv32-opt.
Ok, so SPI2X does not work. I guess SD in SPI-mode have a maximum clock frequency <=4MHz? Does anybody know? This is weird...
However with 4MHz (XTAL/4) it works fine with my own SD-card routines. I used those because i am obviously more familiar with them. You can find them on my github but please note that they are AGPLv3+, so probably not compatible with your project. Of course you can look at them to see how they work anway, but you probably can't copy them to your project (you should specify a licence!).
My remark about the wrong register for Pullup also applies to the pin for dumping the emulator state. Should i make another PR to fix this?
EDIT: Speed is just above 2kHz for my test, Linux has started it's internal stuff, currently "devtmpfs: initialized". I will stop here to not write to much to the SD card.
from arv32-opt.
That's not correct! If you want a pullup (which shouldn't be needed btw) you must write a '1' to PINx. Here you are setting MISO as an output so the SD card and the AVR will "fight" against each other!
Wait, so it should be PORT_SPI
? I got that code from https://github.com/ryanj1234/SD_TUTORIAL_PART4/blob/b10700ff6571a1cc16299ad23dfeb40e90d7014d/spi.c#L17 and don't check it again because it already worked. My bad.
My remark about the wrong register for Pullup also applies to the pin for dumping the emulator state.
Line 250 in a493989
Wait, this code actually writes to
PORTB
, to enable pullup. I also didn't write anything to that pin's DDRB bit, so it should be 0 (input), right? So I don't really understand why the pullup code for pin 9 has wrong register used.
EDIT: Speed is just above 2kHz for my test, Linux has started it's internal stuff, currently "devtmpfs: initialized". I will stop here to not write to much to the SD card.
Thank you for testing. 2KHz is way much better than the normal 700Hz!
from arv32-opt.
I apologize, i got confused. :( For the pullup it is indeed PORTx. It is not DDRx however, writing a '1' there will set the pin to output.
DDRx=1 -> output
PORTx=0/1 for 0/1 as output OR 1 for pullup for input
from arv32-opt.
Thanks for the great project! With the standard 328a processor, I was able to get the boot time down to 8 hours, 18 minutes with the following changes: spi.c: // set SPI params // SPCR |= ((uint8_t) (initParams >> 8)) | (1 << SPE); // SPSR |= ((uint8_t) initParams); SPCR = ((uint8_t) (initParams >> 8)) | (1 << SPE); SPSR = ((uint8_t) initParams);
sdcard.c //SPI_init(SPI_MASTER | SPI_2X_FOSC_2 | SPI_MODE_0); // works! SPI_init(SPI_MASTER | SPI_2X_FOSC_8 | SPI_MODE_0); SPI_init(SPI_MASTER | SPI_FOSC_4 | SPI_MODE_0);
Next up I plan to port the code to an Atmega1280 so I can increase the number of cache buffers with the extra RAM. Cheers! Mark Jungwirth
Thank you! I will definitely try that soon! I would be happy to accept if you make a PR
from arv32-opt.
I will close this as changes are merged to main. Feel free to reopen or create a new issue report if you want. Thank you!
from arv32-opt.
Related Issues (3)
- Running on Wokwi HOT 1
- Boot stalls at address 0x80001CBC HOT 13
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arv32-opt.