Jump to content

This N°9

Programmer
  • Posts

    331
  • Joined

  • Last visited

Everything posted by This N°9

  1. So calls to MIOS_LCD_xxx and any IIC-related functions are not save during a FRAM-session. Which are the functions/modules that use the IIC port (besides MIOS_Bankstick_xxx and MIOS_IIC_xxx)? I just would like to document this in README.txt of the module. I guess the ISR will never manipulate any of these PINs (J4 SD/SC and J10 SO/RC), even not in applications like SID? I first decided not to do this, because this will allocate additional code space. But on the other hand it's just some instructions that would have to be called in the app if there's no save-mode-functions. Anyhow, the ability to do subsequent reads/writes and to handle data between two read/write calls is a big advantage, so I would like to have a good documentation about what can be done in a FRAM session and what not.
  2. First the good news: the FRAM-module (http://www.midibox.org/forum/index.php/topic,12641.0.html) is running (tested with the slower mios_iic so far, tests with the 1MHZ driver will follow). I noticed that it's not possible to stretch a session (begin -> write -> write -> end) over multiple Tick()'s, which seems logic if I see that J4 SC is a shared pin. My question: which function calls will use the J4 pins? For ex. MIOS_LCD_XXX with a LCD connected to J15? The thing is, that the FRAM module does not wrap a whole start->r/w->stop cycle in one function, for the advantage of subsequent r/w without sending the address again. So I need a guideline which module/mios - functions are save to call during such a session. The faster IIC-protocol implementation uses RC4/5 by default, I think there I'll not meet this problem (?).
  3. That's exactly what I intended to do :) FSR1 I'll use for data buffer address pass, MIOS_PARAM_1/2 for chip memory address pass. Stuff like buffer size / chip select I pass via WREG.
  4. Ah yeah... Simmilar issue as with the FSR1/0 swap.. By the way: I use now FSR1 / MIOS_PARAM_1 / MIOS_PARAM_2 in my module to pass parameters to the functions.. Do I go right assuming that MIOS_PARAM_1 / 2 are exactly there for this purpose? First I was not sure if it is 'legal' for modules to use them, but I see that the AIN-module for ex. also uses them as function params. I start loving ASM, it's really hitting the bottom (or top) of the whole coding story... joy :D
  5. Some of you may remember the 'multiple whatever at address 0x00' - issue (the SDCC compiler bug). I just realized what's all about the 0x00 story: (I learned this while looking at the MIOS-wrapper) MIOS places some registers for the OS at memory address 0x00, the SDCC wrapper uses this address *also*, but declares them as 'overlay' (shared), it uses them as function params: ; Internal registers .registers udata_ovr 0x0000 r0x00 res 1 r0x01 res 1 r0x02 res 1 r0x03 res 1 r0x04 res 1 r0x05 res 1 r0x06 res 1 r0x07 res 1 r0x08 res 1 r0x09 res 1 r0x0a res 1 r0x0b res 1 r0x0c res 1 r0x0d res 1 r0x0e res 1 r0x0f res 1 r0x10 res 1 r0x11 res 1 I thought 'oh my god', but the good thing is, that these internal registers will be pushed and popped to/from the stack at every function call/return. So if the program goes back to the main loop, the original values will be there again. I just wonder what happens if I call a MIOS function that sets a flag or so in one of these registers. This value would evetually get lost on the way back to the main loop ?
  6. I think the most critical part will be the slew rates. I have only a few spots in the code where I can't do anything else between setting SDA and SCL than inserting NOP's. Can I assume that the inner-chip timings that have nothing to do with the outer wiring are quite reliable values (like 'start condition hold time' or 'scl low data out valid' ) ? What are your experiences with slew rates? What is a good worst case value for a PIC out pin, with, say a cable of 20cm ? Sure there is also the slave device itself that influences this. I think I will do this, somthing like a 'save mode' that slows down a bit the whole story but makes it saver against outer influences. The thing is, with 1MHZ clock @ 10MIPS, you really don't have that much cycles left to fill up with nop's :)
  7. one more question: I'am writing my faster iic-driver right now, in the specs of the chip I have some timing parameter like: data in setup (SDA set to SCL high): min. 100ns bus free before new transmission: min. 500ns start/stop condition hold time: min. 250ns etc. can I really go to the edge of the timing params, is this not save in respect to maybe a longer cable connecting the IC to the core? how are slew rates of pin outputs on the PIC? For ex. "data in setup" is exactly one instruction cycle, so if I go to the edge I would not to have a nop between the SDA set and the SCL hight set.
  8. ok, I already removed it, if you feel bad about it, revert it :) I think most people won't use the workaround, so it's time saving to explain the workaround for those who need it, than to explain the stuff to those who dont need it. Because it was in the template, I thought it's something that is absolutely needed, maybe it would help to explicitely note that this is not a "must" for having defines that can be overloaded. by the way, I fixed the c function templates (movwf -> movff) in the mod_skel
  9. yeah but the label used with IDATA is for both codespace and ram then?
  10. ok, this makes it a bit clearer to me.. anyway, I will remove the workaround from the mod_skelleton and remove the _score.
  11. So I suggest to remove the 'trick' from the mod_skel, sorry stryd, but for my eyes it causes more confusion than any advantage for 'mod_skel newbies'. You will have to spend a lot of time to explain what it is like in my case ;) I would rather replace it with #ifndef mod_skel_def #define mod_skel_def 1 #endif for example in my code, I need the define for a condition in the .asm as well as in the .inc, so I do the check in both, somebody can include just the .inc then and the define is guaranteed to be set (the same as in the blm module).
  12. I still dont get the point.... Why to 'copy' the define if it is defined? You will use only the copied _mod_skel_def anyway, so why not just use the 'original' ? And is the else-section not basically the same as 'ifndef' ? #ifdef mod_skel_def #define _mod_skel_def mod_skel_def #else #define _mod_skel_def 1 #endif I don't want to argue, but please explain me the difference / advantage of the code above to this one: #ifndef mod_skel_def #define mod_skel_def 1 #endif it does exactly the same: if the stuff is defined, let it be like it is, if not, define it with a default value. The only difference is, that your code copies the define to the _mod_skel_def, whatever it is for ? And in the .inc then, you check *again* for the existence of the define, and assign a default value if it's not there, exactly the same you do in the code above. So what about this ****ing _score thing? I still don't see the trick. Make me see it..
  13. Ahh.. ok. It's neither in the gputils doc nor in the MPASM doc.. It's a bit weired with this harvard architecture stuff.. One thing I also wonder is which directives apply only for code / memory sections. DB/DW/DATA etc. for example seems to apply for both, RES only for memory? I guess that the assembler uses internally one pointer for Data space and one for Program space? For example IDATA seems to allocate both memory and code space. Is the label used for the IDATA section then pointing to data/code as well, in dependency of the command used?
  14. Ok, I see. Couldn't they just also use the .asm file, no need to care about memory locations? I don't plan to write any application in asm, I just wonder and want to understand this whole relocate-thing and all this better. Or maybe I just use the same condition I use to (conditionally) include the fram_iic.inc to (conditionally) set up the variable(s)? Some other question: As I understand both code space and memory are addressed from 0x00. I found some example on the WWW that tells me I can set up variables in memory like this: ORG 0x20 Wert RES 1 ; Wert bedeutet ab sofort 0x20, Wert ist eine 1 Byte große Variable Pointer RES 3 ; Wert bedeutet ab sofort 0x21, Pointer kann als 3 Byte große Variable dienen Temp RES 1 ; Wert bedeutet ab sofort 0x24 sorry for the german.. but isn't ORG just for code space addresses or does it also work with memory? ???
  15. hm... but why use the underscore? why not just write #ifndef mod_skel_def #define mod_skel_def 1 #endif wouldn't this come out to the same, and avoid to use the _ ? in the mod_skel.inc excactly this is done then: #ifndef _mod_skel_def ; if it's not already defined in the makefile (see readme.txt) #define _mod_skel_def 1 ; default to 1 #endif ; (see also mod_skel.asm for GPASM fix!) I really don't see the point. If the define is not given by the makefile, just create it with a default value. Or did I miss something ??? The 'define does not exists' would then just end in a certain value assigned to this define. The condition can then just check for this value to decide wheter to assemble or not? exactly what is done in the condition-example then: #if _mod_skel_def==1 ; note this is using the define from the fix in the asm file! incf _mod_skel_var, F, BANKED #endif so as a short summary, my vision of all this: #ifndef mod_skel_def #define mod_skel_def 1 #endif #if mod_skel_def==1 //do this and taht #endif if you give the define in the makefile, the given value will rule, if not, the default will rule.. what I dont see?
  16. I found this in the mod_skel.asm, but I can't figure out what's the use of it. I also can't find a similar thing in existing modules: ; ========================================================================== ; Fix defines ; ========================================================================== ;; grrrr! "#if defined(mod_skel_def) && mod_skel_def == 0" not supported by GPASM ;; therefore we create a helper #define ;; this 'copies' the define to the module ;; thanks to TK for figuring this out! #ifdef mod_skel_def #define _mod_skel_def mod_skel_def #else #define _mod_skel_def 1 #endif
  17. I have a understanding problem concering variables/relocatable mode: if I build a module and I need a variable "x", I define it in a udata-section in the .asm file. I understand that it's address will then be calculated by the linker later. But what happens if somebody includes the .inc file of the module in his program directly? where will be the variable/label then, how is it's address calculated then? Or asked differently, how are "variables" defined for non-relocatable mode? is the only way to use EQU or is there another way? I'am building a module to drive FRAM IC's. To drive these with 1MHZ clock speed, I provide (optional) iic-functions located in a separate .inc file. This one uses a 1-byte-buffer. The module can use the mios_iic@400kHz or the dedicated iic@1MHZ then. If "#define FRAM_MIOS_IIC 1" is set, the fram_iic.inc will be included. Do I have to define the buffer needed in fram_iic.inc in fram.asm, or is there a way to locate it in fram_iic.inc itself?
  18. this makes sense... file rev date time user ..
  19. I noticed these "id" lines in all files (.mk, .asm, .h, .c): ; $Id: mod_skel.inc 69 2008-02-01 00:20:18Z tk $ what about these? can I change or remove them in my own files?
  20. I will implement the module like this: - I implement iic functions in my module that run @ 1MHZ - Standard port will be RC (0/1). This can be reconfigured with defines. - a #define selects if the mios_iic functions should be used. In this case, the 1MHZ iic-functions will not be included. - for both options, there will be a (optional) 4x multiplex mechanism. Default port will be J10 (RC4/RC5). This also can be changed. this way, most flexibility is guaranteed. For devices that neither use MF nor AIN, the faster solution can be chosen.
  21. Ok, I see the point. I see different variants: - use the mios_iic with 400kHz. This would make the port shareable with other iic-devices, J10 would stay free for optional multiplexing. advantage: shareability, no additional port will be used, smaller code (iic already part of mios) disadvantage: slower transfer rates - use some other (configurable) port. default would be something else than iic (use iic at your own risk). advantage: full clock speed. 8 banksticks could be used in parallel with 16 FRAM (with multiplexing) theoretically. disadvantage: more code, one more port will be used. The speed loss with the first option is not so tragic, because the big advantage of the FRAM is write speed (in opposite to the banksticks), and higher endurance (1 billion r/w cycles). I can't decide this right now, maybe you have some opinion to that. For my own (sequencer) needs, both options would work well.
  22. there's something to mention, this could be important: I looked at the timings of the mios_iic, and it looks like it's target clock frequency is 400kHZ instead of 1MHZ (PIC@10MIPS). A single bit read / write loop takes 23 / 24 cycles, an ACK even 33 cycles. If I calculate just the single bit r/w, I get 416 - 434 KHz. This more that halfs the speed that the Ramtron FRAM supports (min. clock high 0.4uS; min clock low 0.6 uS; data out valid max. 0.55uS; data in setup min. 100ns.;data hold in/out 0nS). One option would be to have a flag that sets the IIC to 1MHZ fast mode. This could also be a #define, with disadvantage not to have control @ runtime. Doing it by a define would allow me to not have the iic-code double, the code size / mem usage of MIOS would not rise (even fall) with the #define fast_mode 1 option. The only thing I would have to do, is to modify some delays if #define fast_mode 1 is set. If you (TK and others) like the modified version when it's finished and tested, it could go to repository definitively.
  23. happy new year to everybody! This would be nice. The FRAM is using the same slave id (b1010) and almost the same control byte (first byte after "start" condition): FM24C512(Ramtron FRAM): [1][0][1][0][A2][A1][A15][R/W] 24LC512(Microchip EEPROM): [1][0][1][0][A2][A1][A0][R/W] A0 - A1 are device select bits. FM24C512 has only 2 device select pins, A15 is the address MSB, the FM24C512 addressspace is parted into two sections which can not be writte or read continously. banksticks/fram could be even mixed, each FRAM would take two addresses of 8, each bankstick just one. So the "cheap" solution would be to just have the multiple-call-communication as "expert mode", where people are adviced not to call other IIC-related functions/devices while having a open communication to FRAM. This would be wise anyway, because it's better for the coder to know when the IIC port is blocked, and in most of the cases the code will not do anything else during a read/write session. For the "save" read/write I just would supply some functions that wrap the calls to make a port-blocking function. Thats true, the IIC stuff is already implemented, and at a short glance in the code, I see the same timings as I read in the FM24C512 datasheet, like 600ns to wait for ACK beeing set etc. So using mios_iic will be the plan. This also simplifies the way for sharing the port between devices/protocols in the future, if some changes on iic-level should be done. sorry about that. But the schematics for the two output types (open drain/push-pull) for the PIC are labeled in english. I attach them here. One is the i/o pin schematic of the pic16, the other pic 18(with readable Latch). Looking at them made the whole thing for my a lot clearer. thanks for all the info, I think I'm ready now to start with the FRAM module. :)
  24. happy new year to the australian guys! :D well, it is... Communication protocoll is IIC. It works very similar to the bankstick, but the protocoll is a bit different because it's not a eeprom, but a FRAM, single bytes can be written / read at same speed (full clock speed max. 1MHz), no need to wait for the write cycle to finish :) The sharing *could* be a problem, because my aim is not to start/perform/stop a whole read/write sequence within one single function. the advantage of this: I can start a read (setting address etc.), after a ACK the device will increment the internal address latch to the next byte, so subsequent reads of single bytes are possible (or writes). For me this is very important, because this enables me to "stream" data very fast, say read a byte or more, check what it is, decide if I need to read more, if not, I perform a stop condition. I could write some low-level-funtions that do this, like: unsigned char MIOS_FRAM_ReadStart(unsigned char devicenr, unsigned int addr); unsigned char MIOS_FRAM_WriteStart(unsigned char devicenr, unsigned int addr); unsigned char MIOS_FRAM_ReadByte(void); unsigned char MIOS_FRAM_WriteByte(unsigned char) unsigned char MIOS_FRAM_ReadBuf(unsigned char * buf, unsigned int byte_count) unsigned char MIOS_FRAM_WriteBuf(unsigned char * buf, unsigned int byte_count); unsigned char MIOS_FRAM_ReadWriteStop(void); These ones would be "unsave" to share with other IIC devices, if a read/write sequence will stretch over several main-loops. If the whole operation is done in one tick-call, the IIC bus should be free on the next MIOS-mainloop. Or are IIC operations also done in ISR/Timer callbacks? There could be also high-level-functions which do a start/rw/stop sequence in one call, like with the BankStick-Functions. More reasons why I would like to use PORTA/J4 is, that the device will be a direct alternative to the banksticks, and I plan to use J10/PORTC to multiplex up to 16 of the FRAM devices (4 can be addressed by pins, 4 arrays would be multiplexed with a 4channel analog dual multiplexer). However, the device is not very DIY friendly (only available in SOIC package so far). I just use it because I need fast stream ability from/to a big data space. Maybe I could use the mios_iic module, but this would mean some more overhead/more calls etcetc. If I implement all in one single module, I can make it very tight. But I'll study the mios_iic module anyway, maybe there are good reasons to use already existing iic functions. Can I drive the IIC with 1MHZ with the mios_iic ? Thanks for link, I think stuff like this is worth to flow into the wiki? I found some other page on the WWW that explain the issue quite clear: http://www.fernando-heitor.de/component/option,com_openwiki/Itemid,123/id,mikrocontroller:einfuehrung/ If I understand right, the general rule is: to set pin states, use LATxx, to read them use PORTxx. To set in/out configuration, use TRISxx while TRISxx=1 means "input" and TRIXxx=0 means "output" (for the PIC)
  25. thanks, this is very usefull info for me. I'll correct the "template bug" in the mod_skel by replacing movwf by moveff. PIC18F452 is exactly the one I'am using.. / have spare ones. I had a look at smashTV's store and see that he sells now the PIC18F4685.. When I did my last order, it was still the 452. In the datasheet I see the new one has double RAM space and more code space available... I have/want to use RA4 because I want to use the same pins as the bankstick/iic would, so RA4 is my dataline. This means also that I need to switch it input<->output. If the pin is only available as open-drain, does this mean it can be used as input when it is in high-z-state? This looks logic to me if I look at the code in mios_iic.inc: bsf MIOS_IIC_LAT_SDA, MIOS_IIC_PIN_SDA ; SDA = input #if RA4_IS_OPEN_DRAIN == 0 bsf MIOS_IIC_TRIS_SDA, MIOS_IIC_PIN_SDA ; SDA = input #endif I suppose you just do both to match newer/older derivates? and if I'am already asking a lot of questions: what stands LAT for? Is there a good information resource on the web or so where I can get an overview of all these principals? thanks a lot
×
×
  • Create New...