SpenceKonde / DxCore

Arduino core for AVR DA, DB, DD, EA and future DU-series parts - Microchip's latest and greatest AVRs. Library maintainers: Porting help and adviccee is available.
Other
188 stars 49 forks source link

Add SD card library #114

Closed Kozma04 closed 2 years ago

Kozma04 commented 3 years ago

I am just wondering if a DxCore-compatible library which allows reading and writing to an SD card will be available, just like the Arduino one (https://github.com/arduino-libraries/SD).

SpenceKonde commented 3 years ago

Has anyone tried it? I haven't.

SpenceKonde commented 3 years ago

What fails with it?

My initial attempt would be to take that one, and in Sd2PinMap.h find the line

#elif defined(__AVR_ATmega4809__) // Arduino UNO WiFI Rev2 follows

and change it to

#elif (__AVR_ARCH__ == 102 || __AVR_ARCH__  == 103 || __AVR_ARCH__ == 104)

then see where it next starts complaining.

SpenceKonde commented 3 years ago

Can antone wirth hardware handy install this one in place of the normal one and see what doesn't work? https://github.com/SpenceKonde/SD If it works on SPI0's default pins, try alt pin sets. Because I'm less optimistic about those/

nabelekt commented 3 years ago

I was able to get this working fine for my purposes. Basically did what @SpenceKonde suggested above. Changes are at https://github.com/SpenceKonde/SD/compare/master...nabelekt:get-working-for-DA128DA28.

Compiles and runs fine on the DA128DA28 with the chipSelect pin set to 7.

sshwarts commented 3 years ago

I also use the modified library just fine on a AVR128DB48 with SD on PF2.

SpenceKonde commented 3 years ago

The chip select pin shouldn't make a difference - I'm referring to the pinswaps to get the alternate sck/miso/mosi pins. I think one would need to set SPI.swap(1); before the call to SPI.begin() is made.

SpenceKonde commented 2 years ago

Can anyone confirm whetherthis works after swapping to an alternate pinset using SPI.swap(non-zero)? That is the thing I' am ionly 90% sure of. Ince that's confirmed, I'm gonna try to get Arduino to merge it in.

SpenceKonde commented 2 years ago

we need a test done with SPI.swap(SPI1_SWAP1); (SPI1 with alternate pin mapping, using the PC4~PC6 lines on a 48+ pin part).

If that doesn't work, the next step would be to see whether it's the alternate port (SPI1 vs 0) that broke it, or the alternate pinset, or if either of them will break it, SPI.swap(SPI0_SWAP_1); puts the SPI port onto PE0-PE2) on a 48+ pin DA/DB, while SPI.swap(SPI1_SWAP_0) puts it on PC0~2.

microPaul commented 2 years ago

I can try this on a DB64. I'll report back in a day or two.

microPaul commented 2 years ago

Here are some results of my SPI testing this afternoon.

I'm using a homebrew DB64 and an SD card module jumpered into the DB64's SPI0 standard pins (PA4, PA5 and PA6). Not that it matters but I'm using PA3 as chip select. I'm also doing serial download (not UPDI) on DxCore 1.4.4.

I'm running this sketch: https://www.arduino.cc/en/Tutorial/LibraryExamples/CardInfo

With a #define Serial Serial4 near the top of the sketch (because the console on my DB64 is Serial4) but I do get a warning that states `p:\Users\p\Documents\Arduino\DB64-sd-card-info-220102-01\DB64-sd-card-info-220102-01.ino:5:0: warning: "Serial" redefined

define Serial Serial4

In file included from sketch\DB64-sd-card-info-220102-01.ino.cpp:1:0: C:\Users\p\AppData\Local\Arduino15\packages\DxCore\hardware\megaavr\1.3.10\cores\dxcore/Arduino.h:425:0: note: this is the location of the previous definition

define Serial Serial0 //Error here? Check for missing ; previous line in sketch.`

be that as it may, I do get nicely formatted output on my Serial Monitor from UART4 (primary)

And I changed the chip select define to be: const int chipSelect = PIN_PA3;

The rest of the sketch is as per the website reference.

When I run the program with the SD module attached to PA4-PA5-PA6 (cs on PA3) all looks good. All the output on the console about about blocks, cluster sizes and volumes looks good. However I don't get a list of the four text files that are on the SD card. Not sure why that's missing.

I then put a SPI.swap(1); immediately before the line if (!card.init(SPI_HALF_SPEED, chipSelect)) { which looks like the first SD card command.

I recompile, serial download, and then my Serial Monitor just shows jumbled characters, with a lot of backwards ? marks, like the serial baud rate is now wrong. So it looks like SPI.swap(1) causes problems for serial.

If I change the argument of the SPI.swap function from 1 to 0 [ SPI.swap(0) ] then the serial output works correctly again.

microPaul commented 2 years ago

Well this is embarrassing. Of course SPI.swap(1) kills serial on my test board. I'm using PE0 PE1 pins for my console terminal (UART4 primary) and PE0 PE1 are part of the pinset for SPI0 alternate.

Let me try some other SPI alternatives that are not going to interfere with other things on my board.

microPaul commented 2 years ago

Ok, good news! I've tested all the SPI swap possibilities (based on the table below) on the DB64 and they all appear to work correctly.

Here's the table from: https://github.com/SpenceKonde/DxCore/blob/master/megaavr/libraries/SPI/README.md

`Pin Mapping Pins Parts Swap-level name Synonym Value
SPI0 DEFAULT PA4-PA7 All SPI0_SWAP_DEFAULT SPI0_SWAP0 0x00
SPI0 ALT1 PE0-PE3 48+ pin SPI0_SWAP_ALT1 SPI0_SWAP1 0x01
SPI0 ALT2 PG4-PG7 DA/DB 64 SPI0_SWAP_ALT2 SPI0_SWAP2 0x02
SPI0 ALT3 PA0-1,PC0-1 DD/EA only SPI0_SWAP_ALT3 SPI0_SWAP3 0x03
SPI0 ALT4 PD4-PD7 DD/EA only SPI0_SWAP_ALT4 SPI0_SWAP4 0x04*
SPI0 ALT5 PC0-PC3 DD/EA only SPI0_SWAP_ALT5 SPI0_SWAP5 0x05*
SPI0 ALT6 PC1-PC3,PF7 DD/EA only SPI0_SWAP_ALT6 SPI0_SWAP6 0x06*
SPI1 DEFAULT PC0-PC3 DA/DB only SPI1_SWAP_DEFAULT SPI1_SWAP0 0x80
SPI1 ALT1 PC4-PC7 DA/DB 48/64 SPI1_SWAP_ALT1 SPI1_SWAP1 0x84*
SPI1 ALT2 PB4-PB7 DA/DB 64 SPI1_SWAP_ALT2 SPI1_SWAP2 0x88*

`

Here are the statements I used to select the particular pins to use for SPI given the argument of the swap statement:

//SPI.swap(SPI0_SWAP_DEFAULT); // this works: SPI on PA4 PA5 PA6 SPI.swap(SPI0_SWAP_ALT1); // this works: SPI on PE0 PE1 PE2 // SPI.swap(SPI0_SWAP_ALT2); // this works: SPI on PG4 PG5 PG6 //SPI.swap(SPI1_SWAP_DEFAULT); // this works: SPI on PC0 PC1 PC2 //SPI.swap(SPI1_SWAP_ALT1); // this works: SPI on PC4 PC5 PC6 //SPI.swap(SPI1_SWAP_ALT2); // this works: SPI on PB4 PB5 PB6

Of course, only one of these statements would be uncommented for a particular test (read info from SD card).

In the case of SPI0_SWAP_ALT1 which uses PE0, PE1, PE2 (and clobbered my Serial4 console in my initial test)...for that test I changed the solder bridging jumpers on my board to make Serial3 (PB0, PB1) my console and reburned the bootloader accordingly. With the console serial port off PE0 and PE1, then the SPI port with SPI.swap(SPI0_SWAP_ALT1) worked as it should.

So, bottom line, it looks to me like all the possible SPI swap positions for the DB64 work correctly.

Also, I i didn't mention it before, but I modified Sd2PinMap.h as Spence suggested to change

elif defined(__AVR_ATmega4809__) // Arduino UNO WiFI Rev2 follows

to

elif (AVR_ARCH == 102 || AVR_ARCH == 103 || __AVR_ARCH__ == 104)

SpenceKonde commented 2 years ago

Wonderful, thank you! I will PR this back to the official library repo.

SpenceKonde commented 2 years ago

Gears are turning on that PR,

SpenceKonde commented 2 years ago

Unless the PR is rejected, there will be no changes made to DxCore and megaTinyCore will get it's copy of SD removed.