Petit FatFS implementation

Go To Last Post
57 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been reading up on Petit FatFS and trying to implement it for a few days now with no success.  Throughout my trials one thing I keep encountering is 'undefined reference' errors.  Today I recreated the issue as follows...

 

  1. Created a new project in Atmel Studio 7
  2. Downloaded Petit FatFS source (pff3a.zip) from elm-chan.org and unzip it into the same folder as my main.c
  3. Add #include's as shown below
  4. call disk_initialize

 

#include <avr/io.h>
#include "diskio.h"
#include "pff.h"

int main(void)
{
    disk_initialize();
    while (1) {}
}

The result is...

Error	ld returned 1 exit status			GccApplication1	collect2.exe	0

Error	recipe for target 'GccApplication1.elf' failed	GccApplication1	D:\AVR-FatFS-Petit-test2\GccApplication1\Debug\Makefile	118

Error	undefined reference to `disk_initialize'	GccApplication1	D:\AVR-FatFS-Petit-test2\GccApplication1\main.c	15

Output is...

------ Build started: Project: GccApplication1, Configuration: Debug AVR ------
Build started.
Project "GccApplication1.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project "D:\AVR-FatFS-Petit-test2\GccApplication1\GccApplication1.cproj" (target "Build" depends on it):
	Task "RunCompilerTask"
		Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
		C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 8 --output-sync
		main.o: In function `main':
D:\AVR-FatFS-Petit-test2\GccApplication1\main.c(15,1): error: undefined reference to `disk_initialize'
collect2.exe(0,0): error: ld returned 1 exit status
		make: *** [GccApplication1.elf] Error 1
		Building target: GccApplication1.elf
		Invoking: AVR/GNU Linker : 5.4.0
		"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -o GccApplication1.elf  main.o pff.o   -Wl,-Map="GccApplication1.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mmcu=attiny85 -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATtiny_DFP\1.3.172\gcc\dev\attiny85"
D:\AVR-FatFS-Petit-test2\GccApplication1\Debug\Makefile(118,1): error: recipe for target 'GccApplication1.elf' failed
		The command exited with code 2.
	Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "GccApplication1.cproj" -- FAILED.
Done building project "GccApplication1.cproj" -- FAILED.

Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

In Atmel Studio, main.c, I can right-click on disk_initialize() and select 'Goto Implementation' where it then correctly shows the two references to the diskio.h and diskio.c files.  Also when I begin typing disk_initialize it comes up as a suggestion.  It's as if the editor see's it but the compiler doesn't.  I have tried this on two computers and with the last 3 versions of Petit FatFS source.  I know there's more to implementing a functional Petit FatFS than this, such as disk access, but it seems this basic test should not throw an undefined reference.  Am I missing something?

 

Much appreciated.

Last Edited: Sat. Apr 6, 2019 - 09:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The root problem is that the compiler cannot find disk_initialize. You will also have to add the pff files to your project. 

 

Do this in the Solution Explorer. Right-click the solution name, then choose "add existing" and select the file, maybe pff.c? But certainly, any .c files from pff3a.zip.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim, it worked, thank you for the help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been trying to implement Petit FatFS on an Atmega 8515 for 3 days now which, from reading other threads, isn't much time in comparison.  I'm pretty confused but have managed to transplant enough of the example code into my test project to get it to compile and run on the hardware, but getting it to run vs. function are two different things.  Here's what I did...

 

  1. Created new project in Atmel Studio.
  2. Added the pfsample dependent files (the .c, .h, and .s file, except for main.c) into my project.
  3. Added two #define lines to usi.S because it wouldn't compile (undefined).  The sample evidently references these from a toolchain file that must be linked into the sample project in some manner that's currently beyond me.  
    #define USICR   _SFR_IO8(0x0D)
    #define USIDR   _SFR_IO8(0x0F)
  4. Now my project which targets the Atmega 8515 compiles and runs on the hardware.

  5. I also edited avr_mmcp.c to use Port B, Pin 4 for CS instead of 3, as show below.
     

    #define CS_LOW()	PORTB &= ~_BV(4)	/* Set CS low */
    #define	CS_HIGH()	PORTB |=  _BV(4)	/* Set CS high */
    #define	IS_CS_LOW	!(PINB & _BV(4))	/* Test if CS is low */
    
  6. Now, to cut to the chase... I'm pretty dang confused.  I've done a lot of reading and looking at examples and am having trouble grasping this.  Currently I'm just trying to initialize the disk and turn on my diagnostic LED if successful.

    //PORTB Pins: 4-CE, 5-MOSI, 6-MISO, 7-SCK
    PORTB = 0b00010000;
    DDRB  = 0b10111111;
      
    if (disk_initialize() == 0)
         ledON();
  7. It does not succeed.

 

My first guess is that it's related to the #define's I added for USICR and USIDR to appease the compiler.  I'll admit that I don't understand their function other than they are some sort of buffer and also that USI might be an implementation in Attiny AVR's and perhaps not Atmega's?  So I think I have an issue right there that I don't know how to fix.  Additionally I'm not sure if I need to define which are my SPI pin or if that's automatically picked based on what AVR my project is targeting.

 

Any guidance is welcome.  Thank you.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the file where you added your defines for USICR make the very first line

#define __SFR_OFFSET 0

and see if anything improves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is was no observable improvement.  Here is what the top of usi.S looks like now.  Are these USICR/DR's referencing PORTB, or acting as an intermediate buffer?  Should this be handled differently with a mega vs tiny?  Thanks.

 

;---------------------------------------------------------------------------;
; USI control functions
;---------------------------------------------------------------------------;
#define __SFR_OFFSET 0
#define USICR   _SFR_IO8(0x0D)
#define USIDR   _SFR_IO8(0x0F)
.nolist
#include <avr/io.h>	// Include device specific definitions.
.list

 

Last Edited: Mon. Apr 8, 2019 - 11:30 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm a bit confused.  The ATmega8515 does not have a Universal Serial Interface (USI) but does have a hardware SPI interface (page 125 of the data sheet).  Probably why the USICR and USIDR registers are not found in <avr/io.h>.  Why don't you just program the SPI's speed to about 1MHz and use its data registers?

 

Alan 

 

BTW. If you are using code from pfsample.zip, do not try to use suart.c and suart.h.  They are configured to use a single pin, bydirectional UART interface with special hardware.  Just set up the hardware uart and use it where xmit() and rcvr() are called.

Last Edited: Mon. Apr 8, 2019 - 01:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are using _SFR_IO8() before the include of the <avr/io.h> that (indirectly) defines it??

 

It does seem very odd that USICR and USIDR are not already being defined for the build. Are you passing the right -mmcu= value ?

 

EDIT: yes, very odd, I see from the build output you showed that it is tiny85. Well the tiny85 header (which in turn uses iotxx5.h) has this:

C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATtiny_DFP\1.3.229\include\avr>grep USI iotnx5.h
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#define USICR   _SFR_IO8(0x0D)
#define USISIE  7
#define USIOIE  6
#define USIWM1  5
#define USIWM0  4
#define USICS1  3
#define USICS0  2
#define USICLK  1
#define USITC   0
#define USISR   _SFR_IO8(0x0E)
#define USISIF  7
#define USIOIF  6
#define USIPF   5
#define USIDC   4
#define USICNT3 3
#define USICNT2 2
#define USICNT1 1
#define USICNT0 0
#define USIDR   _SFR_IO8(0x0F)
#define USIBR   _SFR_IO8(0x10)
#define PRUSI   1
#define __AVR_HAVE_PRR  ((1<<PRADC)|(1<<PRUSI)|(1<<PRTIM0)|(1<<PRTIM1))
#define __AVR_HAVE_PRR_PRUSI
/* USI START */
#define USI_START_vect_num              13
#define USI_START_vect                  _VECTOR(13)
#define SIG_USI_START                   _VECTOR(13)
/* USI Overflow */
#define USI_OVF_vect_num                14
#define USI_OVF_vect                    _VECTOR(14)
#define SIG_USI_OVERFLOW                _VECTOR(14)

So I'd resolve the missing USICR/USIDR thing first - clearly there's something wrong about the way your code is being built if it's not seeing iotn85.h/iotnx5.h

Last Edited: Mon. Apr 8, 2019 - 02:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Should this be handled differently with a mega vs tiny? 

 

Yes, you can't build for tiny 85 when you need this for a Atmega 8515. There will be some porting work if no one has done this before (could be the case since a mega with this small amount of RAM is rare now, even the ancient atmega8 has 1K RAM).

/Lars

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The output from my first post in this thread was from a quick sample to demonstrate my initial 'undefined reference' issue.  It targeted the tiny 85 because that's what Chan's sample did too.

 

allano wrote:

...Why don't you just program the SPI's speed to about 1MHz and use its data registers?

...Just set up the hardware uart and use it where xmit() and rcvr() are called.

 

I believe this sounds like what I need to do, but I am having issues understanding how to do it.

 

Lajon wrote:

...There will be some porting work if no one has done this before (could be the case since a mega with this small amount of RAM is rare now, even the ancient atmega8 has 1K RAM).

 

At one point I found a thread in which clawson mentioned he had done something regarding Petit FatFS porting for use with SPI (maybe not that exactly) and he said to search the forum for it.  I don't think I ever found it unless it's testpf.zip which is one of the things I found and looked at.

 

clawson wrote:

It does seem very odd that USICR and USIDR are not already being defined for the build. Are you passing the right -mmcu= value ?

 

I think that's because of what allano said that the 8515 doesn't have USI.  I also fear that I caused unintended confusion by not clarifying that my first post of compiler output was resolved and it's not relevant to the next round of questions regarding USICR/USIDR.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm still confused. Petit is FatFs for small AVR (ie tiny) I think petit itself assumes USI so you can't use it's hardware support on an ancient relic like 8515. However Petit includes a sample bootloader code and that code has GPIO bitbang for the SPI interface. This could be made to work for 8515 (I use the same driver code in my own SD bootloader in fact)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I'm still confused. Petit is FatFs for small AVR (ie tiny) I think petit itself assumes USI so you can't use it's hardware support on an ancient relic like 8515. However Petit includes a sample bootloader code and that code has GPIO bitbang for the SPI interface. This could be made to work for 8515 (I use the same driver code in my own SD bootloader in fact)

 

Your confusion is likely a result of my poor decision making.  I chose the 8515 because it has all the IO needed for the rest of my project and because it came in a DIP package.  As a hobbyist I do try to research things quite diligently but also admittedly have made some assumptions here, in this case it looks like it bit me.  Obviously I totally underestimated the implementation of reading a file from an SD-Card.  Anyhow, often times I learn by examining example code but in this case Chan's example code has kicked my butt up the street and back again.  I think it's a combination of the multi-layered construct and so many extra features in the example I don't need that are clouding my ability to understand and adapt it.  There's a lot of stuff in it that I'm just not familiar with.  That's usually okay, I can and want to learn, but when they start to pile up it can become overwhelming.

 

The 8515 meets my needs otherwise, so it would be cool to make it work.  Do you perhaps some simpler code I could check out?

 

Much appreciated.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK so I looked at Chan's site. In pfsample.zip there are "avr" and "avr_boot" directories. The bit bang driver is in avr_boot. That's what you want, specifically asmfuncs.S

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Great, I'll dig into that.  Thanks for taking the time to find that out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I implemented the files from the avrboot example which looks much more appropriate to my needs and I can understand it much better.  I also edited the pin definitions in asmfunct.s.  Some things...

 

  1. It wouldn't compile because of many 'undefined reference to APMCSR' in Asmfunc.S.  These seemed to only be in two functions related to writing and erasing (which I don't need to do) so I commented out those lines and now it compiles and runs but it still won't succeed at initialize_disk (returns value of 1).
  2. I'll double check my SPI wiring again for good measure.
  3. Asmfunc.S has a lot of references to r24 & r25, do I need to define those in my project somewhere so the compiler doesn't use it for other things? (example below)

 

;---------------------------------------------------------------------------;
; Transmit a byte
;
; void xmit_spi (BYTE);

.global xmit_spi
.func xmit_spi
xmit_spi:
	ldi	r25, 8
1:	sbrc	r24, 7		; DI = Bit to sent
	sbi	PORT_DI		;
	sbrs	r24, 7		;
	cbi	PORT_DI		; /
	lsl	r24		; Get DO from MMC
	sbic	PIN_DO		;
	inc	r24		; /
	sbi	PORT_CK		; A positive pulse to SCLK
	cbi	PORT_CK		; /
	dec	r25		; Repeat 8 times
	brne	1b		; /
	ret
.endfunc

 

Last Edited: Mon. Apr 8, 2019 - 10:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you reach an impasse using the Atmega5815, you might want to try an Attiny861. It is basically an Attiny85 with 8 more general purpose I/O pins.

 

I just started to interface an Attiny861 with an SD card using petit FatFS and have gotten pfsample files to talk to my PC using slightly modified versions of suart. I'm about to sort out the USI/spi interface and found that I have not defined the direction of its output pins correctly (the MISO/DO pin label was confusing).  You might want to add an LED to the CS line as shown in the picture in the file.

 

Alan

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney wrote:
It wouldn't compile because of many 'undefined reference to APMCSR' in Asmfunc.S. 
That is very odd - I just downloaded the latest pfsample.zip from Chan's site, looked in the avr_boot\ directory at the asmfunc.S file and there is no mention of "APMCSR" anywhere in that file?!? You sure you are looking at the right file?

 

EDIT: The term "SPMCSR" does appear in the file though. It's the SPM control/status register used in the function flash_write:

 

EDIT2: but the tiny85 does have that register:

C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATtiny_DFP\1.3.229\include\avr>grep SPM iotn85.h
#define SPM_PAGESIZE 64

C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATtiny_DFP\1.3.229\include\avr>grep SPM iotnx5.h
#define SPMCSR  _SFR_IO8(0x37)
#define SPMEN   0

 

Last Edited: Tue. Apr 9, 2019 - 09:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

...there is no mention of "APMCSR" anywhere in that file?!? You sure you are looking at the right file? ... The term "SPMCSR" does appear in the file though. ... the tiny85 does have that register

 

Yep, I meant SPMCSR, not sure where I got APMCSR from.  Okay, so this too doesn't mesh with the 8515.  Perhaps I need to go back to the drawing board, bummer.  I am curious however if you could tell me about the r24 and r25 references in asmfunc.S, do I need to make accommodations for those anywhere, or modify since I'm using a different target?  I feel like this is pretty close to working.

Last Edited: Tue. Apr 9, 2019 - 01:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Oh sorry, I keep getting confused so you mean 8515. It's SPM registers are:

 

 

One would need to study the code but I'm guessing that all that's different is the register name. For example I see the code do something like:

 

	; Initiate write operation
	movw	ZL, r22
	ldi	r24, 0b00000101
	sts	_SFR_MEM_ADDR(SPMCSR), r24
	spm

which is using bits 2 and 0. In the datasheet that is Page Write and Store Program Memory enable - which sounds like the right bits still.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You might find the FAQ section of AVR Libc at http://www.nongnu.org/avr-libc//user-manual/FAQ.html , specifically http://www.nongnu.org/avr-libc//user-manual/FAQ.html#faq_reg_usage , very useful for many areas.  R24 is used to pass 8 bit function arguments to assembly code and to return an 8 bit value to the calling function. R25 & R24 are used for 16bit values  The second link has more info about register use.   If you look at Chan's assembly language code, you will see that he uses R24 and R25 a lot without saving their contents.

 

Alan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

One would need to study the code but I'm guessing that all that's different is the register name.

...which is using bits 2 and 0. In the datasheet that is Page Write and Store Program Memory enable - which sounds like the right bits still.

 

Yep, I changed the register name to SPMCR and was unable to uncomment those lines.  And as far as the bits go they do look the same except for one of the functions uses bit 4 which is different on the 8515... but I'm not using these functions anyways so not concerned.  Here's what the lines on the SD Card look like during disk_initialize() attempts as scaled against the example from Chan's How to Use MMC/SDC page.

 

 

"When the card is initialized successfuly, In Idle State bit in the R1 response is cleared (R1 resp changes 0x01 to 0x00). The initialization process can take hundreds of milliseconds (large cards tend to longer), so that this is a consideration to determin the time out value. After the In Idle State bit cleared, the card gets ready to accept the generic read/write commands."

 

It seems that it's never leaving Idle State (bit 0 in the R1 response isn't being cleared).  I've played with the timeout a bit but will continue to investigate further.

Last Edited: Wed. Apr 10, 2019 - 10:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am at the same step in the process of getting pff to work and have received the same response of rc=1 (STA_NOINIT according to pff.h).  I'm a little slower than you to pull out the logic analyzer because I'm trying to understand code flow and what is generating the response.  Needless to say, I'm quite interested in any solution you find. 

 

I started looking for the location where I might increase the wait time between InIdleState and the timeout but my (very preliminary assessment) is that the rc response seems to be caused by not recognizing the type of card so I was going to try a different card.  As a quick test last night, I pulled the SD card from the socket to see if I could get  a rc=2 (STA_NODISK) but did not.  However, I believe my socket can not detect when a card is present.

 

My next step is to pull out my scope and logic sniffer to make sure my SPI signals look reasonable.

 

Good luck.

 

BTW, I'm using a 2GByte card and chose to FAT16 in  the config file.  I exceed the .text memory size of the ATtiny861 if I choose FAT32 and a WRITE capability.  I did try FAT32 (and no WRIRE) but got the same initialization fail response code (rc = 1)

Last Edited: Wed. Apr 10, 2019 - 01:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One possible approach is to do the work on a "big" AVR where you can initially get FatFs rather than Petit working and just use that to verify all the hardware connections/signals. When that is working witch to a bit-bang Petit on the same pins.

 

(I've actually done this the other way round on a mega16/mega32 when developing a Petit/bit-bang based bootloader. The application it would then load was a FatFs using app. Because one used bit-bang but the other used SPI then, because I put the bit-bang on the same pins as the SPI then one would easily take over from the other - this should work "backwards" too).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

One possible approach is to do the work on a "big" AVR where you can initially get FatFs rather than Petit working and just use that to verify all the hardware connections/signals. When that is working witch to a bit-bang Petit on the same pins.

 

(I've actually done this the other way round on a mega16/mega32 when developing a Petit/bit-bang based bootloader. The application it would then load was a FatFs using app. Because one used bit-bang but the other used SPI then, because I put the bit-bang on the same pins as the SPI then one would easily take over from the other - this should work "backwards" too).

 

Now that is an interesting suggestion.  I have a ATmega328 on a development board that would allow me to build a Debug configuration and step through the C code.  Some of the assembly language routines provide USART and SPI services (via USI) that transfer single bytes.  So I should be able to wrap the UART and SPI hardware in the mega328 with functions of the same name.  

 

I'll take a look at the code again to see how isolated the assembly language USART and SPI functions are, how involved the mega328 wrappers might be, if the effort is worth it (which I think would be if I can get the debugger involved) and what other complications may arise from other function interactions. 

 

Quick question:

Will assembly language instructions that don't involve special registers of the tiny861 work in a mega328.   My experience with assembly language is a little dated going was back to the '70s with the Zilog Z80 in a hobby environment and a short stint with the RCA 1802 at work.

 

Thanks, Alan

 

P.S. Life is getting in the way so I'm not sure when I might be able to do the above.  Before that effort, I want to make sure the SPI interface of the tiny861 is active since I have the hardware set up.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

allano wrote:

...I started looking for the location where I might increase the wait time between InIdleState and the timeout but my (very preliminary assessment) is that the rc response seems to be caused by not recognizing the type of card so I was going to try a different card.  As a quick test last night, I pulled the SD card from the socket to see if I could get  a rc=2 (STA_NODISK) but did not.  However, I believe my socket can not detect when a card is present.

 

I tried to extend the timeout in the disk_initialize routine but didn't get any different results.  I also tried two different cards, a 1gb and a 2gb both are formatted FAT but I don't think the format is even a factor yet during the disk_initialize phase, isn't it just hardware at that point?  I believe some card sockets have switches (mechanical I think) that tell if a card is present and/or write protected but it's up to the user to decide whether or not to read those switches and integrate it into their code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney,

I just re-read Chan's article about How to Use MMC/SD to learn what SPI mode to use and noticed his comment that the SD Card's DO line must have a pull up resistor attached or "some cards will fail initialization process".  I know that one fault of my SD socket module is that it does not relinquish control of the MISO line when the CS goes high.   I have not had time to check this condition on my hardware but thought you might want to try it.  I read somewhere that a 10K resistor should work - the output is open collector drain

Edit: its CMOSfrown

 

Last Edited: Thu. Apr 11, 2019 - 11:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In "real" FatFs you have a 10ms timer interrupt that calls disk_timerproc() and in that the code checks the status of the card present and write protect switches. Can't remember how Petit differs in this area. Obviously if you use a socket that does not have the additional switches you arrange to always give the results "present" and "write enabled"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Petit FF has a similar delay in avr_mmcp.c

	for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) dly_100us();	/* Wait for leaving idle state */
	if (!tmr || send_cmd(CMD16, 512) != 0) {	/* Set R/W block length to 512 */
		ty = 0;
	}

ty is the card-type variable which is used to indicate success or failure in many steps of initialize.  At the end of the function, it is tested for non-zero and then returned

	CardType = ty;
	CS_HIGH();
	rcv_spi();

	return ty ? 0 : STA_NOINIT;

 

 

Last Edited: Thu. Apr 11, 2019 - 12:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm guessing one of the things they cut out to reduce the Petit footprint was the additional code to support the (optional) card present/write protect detection.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

allano wrote:

Rooney,

I just re-read Chan's article about How to Use MMC/SD to learn what SPI mode to use and noticed his comment that the SD Card's DO line must have a pull up resistor attached or "some cards will fail initialization process".

 

Oh yeah, I read that page several times too and recall seeing that but I guess I forgot it just as quickly, thanks for bringing it up.  I should have a full size SD socket arriving tomorrow, I've been using a super cheap Micro SD socket so I figured I should expand my options given the lack of success.  This weekend maybe I can try the new socket and the pullup resistor, it sounds promising.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I checked the DO output of my SD socket module with a card in it by plugging its CS line into 3.3 volts and gnd.  It stayed high for both states. 

 

I put a scope on the SPI SCK line and do not see any activity during initialization.  I have re-checked port and pin assignments and directions a couple of times but I may be making a same mistake over and over.   So I'm going to isolate the xmit_spi() and rec_spi() functions in a new project, connect its ins and outs to a 74HC595 shift register, read more about what I might not be setting in the USI registers, put the functions in a loop and see what is going on.     

Last Edited: Fri. Apr 12, 2019 - 02:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So you're not getting any output on the SPI Clock?  I know it's basic but have you made sure it's configured as an output?  I tried a 10k pullup on the card socket's MISO (DO) with no change in result.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Rooney wrote:

So you're not getting any output on the SPI Clock?  I know it's basic but have you made sure it's configured as an output?  I tried a 10k pullup on the card socket's MISO (DO) with no change in result.

 

 

Correct, no SPI clock output.  I would appreciate any suggestion you may have since I've been struggling with this for a couple of days.  All the code that I show is from the pfsample.zip file of the current pff3a (R0.02a) version.

 

In main(), Chan initializes the ports of the ATtiny85 with lines 125 and 126 in the order shown (I added comments to help sort out what is happening.)  As you can see, I'm not sure about the DI and DO designations (will include the connection diagram later).

Note that the label "MISO/DO" is the label placed on PB1 in the Pin Configuration diagram for the tiny861 (pg 2).  And BTW, ISP programming works so MISO must be correct - just don't know yet if DO is.

When I did not see any SPI output, I added my own port direction and initial state operations.  If you can see anything wrong, please make a comment.

 

The connection diagram is:

I assigned the same pins used on the tiny85 to the tiny861 in any attempt to minimize problems.  My connections seem to make sense since DO from the tiny861's USI out goes to the MOSI label on my card module (I hope DI in the diagram) and DI of the tiny861's USI accepts data from MISO label (I hope DO in the diagram) on the card module.  Trying to reverse the two data pins at this time did not make sense since I don't see any activity on the clock line.

 

One problem I have is that ports and pins sometimes get implicitly assigned in many files.  For example, in line 67 of xmit_spi(), the SPI clock is assigned to PB2.  There is no one place where the ports and pins are defined and then used throughout all files.

So maybe the ports are getting re-assigned in some other file.  BTW, the LSS file shows everything is correct as far as register addresses and pin values.  Hence the idea of isolating the USI.S file and setting up and testing port and pins in only one place.

 

I do have one question of you.  Are you using the code for USI.S file that you showed earlier - the one that has a bunch of port/pin #defines in the beginning and the flash_errase() function in it?  The assembly language code for xmit_spi()  is different than in one in USI.S of the pfsample.zip file.  I ask because it may be a "Plan B" but first,  I would really like to find what what I am doing wrong the code I using now.

 

Tnks, Alan

 

Edits: many for grammar

 

Last Edited: Fri. Apr 12, 2019 - 01:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No clock on SPI is usually the classic SS thing (or is this AVR not afflicted by that? )

Last Edited: Fri. Apr 12, 2019 - 01:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
No clock on SPI is usually the classic SS thing (or is this AVR not afflicted by that? )

 

In this case, the SPI interface is created by software and no Slave Select option is available (with USI).

 

Thanks anyway for the suggestion.

 

Edit: stuff in parenthesis

Last Edited: Fri. Apr 12, 2019 - 10:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I struggled for years to interface a storage unit to a microcontroller.  I downloaded the code used by most developers here; ELM I believe.

But the triple combination of no comprehensive documentation on the ELM library, no systematic overview tutorial/documentation of the data/disk/SD/FAT storage process, and incomprehensible C compiler errors left me at total loss for the longest time.

 

I solved this by using the Arduino standardized UNO board coupled with a TFT shield that had an SD adapter mounted.  I bought a cheap 4Gig SD card and PC adapter.   I formatted the SD card on the PC and added the Adafruit Parrot demo BMP file.   Then I downloaded the simple examples for the SD library that is included with the Arduino IDE.   They compiled and ran successfully.   I was able to get the Adafruit parrot displayed on my TFT screen, by compiling the demo exactly as it was and by using same hardware as the demo (abet from a clone manufacturer).

 

Then I downloaded all the examples of SD card access that I could find on the web and studied/reviewed them.  I modified the simple demos and monitored the results.   I did do a brief review of all the code comprising the classes that went into the SD library.  But since << the code just worked >> I didn't spend a lot of time on it.  I spent the time instead developing the application.

 

I'm comfortable with my SD interfacing programming skills even though they are limited to the Arduino platform.  But since the Arduino is the cheapest, most well-documented, and most standardized AVR platform in the world,  I  <<don't care anymore>> that I can't understand all the messages above.  I can make cheap robust working programs that use SD cards, which is the kind that customers prefer to pay for.

 

  Obsession with obsolete microprocessor technical details is a 20th-century mental disorder.  What difference does it make if you can fit an SD interface into 8K of SRAM when the CPU with 80K of SRAM is selling for about the same price?

Last Edited: Fri. Apr 12, 2019 - 03:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

"no comprehensive documentation"? For FatFs? Don't make me laugh. It is truly exemplary in showing how software should be documented. Not only is the API itself rigorously documented but Chan includes all kinds of design documentation, implementation notes and even performance benchmarks. Of course it does take a modicum of intelligence to understand it all and sadly some folks lack the ability to understand even the most basic. For them there is always knitting as a hobby.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Simonetta wrote:

Obsession with obsolete microprocessor technical details is a 20th-century mental disorder.

 

I am afflicted!  And also in the 21st century.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
I struggled for years to interface a storage unit to a microcontroller... ...But the triple combination of no comprehensive documentation on the ELM library, no systematic overview tutorial/documentation of the data/disk/SD/FAT storage process, and incomprehensible C compiler errors left me at total loss for the longest time.

clawson wrote:
"no comprehensive documentation"? For FatFs? Don't make me laugh. It is truly exemplary in showing how software should be documented. Not only is the API itself rigorously documented but Chan includes all kinds of design documentation, implementation notes and even performance benchmarks.

 

It's important to realize you both have valid points because you are looking at it from very different angles. 

 

To hobbyists (I include myself) who don't yet have the underlying knowledge and foundation to easily make it work it can easily be judged as problematic.  This is because a hobbyist's knowledge is often limited to that which they've had a reason to tackle.  In my case I have never coded for SPI devices before and didn't know what a UART or USI was so I had a lot going against me.  What I'm getting at is that Chan's documentation may be exemplary to users with a certain level of existing knowledge but a real challenge for others.  That's just fine though because Chan's giving it away for free and has no obligation to anyone and it's his choice how much he wants to 'dumb down' docs and demos depending on his desired target audience.

 

One the flip side to the more experienced users I'm sure it's a cakewalk.  The examples probably make perfect sense because you already fully understand all the concepts and details because you've "been there, done that" 5, 10, 15 years ago.

 

And then there is everyone in between.  That's the beauty of forums where people from all walks can work together to tackle a common issue or receive assistance.  Initially I found clawson to be very abrasive but I now realize that he just doesn't want to hand out answers and do other people's work.  He's probably also already answered most questions many times over so maybe he feels like the data is out there and people aren't trying to find it.  That might be true -or- it might be that a person has researched it and read the clues scattered among years of forum posts, datasheets, and samples but it's not "snapping together" for them yet.  If someone posts questions without details or they don't appear to have put forth any effort they will get the "read the datasheet" answer.  On the other hand if effort seems to have been applied, details explained, willingness to learn, etc. then that's when help seems to arrive.  That makes sense to me.

 

Simonetta wrote:
...I'm comfortable with my SD interfacing programming skills even though they are limited to the Arduino platform.  But since the Arduino is the cheapest, most well-documented, and most standardized AVR platform in the world,  I  <<don't care anymore>> that I can't understand all the messages above.  I can make cheap robust working programs that use SD cards, which is the kind that customers prefer to pay for.

 

That's cool as long as the Arduino fits your needs but it's important to consider that it may not fit the requirements of many users.  I still use Arduino's for testing theories and temporary projects but I have found that they wouldn't work for some of my projects due to initialization time, physical size, etc.  Maybe there's ways around that but once I started using bare AVR's I found that I really liked the ability to design the whole project anyway I wanted, down to custom PCB's if needed.  For me though it's mostly a hobby so I can have the luxury of going down a rabbit hole.  On the other hand if it's your job to knock out a working device then I understand that time is money and it may make sense to use an Arduino to get the job done if other methods aren't working for you.  It's all good!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Got the SPI interface to work last night in an isolated project. Wish I could tell you why it now works because I did not run an "as-is" test before moving the pin direction and state-setting statements into the init_spi() function.  Was surprised that the SCLK is running at 5MHz 4 MHz with a 8MHz CPU clock.  I use a MOSFET level shifter (from Sparkfun) and 6 inch leads to and from the shifter - not acceptable at 5 4MHz (lots of ringing at the card's socket module).  So before further tests, I plan to build a small adaptor for diodes between 5 volt microcontroller (want to eventually run at 20MHz) and 10k pull-up resistors to 3.3v on the card's socket module.

 

In addition to the xmit_spi() and rcv_spi() functions, I copied avr-mmcp.c with the initialization() function so that I can use the debugger on initialization().  The Debug configuration Hex file size is only 17% of the controller's flash size so I look forward to a more direct method of finding out what is wrong.

 

Edit: correct SPI clock speed.

Last Edited: Sun. Apr 14, 2019 - 02:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's great!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I REALLY doubt that you have a 5MHz SPI clock in an 8MHz MCU, especially with a Tiny85. That is because the SPI clock is an integer division from the MCU clock. So, maybe 8MHz/2 = 4.0MHz. or 8MHz/3 = 2.666... MHz or 8MHz/4 = 2.0MHz or such. But not 5MHz.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Sat. Apr 13, 2019 - 08:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim,

You are absolutely correct.  I was surprised when I saw so many cycles on the scope and was not careful measuring one cycle because I was more interested in other signals.  I was about to correct my error when I saw your post and will do it now.

 

Alan

Last Edited: Sun. Apr 14, 2019 - 02:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think that F_MCU/2 is the absolute maximum SPI clock rate for a master AVR Mega/Tiny. I typically run half that to be safe. I use an older version of FatFs on a Mega328P.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

ka7ehk wrote:

I think that F_MCU/2 is the absolute maximum SPI clock rate for a master AVR Mega/Tiny. I typically run half that to be safe. I use an older version of FatFs on a Mega328P.

 

Jim

You have answered a question I had about how fast I should clock the SPI interface.  Running at 4MHz is not first my first choice for tests but is the speed that results from the instructions in xmit_spi in post 33. 

 

For tests, I've been thinking more around 400KHz although that speed might affect some of the 'n'-counter-delay-loops as in send_cmd():

i.e. it works at 400KHz but not at higher speeds.

 

However, with 'n' outside the do loop, the debugger should be able to tell me what caused the exit: n or res

 

Alan

 

 

Last Edited: Sun. Apr 14, 2019 - 02:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

Rooney,

I have a couple of questions about the code you are using.

1) Are you using the usi.S file beginning with:

I ask because I found the comments in xmit_spi() confusing (although you might not have because (I believe) you do not use the Universal Serial Interface hardware).

In the code:

at line 82, Chan refers to DI as the "bit to send".  That terminology is 'correct' if your reference for DI is at the SD Card side of the interface.  You'll notice that on line 84, he sets the DI pin high if in the previous instruction, sbrc, pin 7 of R24 is clear.  sbrc paraphrased is: skip the next instruction if the bit 7 in R24 is clear (logic 0). So if you have a 1 in the msb (bit 7) of the byte to be sent (R24), flow will continue to the next instruction and set (sbi -> set bit in IO register) DI to a 1 for output.

 

So my next question is:

2) Do you have the connection from "DI" (Pin PB2 of PORTB as assigned above or whatever pin and port you have assigned to PORT_DI) connected to the input (MOSI) of your SD Card module?

 

I suspect you probably have swapped the two SPI data pins by now but wanted to ask anyway.

 

Alan

 

BTW, Since I believe you said that you were learning assembly language, you might be interested in a expansion of assembly language comments as I tried to resolve my confusion (pls take it as guidance and not absolute truth)   And BTW, my assignments of DO and DI are from the viewpoint of the micro-controller.

 

You can find a list of these instructions at https://www.microchip.com/webdoc/avrassembler/avrassembler.wb_instruction_list.html

 

Getting late so I hope I have not messed anything up.

 

Edit: found error in first picture, replaced it with correct version

Last Edited: Wed. Apr 17, 2019 - 12:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

allano, thank you for this information.  Unfortunately I don't have my project or laptop with me this weekend so I can't reference it.  What I can say is that at this point I'm only use code from pfsample/avr_boot for which the only asm file is asmfunc.S.  It does however to be very similar to the code you posted.

 

I have the AVR's MOSI pin connected to SD-Card module's MOSI pin, same for MISO.  I had researched this awhile back because I was wondering if they needed to be crossed (like a null modem cable).  Did I get this wrong?

 

Additionally yesterday I stumbled across a document on Microchip's site regarding using Petit FatFS with Tiny and Mega AVR's.  I had not seen it before and haven't yet looked at it closely.  Here is a link in case you haven't seen it.

 

http://ww1.microchip.com/downloa...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney wrote:

allano, thank you for this information.  Unfortunately I don't have my project or laptop with me this weekend so I can't reference it.  What I can say is that at this point I'm only use code from pfsample/avr_boot for which the only asm file is asmfunc.S.  It does however to be very similar to the code you posted.

 

I have the AVR's MOSI pin connected to SD-Card module's MOSI pin, same for MISO.  I had researched this awhile back because I was wondering if they needed to be crossed (like a null modem cable).  Did I get this wrong?  snip

 

Thanks for the reference to asmfunc.S.  Its code is the same as the code I had in mind. The reference to the Microchip article is a (nice) summary of multiple pages in Chan's website (i.e the Application Programmer's Interface and related info) combined with Microchip's assessment of what controllers might be used.

 

As far correct connections, it depends how you assigned the DI and DO pins in the #defines at the top of asmfunc.S.  I suspect you have correctly assigned DI define to the number 5 (PB5, MOSI), the DO define to 6 (PB6,  MISO) and the clock to 7 (PB7, SCK)  in your ATMega8515 or you would not have seen anything when using your logic analyzer.

 

I hope to get the Dragon and Dragon Lair set up today or tomorrow.  I need to change SPI pin assignments since at the present time, SPI signals might be affected by any load placed on the MOSI, MISO, and CLK pins while the debugger is attached. (If you remember, my SD Module does not tri-state the MISO pin when not selected.)  I realize the debugger uses only the reset pin, target power and ground but I really don't want to take a chance and am getting tired if pulling the programming cable after each change in code.

 

Hope you have a good day,

Alan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney wrote:

 

I have the AVR's MOSI pin connected to SD-Card module's MOSI pin, same for MISO.  I had researched this awhile back because I was wondering if they needed to be crossed (like a null modem cable).  Did I get this wrong?

 

Missed that paragraph on the first way through.  No, you got it right.  Unlike a UART, rhe SPI pin marking don't depend on which end you are sittingr: MOSI on the master goes to MOSI at the slave, etc.

 

Whoever created the silk screen for my RS232 UART module put an arrow showing flow direction next to Tx and Rx pins.  Glad they did because I expected the module to be a "Data Set" but the Tx/Rx markings on the module are as though they are at the Data Terminal end

 

Alan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney,

 

Got it working today in both the isolated project and the pfsample project.  Only slightly modified the usi.S file for clarity (now renamed susi.S because it is the software version that emulates USI hardware).  I attached the file "susi.S.zip"; it is not a zip file so just strip ".zip" from the extension and place it in your pfsample project.  All the function names inside the file are the same as the usi.S you are now using (and BTW, delete the usi.S file). You will have to modify the #defines at the beginning of that file to match your pin assignments but other than that, it should compile and work successfully.  In the attached software, the pin assigned to DO should connect to the MOSI pin on the SD module, DI connect to the MISO pin, CLK to CLK pin and CS to CS pin.

 

I believe my problem was in hardware.  As mentioned in the "SD Card 5v to 3.3v level shifting" thread, I found a problem with signal ringing and build a level shifter daughter board, to mount the Sparkfun level shifter, for the LCSoft SD Socket module.  I tested this combination with an interface tester (Bus Pirate) and confirmed that the SD Card could be initiated and that it replied successfully (read the boot record on the SD Card) to the Bus Pirate. So I now knew that the hardware worked.

 

I then took the software you are using in asmfunc.S, sightly modified xmit_spi() for clarily and confirmed that signals were present on their respective output pins and in correct order using a dual trace scope.  Last step was to connect the controller to the SD Card socket module.

 

Before connecting the Dragon, I tried the 'new' software with the hardware and received an rc=0 reply.  Taken back a bit, I copied (just) susi.S to the pfsample project, compiled and ran the project.  Disk Initialization and Mount Volume returned successfully as show below:

 

PFF test monitor
>?
 fi - Mount volume
 fo <file> - Open file
 fd - Dump 128 bytes of file data
 ft - Stream the file to console
 fe <ofs> - Move r/w ptr
 fw <len> <val> - Write data to file
 fp - Write console input to file
 fl [<path>] - Read directory
>di
rc=0
>fi
rc=0 FR_OK
>

I hope that you have success with that file also.

Alan

 

Added later: If operating correctly, the SD module and card should draw about 15ma more than the rest of your hardware.

Attachment(s): 

Last Edited: Sat. Apr 20, 2019 - 01:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That worked, sort of.  It didn't work at first but then I found disconnecting the AVR Dragon from SPI and power cycling (resetting doesn't work) the circuit allows the card to initialize and open a file... so maybe that was the issue all along, or maybe not.  Regardless, now it reads data but I think I'm getting unreliable results.  I will have to set up a better way to indicate results for debugging (and disconnecting SPI is a real nuisance!).  I'm certainly happy to see some progress though.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess I just need to ditch the 8515 and get something with debugging features.  The 162 appears to be pin compatible with 8515 and has JTAG so that might be something to try or I might just go back to the drawing board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney wrote:

That worked, sort of.  It didn't work at first but then I found disconnecting the AVR Dragon from SPI and power cycling (resetting doesn't work) the circuit allows the card to initialize and open a file... so maybe that was the issue all along, or maybe not.  Regardless, now it reads data but I think I'm getting unreliable results.  I will have to set up a better way to indicate results for debugging (and disconnecting SPI is a real nuisance!).  I'm certainly happy to see some progress though.

 

I'm glad you now can use the pfsample program.  It is rather nice to gain some experience with PetitFF.  I use an USBASP as a programmer and have never been able to leave it connected when I use the same pins for other SPI devices. I have not read the Atmel AVR042 application note (attached) thoroughly but it may show one possible solution.

 

Since you are using a software implementation of SPI, why not just move all the SPI outputs from PORTB to PORTA.  Then you should be able to leave the SPI leads connected while programming and the Dragon connected when running.  I did that with the ATtiny861's USI hardware and its alternate port (USIPP) capability.  All you have to do is change the #defines at the beginning of susi.S and move your wires over to PA0 through PA3.

; port and pin setup
#define DDR_CS		_SFR_IO_ADDR(DDRA), PA3		// Set CS pin Direction
#define	PORT_CS		_SFR_IO_ADDR(PORTA), PA3	// Set CS pin State
#define DDR_CK		_SFR_IO_ADDR(DDRA), PA2		// Set CLK pin Direction
#define	PORT_CK		_SFR_IO_ADDR(PORTA), PA2	// Set CLK pin State
#define DDR_DO		_SFR_IO_ADDR(DDRA), PA1		// Set DO pin Direction
#define	PORT_DO		_SFR_IO_ADDR(PORTA), PA1	// Set DO pin State
#define DDR_DI		_SFR_IO_ADDR(DDRA), PA0		// Set DI pin Direction
#define	PORT_DI		_SFR_IO_ADDR(PORTA), PA0	// Set DI pin State
#define	PORT_DI		_SFR_IO_ADDR(PORTA), PA0	// Apply pull-up resistors
#define PIN_DI		_SFR_IO_ADDR(PINA), PA0		// get DI input state

Have to move to another computer to attach the file.

Alan

Attachment(s): 

Last Edited: Mon. Apr 22, 2019 - 12:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rooney wrote:
I found disconnecting the AVR Dragon from SPI

When you have SPI devices, you need to use a weak pull-down/pull-up to keep it de-selected during other activity on the SPI bus.  I've lost track but this includes ISP activity when the AVR is in reset.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

allano wrote:
Since you are using a software implementation of SPI, why not just move all the SPI outputs from PORTB to PORTA.  Then you should be able to leave the SPI leads connected while programming and the Dragon connected when running.

 

All my IO lines are serving other purposes but for reasons of troubleshooting the SD-Card I could remove those connections to do as you suggest.

 

theusch wrote:
When you have SPI devices, you need to use a weak pull-down/pull-up to keep it de-selected during other activity on the SPI bus.  I've lost track but this includes ISP activity when the AVR is in reset.

 

Okay, so I have 1k resistors on the SD-Card adapter's MOSI, MISO, and CLK lines as per this thread which corrected my issue of SPI not working after adding the card reader.  I also at one point had a 10k pullup on the card adapter's MISO line as per this post in this thread.  I'll investigate what you mentioned, thank you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you get the drift?-- the select line; not clock or data in or data out...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I understand, thank you for making sure.