ilmenator Posted November 9, 2006 Report Share Posted November 9, 2006 Hi all,I have an application which uses an external SRAM card as memory extension. It is based on the schematic from TL - see this post: http://www.midibox.org/forum/index.php?topic=4140.msg27685#msg27685. For the CARD PRESENT status of the card (= is it connected to the core or is the card disconnected) I am currently using one DIN pin. The detection mechanism is very simple: there is one pin on the card connector that is connected to ground by the card whenever it is inserted, and which is connected to +5V via a pullup resistor whenever no card is inserted. This works well and gives me the correct status whenever the status changes, that means whenever I connect or disconnect the memory card. BUT the problem is that I am not interested in the change of the status, but in the status itself: upon powering up the core, I have no means of detecting whether the card is connected or not, because the DIN mechanism is checking for transitions.Now, I am trying to use pin A7 of J5 (that is RE2 of the core 18F452) in the same manner: I have a pullup of 100k against +5V, and whenever the card is inserted, the pin is drawn to ground. To my knowledge, the C code necessary to initialize the input of Port E is very simple:///////////////////////////////////////////////////////////////////////////// // This function is called after startup to initialize the SRAM ///////////////////////////////////////////////////////////////////////////// void SRAM_Init(void) __wparam { // disable the ADC which allocates the analog pins // only needed if controls pins are connected to port A ADCON1 = 0x07; ... // configure RE2 as input for reading SRAM card status // Pin RE.2 = input TRISEbits.TRISE2 = 1; return; } Then I only have to check the status of that pin regularly, e.g. in [tt]Tick(void)[/tt], using something like: app_flags_t.SRAM_CARD_STATUS = PORTEbits.RE2; which could be defined the same way as the DISPLAY_UPDATE_REQ flag in the sdcc_skeleton demo code.So why did I put this into "Troubleshooting" and not "Programming in C"? Well, it does not work this way, and I tried to meter the potential of the RE2 pin using a multimeter. In fact, that pin is always at ground level, no matter if the card is connecting the pin to ground or not! So... is the pullup resistor too large (100 kOhm)? I also measured the resistance accross the resistor (with the circuit powered off, of course). It reads about only 20 kOhm when the "circuit" is connected to pin RE2. If I disonnect it from there (pulling the J5 plug), then the resistor value reads 100 kOhm as it should be. If I connect the card, then the resistance across the pullup drops further down to about 2 kOhm. J5 disconnected and card inserted gives me 28 kOhm across the 100 kOhm pullup. I am sure there is no short circuit, that is why I really don't get any further here. Any suggestions? Do I need to do something more to the core / the PORTE input? Do I need to change the pullup's resistor value to get to a decent potential at pin RE2? ??? ??? ???Best regards, ilmenatorSRAM_card_workbench.JPG Quote Link to comment Share on other sites More sharing options...
stryd_one Posted November 9, 2006 Report Share Posted November 9, 2006 Hey illyYou probably should make sure the port/latch are clear before setting the input, but I don't think it's a big deal...Now I'm having a bit of trouble visualising the circuitry so I might have missed something here, but:(pulling the J5 plug), <SNIP> If I connect the card, then the resistance across the pullup drops further down to about 2 kOhm. J5 disconnected and card inserted gives me 28 kOhm across the 100 kOhm pullup. Is it 2 or 28kOhm? I could really go a rough circuit diagram... or maybe some Z's, it is 0130 after all :-\ Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 9, 2006 Author Report Share Posted November 9, 2006 Hi stryd,it is 2k when J5 is connected to the core and the SRAM card is inserted. It is 28k when J5 is not connected and the card inserted. I was thinking of maybe I have a "ground loop" problem or something like that, as I am using both the J5 and the J15 connectors from the core, both carrying +5V and ground. BUT in fact J15 only delivers to the LCD connected also to J15. Both 74HCT573 are supplied via J5. So I would suppose that if I disconnect J5 completely, then the +5V pin of that IC (pin 20) should have a potential of 0V, that means ground level - but indeed I measure 3.6V without the SRAM card inserted, possibly coming from where??? If I insert the SRAM card, that voltage drops to 3.0V, which is the backup battery voltage - if I remove the battery, strangely enough I still measure 1.35V.It's a real mess, and it's hard to come up with a drawing of the circuit, because I wonder how much of that battery backup circuit of the SRAM card is relevant here - and how that might look like. :-\Yet, I was wondering why it works flawlessly using a DIN input pin then?? I will try to dig deeper (and hopefully to make more sense to all of you readers out there ;D).Thanks, ilmenator Quote Link to comment Share on other sites More sharing options...
TK. Posted November 12, 2006 Report Share Posted November 12, 2006 Hi Ilmenator,are you sure, that TRISE isn't change back to another value somewhere else, e.g. within your SRAM driver? Because for me it sounds like the output driver of the pin is enabled (TRISE flag set to 0)You could use MIOS Studio to read out the SFR value, just open the debug window and start a read transaction from address 0xf96Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 12, 2006 Author Report Share Posted November 12, 2006 Hi Thorsten,I am almost sure that it is set as an input pin, because TRISE is only touched once in the SRAM_Init routine and then left alone. // put PortE in output mode // Pin RE.0 = output TRISEbits.TRISE0 = 0; // Pin RE.1 = output TRISEbits.TRISE1 = 0; // configure RE2 as input for reading SRAM card status // Pin RE.2 = input TRISEbits.TRISE2 = 1; Yet, when I read from address 0xf96 as you suggested, MIOS Studio reads 0F96: 01 Done which should mean that RE.0 is configured as input and RE.1 and RE.2 as outputs, if I read the PIC18FXX2 documentation correctly (DS39564C-page 97). Now, if in the SRAM_Init routine I write this: // put PortE in output mode // Pin RE.0 = output TRISEbits.TRISE0 = 0; // Pin RE.1 = output TRISEbits.TRISE1 = 1; // configure RE2 as input for reading SRAM card status // Pin RE.2 = input TRISEbits.TRISE2 = 0; then I can actually measure the toggle of the potential on input pin RE.2 when connecting/disconnecting the card. If I use MIOS Studio to read from address 0xf96, I get 0F96: 05 DoneIf I manually write 0x04 into 0xf96 using MIOS Studio, the potential on Pin RE.2 also toggles between ground and +4.61 V or so.All that basically means success and your assumption is right. But then I wonder whether maybe the pin enumeration within MIOS got scrambled or something like that? Also I still cannot read the status of RE2 correctly, which might also be related to some pin scrambling in the wrapper or so?I would be glad if you could check this, or tell me how I could possibly check my suspicion?Best regards, ilmenator Quote Link to comment Share on other sites More sharing options...
TK. Posted November 12, 2006 Report Share Posted November 12, 2006 Hi Ilmenator,it seems that the register definition in pic18f452.h is not correct:extern __sfr __at 0xf96 TRISE;typedef union { struct { unsigned :1; unsigned TRISE0:1; unsigned TRISE1:1; unsigned TRISE2:1; unsigned :1; unsigned IBOV:1; unsigned OBF:1; unsigned IBF:1; };} __TRISEbits_t;[/code] I would expect: [code]extern __sfr __at 0xf96 TRISE;typedef union { struct { unsigned TRISE0:1; unsigned TRISE1:1; unsigned TRISE2:1; unsigned :1; unsigned PSPMODE:1; unsigned IBOV:1; unsigned OBF:1; unsigned IBF:1; };} __TRISEbits_t;Could you please check, if it works with this change?This header file is not part of MIOS, but has been copied from an SDCC include directory. Maybe there is a newer version in the meantime.Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 12, 2006 Author Report Share Posted November 12, 2006 Yes, the corrected version does its job as it's supposed to. :D So what I have now is the correct potential on the input pin RE2 of the PIC. Still I cannot read the status with my code. Here is what I do:///////////////////////////////////////////////////////////////////////////// // This function is called after startup to initialize the SRAM ///////////////////////////////////////////////////////////////////////////// void SRAM_Init(void) __wparam { // clear PortE PORTE = 0x00; // disable the ADC which allocates the analog pins // only needed if controls pins are connected to port A ADCON1 = 0x07; ... // put PortE in output mode // Pin RE.0 = output TRISEbits.TRISE0 = 0; // Pin RE.1 = output TRISEbits.TRISE1 = 0; // configure RE2 as input for reading SRAM card status // Pin RE.2 = input TRISEbits.TRISE2 = 1; return; } Then in main.h I modified the Global Types section like this: ///////////////////////////////////////////////////////////////////////////// // Global Types ///////////////////////////////////////////////////////////////////////////// // status of application typedef union { struct { unsigned ALL:8; }; struct { unsigned DISPLAY_UPDATE_REQ:1; // requests a display update unsigned SRAM_CARD_STATUS:1; // if set, SRAM card is present }; } app_flags_t; In main.c I used the Tick() function to check the status and request a display update - I know that the display update should not be requested from here, but it's a quick and dirty solution. ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS in the mainloop when nothing else is to do ///////////////////////////////////////////////////////////////////////////// void Tick(void) __wparam { app_flags.SRAM_CARD_STATUS = PORTEbits.RE2; app_flags.DISPLAY_UPDATE_REQ = 1; } Finally, in DISPLAY_Tick() I print the status on the LCD like this: ///////////////////////////////////////////////////////////////////////////// // This function is called in the mainloop when no temporary message is shown // on screen. Print the realtime messages here ///////////////////////////////////////////////////////////////////////////// void DISPLAY_Tick(void) __wparam { if( !app_flags.DISPLAY_UPDATE_REQ ) return; // clear request app_flags.DISPLAY_UPDATE_REQ = 0; if( app_flags.SRAM_CARD_STATUS ){ MIOS_LCD_CursorSet(0x60); MIOS_LCD_PrintCString("Card OK"); } else{ MIOS_LCD_CursorSet(0x60); MIOS_LCD_PrintCString("No Card"); } }I think that this code should work - any thoughts on this?Thanks very much, ilmenator Quote Link to comment Share on other sites More sharing options...
TK. Posted November 12, 2006 Report Share Posted November 12, 2006 I'm not 100% sure, but I remember that I had some issues with bit copies like this one:app_flags.SRAM_CARD_STATUS = PORTEbits.RE2;what happens, when you display the PORTE value directly on screen? E.g., within the DISPLAY_Tick() functionBest Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 13, 2006 Author Report Share Posted November 13, 2006 Hi Thorsten,I replaced app_flags.SRAM_CARD_STATUS = PORTEbits.RE2; with if( PORTEbits.RE2 ){ app_flags.SRAM_CARD_STATUS = 1; }else{ app_flags.SRAM_CARD_STATUS = 0; } ,now everything works as expected. ;DI left a comment in the C programming section of the Wiki: http://www.midibox.org/dokuwiki/doku.php?id=c_tips_and_tricks_for_pic_programming#sdcc_bugs_workaroundsAs always Thorsten: thanks for that hint!Best regards, ilmenator Quote Link to comment Share on other sites More sharing options...
stryd_one Posted November 14, 2006 Report Share Posted November 14, 2006 Success! So are you going to let us in on your secret project then? ;) Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 14, 2006 Author Report Share Posted November 14, 2006 I have some more mysteries to solve before going public with this baby...One is best formulated in a question: what happens if I "hijack" the address and data bus of a device that is supposed to be the master of these buses with only one "receiver" attached? Do I need to separate the original master from the buses whenever the "hijacker" tries to access it? More specifically: will a second "bus master device" (i.e. a PIC using address and data bus for communication with SRAM memory) present any harm to the first one? I have a feeling that I do not want to try this out...So I have looked into the 74HCT646 bus transceiver to act as a bus separator. I know that there are special bus switch devices like e.g. Fairchild or IDT 3245 bus switches, but I have not found a way of purchasing them in lower quantities here in Germany. Has anybody used the 74HCT646 before?Best regards, ilmenator Quote Link to comment Share on other sites More sharing options...
stryd_one Posted November 15, 2006 Report Share Posted November 15, 2006 Mate if you can get that to work you're doing better than me... but that's not hard hahahaha! Seriously though, if I can do ANYTHING to help, if you need parts or funding or anything let me know! I was trying to get that going for the vX, so I could have one core for the CS, which would read/write to the database in SRAM, and another core which would read/write from the SRAM and act as the sequencer core (brains). Obviously you need a connection between the cores to ensure exclusivity when read/write operations on the buss are required, and it needs to be pretty fast so MB-Link didn't seem the right method. I was thinking about using a free pin on each core to negotiate the master core.Because the two cores would be connected to each other by their LCD busses I wasn't sure of the right way to make sure that they didn't interfere with each other, so maybe the 646 is the right way to go... Of course because my app is a sequencer I'm also concerned about having to drive too many pins and slowing things down... Not sure how that's going to effect you though, but I thought it worth mentioning.Hopefully some hardware guru will chime in any minute ;) Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 15, 2006 Author Report Share Posted November 15, 2006 Stryd,thanks for offering help - I will surely get back to you one of these days. My application is not time critical, so I think I could establish a protocol that insures that only one device accesses the bus at a time. In the original machine that I am trying to "hijack" this is done via the Card Status flag - so the synth (you might be able to guess what I am trying to do by now ;D) only accesses the buses when a card is present. If I simulate that status flag with my application, I should be able to prevent the synth from accessing the bus. I will further try to physically remove the buses from the synth via the 646 to minimize the risk of damage to the synth. Whenever the status flag is set by my application, it means it will no longer have control over the buses, but the synth takes over. There is one critical moment, that is when my application wants to get back the bus control. It needs to set the status flag accordingly, which should not be done when the synth is trying to write to the card. But on the other hand, you would not unplug the card physically from the synth when you know that the synth is writing your sounds to the card, either, or would you? ;DBest regards, ilmenator Quote Link to comment Share on other sites More sharing options...
stryd_one Posted November 16, 2006 Report Share Posted November 16, 2006 Hmm .... If the synth checks that the card is present, you might be able to use that to your advantage... You might want to take a look at how the synth checks that pin, and maybe the core can use it and manipulate it's state? Quote Link to comment Share on other sites More sharing options...
ilmenator Posted November 17, 2006 Author Report Share Posted November 17, 2006 That's exactly how I will implement this. ;DBest regards, ilmenator Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.