I will re-check my code and get back to you. I took me many days to figure it out. I've made many mistakes. The code could be wrong.
if your intent is to write the to page buffer(in the code above) there is no need to use the byte address by shifting left and effectively doubling it. We are addressing this as if it were ram even though it is flash when writing a page to this "imaginary" page buffer... (but I don't know if that is what you are trying to do).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The fuses were causing the Status error. But, still no joy.
The explicit use case is - change on byte on a valid page in Program memory. This implies caching/reading the page and changing the byte. That is the functionality needed, this can be expanded to support many other use cases.
I will post a video soon, of my lack of progress.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I will attach another Flash Write program.
With my setup, it seems to work... I change the Test Byte from 0xaa to 0xbb to 0xcc and it fills the Flash Memory. Reads DATA using LPM or LD. The Timer interrupt blink works. Getting consistent flash writes.
I assume You're using the nano... is there any issues with the debugger or a bootloader? ... Shouldn't be.
Sounds like you are doing what is needed to get byte granularity... which is not easy.
The Write Flash process is tricky. As long as the BOOTEND fuse is not Zero, it should write Flash regardless of interrupt capability... I think.
Attached a reworked Flash Write with BOOTEND at 8 and APPEND at 16 .
This is the same program as above . It reads the flash before Flash Write, Prints to USART, puts it in ram, modifies a byte in ram, writes to Flash, reads the modified re- written flash and sends to USART. This works on the 0X1288 BOOTEND 8 : 0X1287 APPEND 16 Fuse settings
@Anobium: compiled some code fragments that You provided:
Sram variables are 1 byte in size and word(2 bytes)need to be reserved for some of these
unless the compiler is only using LOW byte IDK?? Possibly because
we are not going over 256 bytes for a page write?.
seems like the compiler is treating the 16bit addresses like 8 bit addresses
The 0x4000 is not added to the pointer ?
flash in Data Space starts at 0x4000 (16384 decimal)
The X register is counting up only on the low byte --- good, but the XH register is zero
Which means it isn't pointing anywhere in Sram or flash and is trying to write to CPU or something.
At minimum we need 0x4000 + address = (16384 + APPDATA(or APPCODE if using The bootloader section )
address being the section (APPCODE or APPDATA (depending)) that you want to write to.
Also depends on the fuse values.
A NOTE ON FUSES:
The BOOT SECTION is in low FLASH unlike ATMEGA328P type chips where the Bootloader is somewhere close to the end of high FLASH.
Assuming BOOTEND and APPEND are set the same:
You will have only two sections in this case.
BOOT Section and APPDATA Section
APPDATA starts at APPEND +1
( if APPEND fuse is set to 1 : 1 * 256 = 256 : 256-1 = 255 = APPEND : APPDATA starts 256)
( if APPEND fuse is set to 2 : 2 * 256 = 512 : 512-1 = 511 = APPEND : APPDATA starts 512)
( if APPEND fuse is set to 4 : 4 * 256 = 1024 : 1024-1 = 1023 = APPEND : APPDATA starts 1024)
EG.
if BOOTEND is 4 and APPEND is 4, then 0 to 1023 is BOOT section and 1024 to 49151 is APPDATA section.
to make interrupts work, you will need to move the interrupt Jump table or move the Interrupt vectors to the boot section... but don't worry about that until we get the chip Writing Flash.
Not sure I have an accurate idea of what's going on because I only have code fragments do not know if the compiler understands me? I'm not good with high level languages.
Still working on this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@Anobium: compiled some code fragments that You provided:
Sram variables are 1 byte in size and word(2 bytes)need to be reserved for some of these
unless the compiler is only using LOW byte IDK?? Possibly because
we are not going over 256 bytes for a page write?.
seems like the compiler is treating the 16bit addresses like 8 bit addresses
The 0x4000 is not added to the pointer ?
flash in Data Space starts at 0x4000 (16384 decimal)
The X register is counting up only on the low byte --- good, but the XH register is zero
Which means it isn't pointing anywhere in Sram or flash and is trying to write to CPU or something.
At minimum we need 0x4000 + address = (16384 + APPDATA(or APPCODE if using The bootloader section )
address being the section (APPCODE or APPDATA (depending)) that you want to write to.
Also depends on the fuse values.
A NOTE ON FUSES:
The BOOT SECTION is in low FLASH unlike ATMEGA328P type chips where the Bootloader is somewhere close to the end of high FLASH.
Assuming BOOTEND and APPEND are set the same:
You will have only two sections in this case.
BOOT Section and APPDATA Section
APPDATA starts at APPEND +1
( if APPEND fuse is set to 1 : 1 * 256 = 256 : 256-1 = 255 = APPEND : APPDATA starts 256)
( if APPEND fuse is set to 2 : 2 * 256 = 512 : 512-1 = 511 = APPEND : APPDATA starts 512)
( if APPEND fuse is set to 4 : 4 * 256 = 1024 : 1024-1 = 1023 = APPEND : APPDATA starts 1024)
EG.
if BOOTEND is 4 and APPEND is 4, then 0 to 1023 is BOOT section and 1024 to 49151 is APPDATA section.
to make interrupts work, you will need to move the interrupt Jump table or move the Interrupt vectors to the boot section... but don't worry about that until we get the chip Writing Flash.
Not sure I have an accurate idea of what's going on because I only have code fragments do not know if the compiler understands me? I'm not good with high level languages.
Still working on this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That is an error in the compiler or my use of it. These are meant to be constants so I need to look why the compiler is not treating as a constant. The latest DAT file and compiler may be needed to support these specific constants ( they come from the DAT file).
I took a break from PROGRAMWRITE. I will restart today using your great insights!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@cribcat I have edited your words posted. I will include in programs I am publishing.
If you have time. Please correct/edit etc.
Thanks
DetailsofwritingdataintoprogrammemoryonAVRmicrocontrollersusingGCBASIC.WritingDatatoProgramMemoryinAVRMicrocontrollers1.**Background:**-WhenworkingwithAVRmicrocontrollers,understandingthefusesandtheirimpactonwritingtoprogrammemoryiscrucial.-TheAVRDX(ATmegaDX)seriesdiffersfromATmega328P-typechipsintermsofmemoryorganization.2.**BOOTSectionandAPPDATASection:**-TheBOOTsectionresidesinlowFLASHmemorylocations.Incontrast,ATmega328P-typechipstypicallyplacethebootloaderclosetotheendofhighFLASHmemory.-GCBASICloadstheuserprogramintolowmemorystartingatlocation0x00.-Thetopofthebootloader(or,inthecaseofGCBASIC,thatisthetopoftheuserprogram)isreferredtoasBOOTEND.3.**FusesConfiguration:**-TheBOOTENDandAPPENDfusesplayacriticalrole:-**BOOTEND**:DeterminestheendaddressoftheBOOTsection.-**APPEND**:SetsthestartingaddressoftheAPPDATAsection.-Thefollowingrelationshipholds:APPDATAstartsatAPPEND+1.4.**CalculatingAPPDATAStartAddress:**-Let's break down the calculation:-IftheAPPENDfuseissetto1:-APPEND=1*256=256-APPDATAstartsataddress256.-IftheAPPENDfuseissetto2:-APPEND=2*256=512-APPDATAstartsataddress512.-IftheAPPENDfuseissetto4:-APPEND=4*256=1024-APPDATAstartsataddress1024.5.**Example:**-SupposeBOOTENDissetto4,andAPPENDisalsosetto4.-Thememorylayout:-0to1023:BOOTsection-1024to49151:APPDATAsectionRememberthatthefusesmustbeconfiguredappropriatelytosupportthewriteoperation.Iftheself-writecapabilityoftheAVRDXisused,itcannotwritetomemorylocationsdesignatedasthebootloader(i.e.,withintheBOOTsection).FeelfreetoaskifyouneedfurtherclarificationorhaveadditionalquestionsviatheGCBASICForum
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have created four demos - write byte, write word, write string and write data block.
/*ThisprogramwritesaBYTEtoPROGRAMmemory.ThesourceBYTEisshownbelow,theresultisshownonaserialterminalviatheUSART.***********************************************************************************************************************************************DetailsofwritingdataintoprogrammemoryonAVRmicrocontrollersusingGCBASIC.WritingDatatoProgramMemoryinAVRMicrocontrollers1.**Background:**-WhenworkingwithAVRmicrocontrollers,understandingthefusesandtheirimpactonwritingtoprogrammemoryiscrucial.-TheAVRDX(ATmegaDX)seriesdiffersfromATmega328P-typechipsintermsofmemoryorganization.2.**BOOTSectionandAPPDATASection:**-TheBOOTsectionresidesinlowFLASHmemorylocations.Incontrast,ATmega328P-typechipstypicallyplacethebootloaderclosetotheendofhighFLASHmemory.-GCBASICloadstheuserprogramintolowmemorystartingatlocation0x00.-Thetopofthebootloader(or,inthecaseofGCBASIC,thatisthetopoftheuserprogram)isreferredtoasBOOTEND.3.**FusesConfiguration:**-TheBOOTENDandAPPENDfusesplayacriticalrole:-**BOOTEND**:DeterminestheendaddressoftheBOOTsection.-**APPEND**:SetsthestartingaddressoftheAPPDATAsection.-Thefollowingrelationshipholds:APPDATAstartsatAPPEND+1.4.**CalculatingAPPDATAStartAddress:**-Let's break down the calculation:-IftheAPPENDfuseissetto1:-APPEND=1*256=256-APPDATAstartsataddress256.-IftheAPPENDfuseissetto2:-APPEND=2*256=512-APPDATAstartsataddress512.-IftheAPPENDfuseissetto4:-APPEND=4*256=1024-APPDATAstartsataddress1024.5.**Example:**-SupposeBOOTENDissetto4,andAPPENDisalsosetto4.-Thememorylayout:-0to1023:BOOTsection-1024to49151:APPDATAsectionRememberthatthefusesmustbeconfiguredappropriatelytosupportthewriteoperation.Iftheself-writecapabilityoftheAVRDXisused,itcannotwritetomemorylocationsdesignatedasthebootloader(i.e.,withintheBOOTsection).FeelfreetoaskifyouneedfurtherclarificationorhaveadditionalquestionsviatheGCBASICForum*/#chip mega4809 // Declare the Target Processor and Speed#option explicit // Require Explicit declaration of Variables#DEFINE USART3_BAUD_RATE 9600#DEFINE USART3_TX_BLOCKING#DEFINE USART3_DELAY OFF'*****************************************************************************************************//Mainprogramcommenceshere..everythingbeforethisissetupfortheboard.//NowassumesSerialTerminalisoperationalHserPrintCRLF1HSerPrintStringCRLF"Change/set a byte in PROGRAM memory",1//VariablesDimindex,Value,DataOffset,AddressasWordDimnewValueasWord//ThisistheaddressinPROGRAMmemory.//CanbeanyvalidPROGRAMmemoryasdeterminedbytheFUSES.Address=0xB000Value=0x55//WritethebyteProgramWrite(Address,value)//ShowresultsbyreadingthePROGRAMmemoryandsendtoaterminalviatheUSARTHserPrintCRLFHserPrint"Byte value written to PROGRAM memory = 0x"//Getthevalueofthebytewritten,setnewvalueto0anduseanewvariabletoprovethisisavalidresultnewvalue=0ProgramRead(Address,newvalue)HserPrintHex(newvalue)HserPrintCRLF//Showanyerror-anonzerovalueforNVMCTRLStatusCounterwillbeanerror.IfNVMCTRLStatusCounter<>0Then//Bit2–WRERRORWriteError//Thisbitwillread'1'whenawriteerrorhashappened.Awriteerrorcouldbewritingtodifferentsectionsbeforedoing//apagewriteorwritingtoaprotectedarea.Thisbitisvalidforthelastoperation.//Bit1–EEBUSYEEPROMBusy//Thisbitwillread'1'whentheEEPROMisbusywithacommand.//Bit0–FBUSYFlashBusy//Thisbitwillread'1'whentheFlashisbusywithacommand.HserPrint"NVMCTRL Error Status = "HserPrintStringCRLFByteToBin(NVMCTRLStatusCounter)//~Justshowsthebits2+1+0ofthestatusregisterEndIfDoLoopEnd
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The cause of the interrupts not firing is likely because of changing the fuse settings. It is unavoidable with these chips. You have to move the Interrupt JUMP table OR change the IVSEL to the BOOT Section. I will send two examples of how to fix.
As far as my understanding of fuses, I have many days/weeks tied up in trying to understand them. I think I have a handle on it but...Who Knows?
As far as the .DAT file: This is what prompted me to ask how far are we taking the functionality. We have the TCA timer That also has a split mode. It supports two PWM channels with interrupts(If I Recall Correctly). I have a program that runs TCA split mode with 6 PWM outputs as well.
We also have CCL which has the capability of adding gates to the input/ output circuitry. We have an event system which does something? There is AC/ADC Vref Select code that should be addressed, PORTMUX ...etc. These are all icing on the cake and you may want to wait to get them implemented... but many of them have (multiple) interrupt(s). I didn't know how to handle in the .DAT file.
I use the bit Mask( _bm) VS. the bit Position(_bp) usually. The .DAT file seems to use only bit Position(_bp)... is this correct? Are there other factors? I'm sure you'll keep me posted.
Currently working on trying to get a READ on an I2C 24LC64/24LC256 EEPROM for the past 2 weeks.
I will check the demos /explanations you wrote.
G
I use the bit Mask( _bm) VS. the bit Position(_bp) usually. The .DAT file seems to use only bit Position(_bp)... is this correct? Are there other factors? I'm sure you'll keep me posted.
Should have been resolved in build 1427. If these are not available please let me know.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@cribcat - You genius! I wasted many hours on this. I must learn to ask you first!
I changed the Fuses and it worked immediately!
#Chip mega4809#option Explicit/*This demo sets the LED on and off when the interrupt happens.------------PORTA--------------- Bit#: -7---6---5---4---3---2---1---0--- IO: --------------------------------- IO: ---------------------------------------------PortF---------------- Bit#: -7---6---5---4---3---2---1---0--- IO: -----SW-LED----------------------*/#DEFINE SW PINF.6DIR SW In // set the PULLUP for this specific port.pin PortF_PIN6CTRL.3 = 1#DEFINE LED PORTF.5DIR LED OutLED = 1On Interrupt PortFChange call ISR PORTF_PIN6CTRL = 0x03;DoLoopSub ISR LED = !LED wait 10 msEnd Sub
This should help explain the GCBASIC ( therefore my approach to the generic interrupts ).
Handling generic interrupts. A generic interrupt is where the interrupts listed in the Help are supported. Like PORTFCHANGE -this means the any interrupt on the port will the specified interrupt handler.
Handling non-generic or all interrupts. Let me caled them non-specific. A usermust write a interrupt handler called INTERRUPT. GCBASIC will handle the caching of the context but this means ANY interrupt of any source can be handled.
#Chipmega4809#optionExplicit/*This demo sets the LED on and off when the interrupt happens. ------------PortF---------------- Bit#: -7---6---5---4---3---2---1---0--- IO: -----SW-LED----------------------*/#DEFINESWPINF.6DIRSWIn//setthePULLUPforthisspecificport.pinPortF_PIN6CTRL.3=1#DEFINELEDPORTF.5DIRLEDOutLED=1//SetthepullupPORTF_PIN6CTRL=0x03;DoLoopSubINTERRUPTIfPORTF_INTFLAGS.6=1Then//handleaspecificinterruptLED=!LEDwait10msPORTF_INTFLAGS.6=1EndIfEndSub
the actual Interrupt() is topped and tailed by GCBASIC with the context save and restore. The context handler is smart and saves what is needed to be saved/restored..
@cribcat - two things. ISRs and Buld 1428 ( this has interrupt in DAT files and a tweek to the compiler).
Regarding ISR Vectors and FUSES.
I will, somehow, resolve automatically. The fuses can be read by a program therefore the program knows the fusese are non zero values. Then, as you have provided, change the vectoring.
Seems to me that ATMEL designed a chip for bootloaders as the key focus and they just confused the standard use case.
In the "C" language (AVR-GCC) they put a structure that sets the fuses and lets the compiler know where everything is. AVR-GCC also goes by a linker file and has a little more flexibility as well as Complexity. E.G.
AVR-ASM doesn't have a linker , but would a user statement of the Fuses (BOOTEND, APPEND) do the trick? ... I know we're trying to avoid complexity for the user though, Just a thought.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
"The datasheet is confusing for BOOTEDN/APPEND, but if you read one of their app notes- When BOOTEND is zero, the entire Flash is considered to be boot section, the value in APPEND is ignored, and it is not possible to write to Flash.
When BOOTEND is non-zero, the default location of the interrupt vector table pointer will be written to the start of the application code section by default. If no bootloader is used and the interrupt vector is not moved, it is possible to overwrite this by changing the IVSEL bit in the CPUINT_CTRLA register. If the IVSEL bit is changed, the interrupt vector will be pointed to the start of the bootloader section
Which seems to match what I see in a tiny3217- if BOOTEND is 0, it does not matter what APPEND is as the whole flash is a boot section so no writing. When you want APP DATA only, setting BOOTEND and APPEND to the same value (0x7C) gets you a BOOT section of 0x7C*256, an APP CODE section of 0 length, and an APP DATA section length of 0x400. Although there is no APP CODE section, the interrupt vectors are still placed according to the APPEND fuse value so unless IVSEL is set the hardware will route vectors to the APP DATA section. "
this explains a lot for me.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am considering adding this to the Help. Have a hack/edit this.
Evan
AVRDX microcontrollers, the BOOTEND and APPEND fuses, and their impact on interrupt vectors.
AVRDX Microcontrollers:
The AVRDX microcontrollers represent the latest and highest-spec 8-bit AVRs available.
Interrupt Vectors Overview:
Interrupt vectors are predefined memory locations that point to interrupt service routines (ISRs) for various events.
By default, the lowest addresses in the program memory space are reserved for the Reset Vector and the Interrupt Vectors.
The complete list of vectors includes RESET (highest priority), followed by INT0 (External Interrupt Request 0), and others. See the datasheet.
BOOTEND and APPEND Fuses:
These fuses are specific to the AVRDX microcontrollers and impact memory layout, program memory write operations and interrupt handling.
BOOTEND Fuse:
The BOOTEND fuse determines whether the Reset Vector and the Interrupt Vectors are located at the start of the Boot Flash section or not.
APPEND Fuse:
The APPEND fuse controls whether the interrupt vectors are appended to the end of the application section in flash memory.
This can be useful for certain bootloader scenarios.
GCBASIC and Bootloader support:
In GCBASIC, if the BOOTEND fuse is non-zero, the GCBASIC compiler will relocate the vectors using the #option bootloader nn directive.
Here, nn represents the BOOTEND value multiplied by 256 and divided by 2.
This ensures that the vectors align correctly with the bootloader behavior.
Safe Fuses and Interrupt Vectors:
When setting fuses, consider safety and usability:
Safe fuses to set include CODESIZE/BOOTSIZE or APPEND/BOOTEND fuses. These prevent unexpected behavior when uploading to a board that previously had a different bootloader (e.g., Optiboot).
Remember, understanding these fuses and their impact on interrupt vectors is crucial when designing firmware for AVRDX microcontrollers.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have tested and validated Software TWI/I2C. This just uses the existing I2C library. All the TWI/I2C is done in software with hardware dependency - therefore it always slower.
I have posted two SWTWI demos. One a discovery program - this shows the I2C device(s) on the I2C bus, and the other is a demon of test, graphics etc.
Result - it works. So, another thing ticked off the list.
I am not overly familiar with I2C Hardware . What does that entail? I've written a BIT BANG I2C for M328P chips but neve have done hardware. Don't have a good idea of what that looks like.
I wrote an INTERRUPT ONLY driven twi driver last January and it's the only thing I can get to work with my 24LC64 eeprom device. It will write 32 bytes and then read them back .
I can't seem to get hardware going with user software polling interaction. Must be something I don't understand. I do think I'm close though.
Now that I have the interrupt only code working (I think) Should be able to " reverse engineer " to get working code. Hopefully it will translate into viable master and slave code for two MCUs.
G
😄
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am finalising the ADC routines. The approach is a merge of GCBASIC and ASM but the user just calls ReadADC( AINn ). Should be completed in next few days. It will keep me busy.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The. I2C library's are included in the installation. They support a large set of I2C hardware and they support software and hardware I2C/TWI.
The architecture is three layers. User API, hardware specific library and then the communication layers. This means the comms layers is chip specific and as long as the basics work the solutions can be built upon that layer.
This is not my architecture design but Hugh's.
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I will re-check my code and get back to you. I took me many days to figure it out. I've made many mistakes. The code could be wrong.
if your intent is to write the to page buffer(in the code above) there is no need to use the byte address by shifting left and effectively doubling it. We are addressing this as if it were ram even though it is flash when writing a page to this "imaginary" page buffer... (but I don't know if that is what you are trying to do).
Thanks.
The fuses were causing the Status error. But, still no joy.
The explicit use case is - change on byte on a valid page in Program memory. This implies caching/reading the page and changing the byte. That is the functionality needed, this can be expanded to support many other use cases.
I will post a video soon, of my lack of progress.
I will attach another Flash Write program.
With my setup, it seems to work... I change the Test Byte from 0xaa to 0xbb to 0xcc and it fills the Flash Memory. Reads DATA using LPM or LD. The Timer interrupt blink works. Getting consistent flash writes.
I assume You're using the nano... is there any issues with the debugger or a bootloader? ... Shouldn't be.
Sounds like you are doing what is needed to get byte granularity... which is not easy.
The Write Flash process is tricky. As long as the BOOTEND fuse is not Zero, it should write Flash regardless of interrupt capability... I think.
Attached a reworked Flash Write with BOOTEND at 8 and APPEND at 16 .
This is the same program as above . It reads the flash before Flash Write, Prints to USART, puts it in ram, modifies a byte in ram, writes to Flash, reads the modified re- written flash and sends to USART. This works on the 0X1288 BOOTEND 8 : 0X1287 APPEND 16 Fuse settings
@Anobium: compiled some code fragments that You provided:
Sram variables are 1 byte in size and word(2 bytes)need to be reserved for some of these
unless the compiler is only using LOW byte IDK?? Possibly because
we are not going over 256 bytes for a page write?.
.EQU ADDRESS=10240 ; 0x2800
.EQU CCOUNT=10241 ; 0x2801
.EQU CHIPMAPPED_PROGMEM_START=10242 ; 0x2802
.EQU CHIPPROGMEM_PAGE_SIZE=10243 ; 0x2803
.EQU DDATA=10244 ; 0x2804
.EQU XMEMDATA=10245 ; 0x2805
.EQU XMEMDATA_H=10246 ; 0x2806
seems like the compiler is treating the 16bit addresses like 8 bit addresses
The 0x4000 is not added to the pointer ?
flash in Data Space starts at 0x4000 (16384 decimal)
The X register is counting up only on the low byte --- good, but the XH register is zero
Which means it isn't pointing anywhere in Sram or flash and is trying to write to CPU or something.
At minimum we need 0x4000 + address = (16384 + APPDATA(or APPCODE if using The bootloader section )
address being the section (APPCODE or APPDATA (depending)) that you want to write to.
Also depends on the fuse values.
A NOTE ON FUSES:
The BOOT SECTION is in low FLASH unlike ATMEGA328P type chips where the Bootloader is somewhere close to the end of high FLASH.
Assuming BOOTEND and APPEND are set the same:
You will have only two sections in this case.
BOOT Section and APPDATA Section
APPDATA starts at APPEND +1
( if APPEND fuse is set to 1 : 1 * 256 = 256 : 256-1 = 255 = APPEND : APPDATA starts 256)
( if APPEND fuse is set to 2 : 2 * 256 = 512 : 512-1 = 511 = APPEND : APPDATA starts 512)
( if APPEND fuse is set to 4 : 4 * 256 = 1024 : 1024-1 = 1023 = APPEND : APPDATA starts 1024)
EG.
if BOOTEND is 4 and APPEND is 4, then 0 to 1023 is BOOT section and 1024 to 49151 is APPDATA section.
to make interrupts work, you will need to move the interrupt Jump table or move the Interrupt vectors to the boot section... but don't worry about that until we get the chip Writing Flash.
Not sure I have an accurate idea of what's going on because I only have code fragments do not know if the compiler understands me? I'm not good with high level languages.
Still working on this.
@Anobium: compiled some code fragments that You provided:
Sram variables are 1 byte in size and word(2 bytes)need to be reserved for some of these
unless the compiler is only using LOW byte IDK?? Possibly because
we are not going over 256 bytes for a page write?.
.EQU ADDRESS=10240 ; 0x2800
.EQU CCOUNT=10241 ; 0x2801
.EQU CHIPMAPPED_PROGMEM_START=10242 ; 0x2802
.EQU CHIPPROGMEM_PAGE_SIZE=10243 ; 0x2803
.EQU DDATA=10244 ; 0x2804
.EQU XMEMDATA=10245 ; 0x2805
.EQU XMEMDATA_H=10246 ; 0x2806
seems like the compiler is treating the 16bit addresses like 8 bit addresses
The 0x4000 is not added to the pointer ?
flash in Data Space starts at 0x4000 (16384 decimal)
The X register is counting up only on the low byte --- good, but the XH register is zero
Which means it isn't pointing anywhere in Sram or flash and is trying to write to CPU or something.
At minimum we need 0x4000 + address = (16384 + APPDATA(or APPCODE if using The bootloader section )
address being the section (APPCODE or APPDATA (depending)) that you want to write to.
Also depends on the fuse values.
A NOTE ON FUSES:
The BOOT SECTION is in low FLASH unlike ATMEGA328P type chips where the Bootloader is somewhere close to the end of high FLASH.
Assuming BOOTEND and APPEND are set the same:
You will have only two sections in this case.
BOOT Section and APPDATA Section
APPDATA starts at APPEND +1
( if APPEND fuse is set to 1 : 1 * 256 = 256 : 256-1 = 255 = APPEND : APPDATA starts 256)
( if APPEND fuse is set to 2 : 2 * 256 = 512 : 512-1 = 511 = APPEND : APPDATA starts 512)
( if APPEND fuse is set to 4 : 4 * 256 = 1024 : 1024-1 = 1023 = APPEND : APPDATA starts 1024)
EG.
if BOOTEND is 4 and APPEND is 4, then 0 to 1023 is BOOT section and 1024 to 49151 is APPDATA section.
to make interrupts work, you will need to move the interrupt Jump table or move the Interrupt vectors to the boot section... but don't worry about that until we get the chip Writing Flash.
Not sure I have an accurate idea of what's going on because I only have code fragments do not know if the compiler understands me? I'm not good with high level languages.
Still working on this.
Re
That is an error in the compiler or my use of it. These are meant to be constants so I need to look why the compiler is not treating as a constant. The latest DAT file and compiler may be needed to support these specific constants ( they come from the DAT file).
I took a break from PROGRAMWRITE. I will restart today using your great insights!
Resolved! I was using an incorrect Constant! Once I spotted that.. it worked!
ARGHHHHHHHHHHHHHHHHHHHHHHHH!
You code was correct!
GCBASIC syntax is PROGRAMWRITE ( address, byte ). This will cache the page and update the single byte. Sounds, so easy!
Evan
I will put up two videos and a new complete build tomorrow then you can have a look at progress.
@cribcat I have edited your words posted. I will include in programs I am publishing.
If you have time. Please correct/edit etc.
Thanks
An example PROGRAM write/read .. writes a byte.
I have created four demos - write byte, write word, write string and write data block.
Video for users for PROGRAMWRITE() and PROGRAMREAD()
Enjoy
@cribcat et al.
Latest patch build is here: https://1drv.ms/u/s!Ase-PX_n_4cvhYNY1VP0Ztcl4FYRAg?e=z5TEd8
Download and test.
Evan
I am next going to sort the Interrupt Vectors in the DAT file. I will use the information you provided and I will validate.
Evan
I have made changes to the software that Gens the DAT file. It now is adding the interrupt vectors to the DAT.
If you get some time. Can you review the ASM attached? Why is the interrupt not firing? I must have missed BIT somewhere. Your eyes may save me days!
Thank you for being here.
The cause of the interrupts not firing is likely because of changing the fuse settings. It is unavoidable with these chips. You have to move the Interrupt JUMP table OR change the IVSEL to the BOOT Section. I will send two examples of how to fix.
As far as my understanding of fuses, I have many days/weeks tied up in trying to understand them. I think I have a handle on it but...Who Knows?
As far as the .DAT file: This is what prompted me to ask how far are we taking the functionality. We have the TCA timer That also has a split mode. It supports two PWM channels with interrupts(If I Recall Correctly). I have a program that runs TCA split mode with 6 PWM outputs as well.
We also have CCL which has the capability of adding gates to the input/ output circuitry. We have an event system which does something? There is AC/ADC Vref Select code that should be addressed, PORTMUX ...etc. These are all icing on the cake and you may want to wait to get them implemented... but many of them have (multiple) interrupt(s). I didn't know how to handle in the .DAT file.
I use the bit Mask( _bm) VS. the bit Position(_bp) usually. The .DAT file seems to use only bit Position(_bp)... is this correct? Are there other factors? I'm sure you'll keep me posted.
Currently working on trying to get a READ on an I2C 24LC64/24LC256 EEPROM for the past 2 weeks.
I will check the demos /explanations you wrote.
G
Should have been resolved in build 1427. If these are not available please let me know.
@cribcat - You genius! I wasted many hours on this. I must learn to ask you first!
I changed the Fuses and it worked immediately!
This should help explain the GCBASIC ( therefore my approach to the generic interrupts ).
Handling generic interrupts. A generic interrupt is where the interrupts listed in the Help are supported. Like PORTFCHANGE -this means the any interrupt on the port will the specified interrupt handler.
Handling non-generic or all interrupts. Let me caled them non-specific. A usermust write a interrupt handler called INTERRUPT. GCBASIC will handle the caching of the context but this means ANY interrupt of any source can be handled.
This gens this ASM, these are segments.
All vectors are to the user defined Interrupt()
the actual Interrupt() is topped and tailed by GCBASIC with the context save and restore. The context handler is smart and saves what is needed to be saved/restored..
This will handle all cases.
Last edit: Anobium 2024-09-18
@cribcat - two things. ISRs and Buld 1428 ( this has interrupt in DAT files and a tweek to the compiler).
Regarding ISR Vectors and FUSES.
I will, somehow, resolve automatically. The fuses can be read by a program therefore the program knows the fusese are non zero values. Then, as you have provided, change the vectoring.
Seems to me that ATMEL designed a chip for bootloaders as the key focus and they just confused the standard use case.
Build 1428 - https://1drv.ms/u/s!Ase-PX_n_4cvhYRZX6QjCzv3CKdcYw?e=f1KfXP
This has all the new DAT file and the latest compiler. This does not have FUSES related ISR vectoring - I need to think on this! A lot.
High level state of play. Not much more to complete!!!
In the "C" language (AVR-GCC) they put a structure that sets the fuses and lets the compiler know where everything is. AVR-GCC also goes by a linker file and has a little more flexibility as well as Complexity. E.G.
AVR-ASM doesn't have a linker , but would a user statement of the Fuses (BOOTEND, APPEND) do the trick? ... I know we're trying to avoid complexity for the user though, Just a thought.
A little extra information I found...
This is from CURTVM on the AVRFREAKS forum and deals with writing flash:
https://www.avrfreaks.net/s/topic/a5C3l0000003jtrEAA/t390218
"The datasheet is confusing for BOOTEDN/APPEND, but if you read one of their app notes- When BOOTEND is zero, the entire Flash is considered to be boot section, the value in APPEND is ignored, and it is not possible to write to Flash.
When BOOTEND is non-zero, the default location of the interrupt vector table pointer will be written to the start of the application code section by default. If no bootloader is used and the interrupt vector is not moved, it is possible to overwrite this by changing the IVSEL bit in the CPUINT_CTRLA register. If the IVSEL bit is changed, the interrupt vector will be pointed to the start of the bootloader section
Which seems to match what I see in a tiny3217- if BOOTEND is 0, it does not matter what APPEND is as the whole flash is a boot section so no writing. When you want APP DATA only, setting BOOTEND and APPEND to the same value (0x7C) gets you a BOOT section of 0x7C*256, an APP CODE section of 0 length, and an APP DATA section length of 0x400. Although there is no APP CODE section, the interrupt vectors are still placed according to the APPEND fuse value so unless IVSEL is set the hardware will route vectors to the APP DATA section. "
this explains a lot for me.
Good analysis.
GCBASIC already supports this! Amazingly, when I tested just now. The following happens.
Chip has fuses of BOOTEND = 0. In GCBASIC not change required.
Chip has fuse of BOOTEND = n. In GCBASIC requires #OPTION BOOTLOADER n*256/2,
If BOOTEND is 0x02 add #OPTION BOOTLOADER 0x100.
ASM where
If only I remembered all this the other day!
So, I we have a solution within GCBASIC. If a user changes the Fuses then then need to use #OPTION BOOTLOADER n*256/2.
Makes sense? and, will this work?
I just tested the theory - it works!! I have attached a working demo.
Last edit: Anobium 2024-09-19
I am considering adding this to the Help. Have a hack/edit this.
Evan
AVRDX microcontrollers, the BOOTEND and APPEND fuses, and their impact on interrupt vectors.
AVRDX Microcontrollers:
The AVRDX microcontrollers represent the latest and highest-spec 8-bit AVRs available.
Interrupt Vectors Overview:
Interrupt vectors are predefined memory locations that point to interrupt service routines (ISRs) for various events.
By default, the lowest addresses in the program memory space are reserved for the Reset Vector and the Interrupt Vectors.
The complete list of vectors includes RESET (highest priority), followed by INT0 (External Interrupt Request 0), and others. See the datasheet.
BOOTEND and APPEND Fuses:
These fuses are specific to the AVRDX microcontrollers and impact memory layout, program memory write operations and interrupt handling.
BOOTEND Fuse:
The BOOTEND fuse determines whether the Reset Vector and the Interrupt Vectors are located at the start of the Boot Flash section or not.
APPEND Fuse:
The APPEND fuse controls whether the interrupt vectors are appended to the end of the application section in flash memory.
This can be useful for certain bootloader scenarios.
GCBASIC and Bootloader support:
In GCBASIC, if the BOOTEND fuse is non-zero, the GCBASIC compiler will relocate the vectors using the #option bootloader nn directive.
Here, nn represents the BOOTEND value multiplied by 256 and divided by 2.
This ensures that the vectors align correctly with the bootloader behavior.
Safe Fuses and Interrupt Vectors:
When setting fuses, consider safety and usability:
Safe fuses to set include CODESIZE/BOOTSIZE or APPEND/BOOTEND fuses. These prevent unexpected behavior when uploading to a board that previously had a different bootloader (e.g., Optiboot).
Remember, understanding these fuses and their impact on interrupt vectors is crucial when designing firmware for AVRDX microcontrollers.
I have tested and validated Software TWI/I2C. This just uses the existing I2C library. All the TWI/I2C is done in software with hardware dependency - therefore it always slower.
I have posted two SWTWI demos. One a discovery program - this shows the I2C device(s) on the I2C bus, and the other is a demon of test, graphics etc.
Result - it works. So, another thing ticked off the list.
Just need the same for hardware TWI/I2C.
:-)
Last edit: Anobium 2024-09-19
Looks Good, Excellent work !... That's Good News.
I am not overly familiar with I2C Hardware . What does that entail? I've written a BIT BANG I2C for M328P chips but neve have done hardware. Don't have a good idea of what that looks like.
I wrote an INTERRUPT ONLY driven twi driver last January and it's the only thing I can get to work with my 24LC64 eeprom device. It will write 32 bytes and then read them back .
I can't seem to get hardware going with user software polling interaction. Must be something I don't understand. I do think I'm close though.
Now that I have the interrupt only code working (I think) Should be able to " reverse engineer " to get working code. Hopefully it will translate into viable master and slave code for two MCUs.
G
I am finalising the ADC routines. The approach is a merge of GCBASIC and ASM but the user just calls ReadADC( AINn ). Should be completed in next few days. It will keep me busy.
@cribcat
The. I2C library's are included in the installation. They support a large set of I2C hardware and they support software and hardware I2C/TWI.
The architecture is three layers. User API, hardware specific library and then the communication layers. This means the comms layers is chip specific and as long as the basics work the solutions can be built upon that layer.
This is not my architecture design but Hugh's.