The ASM generated is not AVR specific. There is no handler for AVR ( the compiler should issue a warning - I failed to do that)
In the context that that there is no handler for aVR. The ASM is correct to load any byte value into PROGMEM ( not EE ) on 18F ( not 16, 14, 12, 10f as this cannot support values of of greater than 0x3f for the high byte). But, I would need to check that the 'As BYTE' is working.
The goal here is the correct structure for AVRDx.
Is this correct for Bytes ?
DATA DataSet1 as Byte
3,2,0x40,0x00
End DATA
ASM
DATASET1:
.db 0x0203, 0x0040
Is this correct for Words ?
DATA DataSet1 as Byte
3,2,0x4000
End DATA
ASM
DATASET1:
.dw 0x0300, 0x0300, 0x0040
Once I know the expected ASM then it will be easy to update the compiler.
Last edit: Anobium 2024-08-25
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
TX and RX for ARVDx across all five USARTs is now supported.
Very simple to use, the same as always in GCBASIC. Example program below shows USART setup with optional TX_BLOCKING and/or RX_BLOCKING constants. The standard HSER command set.
The GCBASIC routines have always returned a default value if HSERRECEIVE() is called and no incoming data is received. This prevents blocking.
The major difference is that if only one USART is defined in the source, with the USART setup constants, then the methods will default to that USART. This means that send the comport parameter is not mandated. If the comport parameter is used then the compiler will optimise the code produced.
Further clariification that two other usefule constants exists, as follows.
#DEFINE DEFAULTUSARTRETURNVALUE 'The byte value returned from USART receive when USARTx_BLOCKING is NOT used.
#DEFINE DEFAULT_COMPORT 'The default USART. Used when calling HSER functions to select USARTn.
Example
#chip mega4809
#option Explicit
// Serial setup
#DEFINE USART3_BAUD_RATE 9600
#DEFINE USART3_DELAY OFF
#DEFINE USART3_TX_BLOCKING
#DEFINE USART3_RX_BLOCKING
// Variables
Dim inbyte as Byte
// Main program
HSerPrintStringCRLF "Serial Loopback on terminal"
Do
HSerReceive( inbyte, 3)
If inbyte <> DEFAULTUSARTRETURNVALUE Then
HSerSend ( inbyte, 3 )
End If
Loop
GCBASIC supports multiple USARTS ( as it should ). The USART will handle the second or more USART automatically. The library adds additional IF-THEN statements as need to support the defined USARTs. The following ASM show USART1 and USART3 in use.
Another example for you.
This one calls the HSerReceive() function rather than the subroutine.
:-)
#chip mega4809
#option Explicit
#DEFINE USART3_BAUD_RATE 9600
#DEFINE USART3_TX_BLOCKING
#DEFINE USART3_RX_BLOCKING
#DEFINE USART3_DELAY OFF
// This assumes you are using a serial PC terminal.
// Main program
// Wait for terminal to settle
wait 1 s
HSerPrintStringCRLF "GCBASIC serial loop back"
HSerPrintStringCRLF "Data received will be sent back"
HserPrintCRLF
PulseOut PortF.5, 100 ms
wait 100 ms
Do
HSerSend ( HSerReceive (3) , 3) // HserSend needs to be told which USART to use, this will be fixed when only one USART is defined in program
Loop
Using the subroutine is faster but may use an addition byte of RAM.
HSerReceive( inbyte, 3) where inbyte is the target byte rather than = HSerReceive(3).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have completed testing of the Serial Buffer Ring. This program has an interrupt on the USART RX and puts the incoming data into a buffer. The main program then HserPrint the data on the terminal.
This buffer is well known, and, is documented in the Help ( I will update to add the AVRDX example).
The program main loops, when there is new data in the buffer then bkbhit will be true. Then, the next byte out of the buffer is obtain via the function bgetc().
The proves the interrupt handler of the compiler is working.
The source program has the GCBASIC instruction On Interrupt USART3_RXC Call readUSART This instructs the compiler to SEI and enable the USART3_RXC interrupt. The USART3_RXC interrupt enable bit is in the DAT/Interrupts section.
The compiler did not support REGISTER.BITNAME_AS_CONSTANT. The compiler did support REGISTER.bit_number_constant or bit_name_constant. Noting that bit_name_constant prior to AVRDx was unique so this worked.
The compiler now also supports REGISTER.BITNAME_AS_CONSTANT The compiler resolve this to REGISTER.bit_number_constant which works great.
Summary
New compiler - 1416
New DAT file - I have added the interrupt information for serial.
No updates to USART.H required.
Attached is the test program.
If you would like to try this. I can upload the files for you. I am concerned that we are updating the main release to often. I am getting feedback to reduce the number of releases/updates. Let me know if you can test.
Regarding 40_MEGA4809_USART_RXTX .gcb gave me a warning message(see attachment) when I compiled and did NOT return characters when typed. It did display the message "Started: Serial between two devices" on Realterm.
I think the Progmem "data" is possible on the avr-0/1 series chips using the NVM controller.
If my memory serves me, in the older MCUs like the m328P, only the bootloader can do the SPM(Store Program Memory)in a routine. You have to define and set the bootloader section with fuses, then write from that section.
In the avr-0/1 series, BOOT section can write to APP section and the APP section can write to the APPDATA section. --BUT--- there are 2 fuses that set this up and they need to be set correctly and FUSES can only be set by UPDI. Might make it a pain for the end user.
I will attempt to get working code for m4809 storing in Progmem FLASH .
The 328P has 1024 bytes of EEPROM which is a lot easier to write than something like a bootloader.
thanks
G
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This build is focused on UART.H operations, and the interrupt handler for USART. The compiler now caches correctly upon an interrupt, the DAT file has these interrupt bits.
Instructions are in the ZIP. You may have to UNBLOCK these file using the Windows properties for the EXE's.
This version also compiles the generated ASM in AVR2ASM. This is always a good thing!
Enjoy!
Last edit: Anobium 2024-08-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Compiled and loaded hex from "40_MEGA4809_USART_RXTX .gcb" in the 'Demos' directory that you sent with the Build 1416 package .
it says "Started: Serial between two devices" and echoes back any character typed .
Looks Good... Congratulations!
will look at RTC.
👍
1
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
We also have USERROW which gives us another 64 bytes of EEPROM. Evidently it operates like EE and you can write a single byte at a time while CPU running. Working on Flash write Progmem at the moment.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
USERROW should read the same as the EEProm(according to the data sheet). It's address starts@ 0x1300 and ends 0x133F while EE is 0x1400 to 0x14FF.
In fact, I think all the AVR-0/1 processors have Unified Memory ... so you can read flash with an LD instruction. LD R18, X+ just remember that " dataMapped_PROGMEM" starts @ 0x4000 on the M4809.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Interestingly, these AVRDx timers are different. They would be. :-)
The timers are not code-compatible (a different set of registers), but all functionalities present on legacy AVR are replicable using AVRDx timers.
GCBASIC replicates the legacy AVR functionality using AVRDx timers. This leaves all the new AVRDx timer functionality for the user to play with.
The GCBASIC commands are:
InitTimer()
SetTimer()
StartTimer()
StopTimer()
On Interrupt Timer0OverFlow
In Normal ( Coounter ) mode, the TCA Overflow output is not present on a pin, but the TCA can be used to generate an interrupt when the number of counting events reached the TCAn.CMPn value.
The GCBASIC uses the configuration of TCA to generate periodic interrupts on the overflow flag. This provides functional compatibility.
This program shows the functionality - the demos in the ZIP (see the link) are more comprehensive.
#chip mega4809
#option Explicit
/*
Flash LED every specified time period
Some examples for testing
PS_0_1024 0x4C4A = 1s
PS_0_64 31250 = 100ms
*/
//! Initialise the Timer for 1s
InitTimer0 ( Osc, PS_0_1024 )
//! Set the timer
SetTimer ( 0 , 0x4C4A )
//! Start timer
StartTimer ( 0 )
//! Set the interrupt
On Interrupt Timer0OverFlow Call ISR
// Main loop
Do
Loop
Sub ISR
PulseOutInv PortF.5, 50 ms
End Sub
All very easy. The values for scaler and the period can be obtained from the Timer calculator in the demo folders.
Latest ZIP contains new library, compiler ( I tweaked ) and DAT file! All the files are to be used.
Speaking of timers, for the millis () function, There are four TCB type and one TCA type. The TCA timer would seem Ideal for millis() but you are left with TCB timers which have unity or /2 prescale capability. You can run TCB from TCA's prescaled input clock but they are then locked. ULP_OSC? Maybe I've put the cart before the horse ... anyway it's on my mind.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Millis() is now support on AVRDX for any of the valid frequencies ( supported by AVRDX ).
24, 20, 16, 10, 8, 5,4,2.5,2,1.25,1,0.625 and other little frequencies...
The program code below counts the millis for 1000 ( see the constant LEDRate ) and therefore the If - then statement means the LED toggles every 1000 ms.
The program code below is a standard demo to show this capability.
#chip mega4809, 5 ' Declare the Target Processor and Speed#option explicit ' Require Explicit declaration of Variables#include <millis.h> ' Include the Library#define LED PORTF.5 ' Define the LED Pin#define LEDRate 1000 ' Flash rate in mS' SetupDirLEDOut' Make the LED Pin an OutputLED=0DimCurMs,LstMsasword' declare working variables' Main 'Thislooprunsoverandoverforever.LstMs=0CurMs=0' Main 'Thislooprunsoverandoverforever.DoCurMs=millis()ifCurMs-LstMs>=LEDRatethen' required Time has ElapsedLED=!LED' So Toggle state of LEDLstMs=CurMs' And Record Toggle TimeendifLoopEND
Files updated.
millis.h - add AVRDX capability
timer.h - change the inittimer0 function to NOT clear the enable state of the timer
mega4809.dat - improved interrupt handler
Thanks for the message in the file.
The ASM generated is not AVR specific. There is no handler for AVR ( the compiler should issue a warning - I failed to do that)
In the context that that there is no handler for aVR. The ASM is correct to load any byte value into PROGMEM ( not EE ) on 18F ( not 16, 14, 12, 10f as this cannot support values of of greater than 0x3f for the high byte). But, I would need to check that the 'As BYTE' is working.
The goal here is the correct structure for AVRDx.
Is this correct for Bytes ?
DATA DataSet1 as Byte
3,2,0x40,0x00
End DATA
ASM
DATASET1:
.db 0x0203, 0x0040
Is this correct for Words ?
DATA DataSet1 as Byte
3,2,0x4000
End DATA
ASM
DATASET1:
.dw 0x0300, 0x0300, 0x0040
Once I know the expected ASM then it will be easy to update the compiler.
Last edit: Anobium 2024-08-25
USART TX and RX completed
TX and RX for ARVDx across all five USARTs is now supported.
Very simple to use, the same as always in GCBASIC. Example program below shows USART setup with optional TX_BLOCKING and/or RX_BLOCKING constants. The standard HSER command set.
The GCBASIC routines have always returned a default value if HSERRECEIVE() is called and no incoming data is received. This prevents blocking.
The major difference is that if only one USART is defined in the source, with the USART setup constants, then the methods will default to that USART. This means that send the comport parameter is not mandated. If the comport parameter is used then the compiler will optimise the code produced.
Further clariification that two other usefule constants exists, as follows.
Example
ASM
Multiple USARTs defined
GCBASIC supports multiple USARTS ( as it should ). The USART will handle the second or more USART automatically. The library adds additional IF-THEN statements as need to support the defined USARTs. The following ASM show USART1 and USART3 in use.
See attached. I will upload to SVN. And, this will be released.
Meanwhile, download and copy to the include/lowlevel folder.
Enjoy
Another example for you.
This one calls the HSerReceive() function rather than the subroutine.
:-)
Using the subroutine is faster but may use an addition byte of RAM.
HSerReceive( inbyte, 3)
whereinbyte
is the target byte rather than= HSerReceive(3)
.Serial Buffer Ring
I have completed testing of the Serial Buffer Ring. This program has an interrupt on the USART RX and puts the incoming data into a buffer. The main program then HserPrint the data on the terminal.
This buffer is well known, and, is documented in the Help ( I will update to add the AVRDX example).
The program main loops, when there is new data in the buffer then
bkbhit
will be true. Then, the next byte out of the buffer is obtain via the function bgetc().The proves the interrupt handler of the compiler is working.
The source program has the GCBASIC instruction
On Interrupt USART3_RXC Call readUSART
This instructs the compiler toSEI
and enable the USART3_RXC interrupt. The USART3_RXC interrupt enable bit is in the DAT/Interrupts section.The interrupt vector is set and
.ORG 74
rjmp IntUSART3_RXC ;USART3_RXC
And, the handler added. The context is saved as required and is managed by GCBASIC, with automatically saving of all solution specific variables.
The compiler version required is 1416.
The compiler needed to be update to handle the AVRDx interrupt definitions. The DAT file requires for each interrupt
Name, Interrupt Handler Name, vector address, enable bit, and interrupt flag
Explanation
USART3_RXC:USART3_RXC,74,USART3_CTRLA.USART_RXCIE_bp,USART3_STATUS.USART_RXCIF_bp
The compiler did not support
REGISTER.BITNAME_AS_CONSTANT
. The compiler did supportREGISTER.bit_number_constant
orbit_name_constant
. Noting thatbit_name_constant
prior to AVRDx was unique so this worked.The compiler now also supports
REGISTER.BITNAME_AS_CONSTANT
The compiler resolve this toREGISTER.bit_number_constant
which works great.Summary
New compiler - 1416
New DAT file - I have added the interrupt information for serial.
No updates to USART.H required.
Attached is the test program.
If you would like to try this. I can upload the files for you. I am concerned that we are updating the main release to often. I am getting feedback to reduce the number of releases/updates. Let me know if you can test.
Evan
Regarding 40_MEGA4809_USART_RXTX .gcb gave me a warning message(see attachment) when I compiled and did NOT return characters when typed. It did display the message "Started: Serial between two devices" on Realterm.
You need the new compiler, DAT file and USART.h
I will zip for you on my Monday morning.
Evan
Evan, Looks like you've been extremely busy!
I think the Progmem "data" is possible on the avr-0/1 series chips using the NVM controller.
If my memory serves me, in the older MCUs like the m328P, only the bootloader can do the SPM(Store Program Memory)in a routine. You have to define and set the bootloader section with fuses, then write from that section.
In the avr-0/1 series, BOOT section can write to APP section and the APP section can write to the APPDATA section. --BUT--- there are 2 fuses that set this up and they need to be set correctly and FUSES can only be set by UPDI. Might make it a pain for the end user.
I will attempt to get working code for m4809 storing in Progmem FLASH .
The 328P has 1024 bytes of EEPROM which is a lot easier to write than something like a bootloader.
thanks
G
I worked on the USART. Not a huge amount of changes but the testing was a lot of work.
Memory - we have legacy AVR memory write/read PROGMEM and EEPROM. It these operations that are needed for the m4809/AVRDx chips.
DATA blocks are only useful if PROGMEM read works!
So, PROGMEM write and read and DATA block is the goal.
Re fuses. Assume they are correct. The user has to set these correctly.
I am now working the Timers. When I get your Timer ASM integrated then I will test GCBASIC interrupt handler.
Last edit: Anobium 2024-08-26
Build 1416 - https://1drv.ms/u/s!Ase-PX_n_4cvhP45TxJysh7wxNKMlQ?e=53iSBe
This build is focused on UART.H operations, and the interrupt handler for USART. The compiler now caches correctly upon an interrupt, the DAT file has these interrupt bits.
Instructions are in the ZIP. You may have to UNBLOCK these file using the Windows properties for the EXE's.
This version also compiles the generated ASM in AVR2ASM. This is always a good thing!
Enjoy!
Last edit: Anobium 2024-08-26
RTC with Interrupt
I started to look at the Timers. However, came across the RTC in the datasheet. Sad.
Attached is RTC with Interrupt example. Should work with LED on PORTF.5
Flashes the LED every 1 sec - with the RTC. Nice.
I have put this in the ZIP.
Compiled and loaded hex from "40_MEGA4809_USART_RXTX .gcb" in the 'Demos' directory that you sent with the Build 1416 package .
it says "Started: Serial between two devices" and echoes back any character typed .
Looks Good... Congratulations!
will look at RTC.
Here is the code to read internal 256 byte EEPROM
Here is the code to write internal 256 byte EEPROM . USART set to 57600
Code to Write a page at once. Read delay is 500ms...Slow.
Compiled " 50_MEGA4809_RTC_Interrupt .gcb " and it ran successfully on my Hardware.
Thanks for the EE routines. I have downloaded and I have updated the tracker ( as the start of this thread).
We also have USERROW which gives us another 64 bytes of EEPROM. Evidently it operates like EE and you can write a single byte at a time while CPU running. Working on Flash write Progmem at the moment.
Is USERROW addressable just like the rest of PROGMEM?
-----‐--
I am working on Timers.
Lots to do. But, I have your good work as the basis.
USERROW should read the same as the EEProm(according to the data sheet). It's address starts@ 0x1300 and ends 0x133F while EE is 0x1400 to 0x14FF.
In fact, I think all the AVR-0/1 processors have Unified Memory ... so you can read flash with an LD instruction. LD R18, X+ just remember that " dataMapped_PROGMEM" starts @ 0x4000 on the M4809.
That makes sense now.
PICs have HEF/SAF which is addressed in a similar way. I can add this information to the DAT files. Then, the address etc will be exposed.
Timer0
Timer0 for AVRDx works.
Interestingly, these AVRDx timers are different. They would be. :-)
The timers are not code-compatible (a different set of registers), but all functionalities present on legacy AVR are replicable using AVRDx timers.
GCBASIC replicates the legacy AVR functionality using AVRDx timers. This leaves all the new AVRDx timer functionality for the user to play with.
The GCBASIC commands are:
InitTimer()
SetTimer()
StartTimer()
StopTimer()
On Interrupt Timer0OverFlow
In Normal ( Coounter ) mode, the TCA Overflow output is not present on a pin, but the TCA can be used to generate an interrupt when the number of counting events reached the TCAn.CMPn value.
The GCBASIC uses the configuration of TCA to generate periodic interrupts on the overflow flag. This provides functional compatibility.
This program shows the functionality - the demos in the ZIP (see the link) are more comprehensive.
All very easy. The values for scaler and the period can be obtained from the Timer calculator in the demo folders.
Latest ZIP contains new library, compiler ( I tweaked ) and DAT file! All the files are to be used.
https://1drv.ms/u/s!Ase-PX_n_4cvhP45TxJysh7wxNKMlQ?e=7JRNLm
Speaking of timers, for the millis () function, There are four TCB type and one TCA type. The TCA timer would seem Ideal for millis() but you are left with TCB timers which have unity or /2 prescale capability. You can run TCB from TCA's prescaled input clock but they are then locked. ULP_OSC? Maybe I've put the cart before the horse ... anyway it's on my mind.
I will do millis() next. I think TCA may be the right way to go at 16mHz. I will have a go at this tomorrow.
Millis()
Millis() is now support on AVRDX for any of the valid frequencies ( supported by AVRDX ).
24, 20, 16, 10, 8, 5,4,2.5,2,1.25,1,0.625 and other little frequencies...
The program code below counts the millis for 1000 ( see the constant LEDRate ) and therefore the If - then statement means the LED toggles every 1000 ms.
The program code below is a standard demo to show this capability.
Files updated.
millis.h - add AVRDX capability
timer.h - change the inittimer0 function to NOT clear the enable state of the timer
mega4809.dat - improved interrupt handler
Download from https://1drv.ms/u/s!Ase-PX_n_4cvhP45TxJysh7wxNKMlQ?e=uyqMLF
Last edit: Anobium 2024-08-30
Re: millis() Great news. Tiny3217 works great. Which means the Timer library works and Millis().
See demo here https://github.com/GreatCowBASIC/Demonstration_Sources/blob/main/Millis%20Solutions/tiny3217_1s.gcb