diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 83108e3..b5e1b1c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable(${PROJECT_NAME} main.c ch32fun.c + #blink/blink.c ) target_include_directories(${PROJECT_NAME} PUBLIC @@ -9,6 +10,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC ) target_link_libraries(${PROJECT_NAME} PRIVATE + blink gcc ) diff --git a/src/blink/CMakeLists.txt b/src/blink/CMakeLists.txt new file mode 100644 index 0000000..3226cf8 --- /dev/null +++ b/src/blink/CMakeLists.txt @@ -0,0 +1,43 @@ +add_library(blink STATIC + blink.c +) + +target_include_directories(blink PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +if(NOT UNIT_TESTING) +# The `-ffunction-sections` and `-fdata-sections` need to be used +# in the compile and linker options otherwise it doesnt't +# correctly remove the unused functions. + target_compile_options(blink PUBLIC + -g + -Os + -flto + -ffunction-sections + -fdata-sections + -fmessage-length=0 + -msmall-data-limit=8 + -march=rv32ec + -mabi=ilp32e + -DCH32V003=1 + ) + +# target_link_options(blink PUBLIC +# -flto +# -ffunction-sections +# -fdata-sections +# -fmessage-length=0 +# -msmall-data-limit=8 +# -march=rv32ec +# -mabi=ilp32e +# -static-libgcc +# -nostdlib +# -L${CMAKE_SOURCE_DIR}/src +# -Wl,--print-memory-usage +# -Wl,-Map=${PROJECT_NAME}.map +# -Wl,--gc-sections +# -T${CMAKE_SOURCE_DIR}/src/linker_script.ld +# ) +endif() + diff --git a/src/blink/blink.c b/src/blink/blink.c new file mode 100644 index 0000000..fdae86f --- /dev/null +++ b/src/blink/blink.c @@ -0,0 +1,34 @@ +/* + * Author: username + * Date: 2025 + * filename: blink.c + * description: module_purpose + */ + +#include "blink.h" +// #include + +// Define the function pointer (initialized to NULL) +DelayFunction delay_ms = 0; + +// Returns without caling if function pointer wasn't defined. +void blink_led(unsigned int times) +{ + if (!delay_ms) + { + return; + } + + for (int i = 0; i < times; i++) + { + // Sets the gpio pin(high). + *GPIO_PORT_BSHR |= (1 << 0); + + delay_ms(500); + + // Resets the gpio pin(low). + *GPIO_PORT_BSHR |= (1 << (0 + 16)); + + delay_ms(500); + } +} diff --git a/src/blink/blink.h b/src/blink/blink.h new file mode 100644 index 0000000..be8f342 --- /dev/null +++ b/src/blink/blink.h @@ -0,0 +1,20 @@ +/* + * Author: Jake G + * Date: 2025 + * filename: BLINK.h + * description: blink LED(for testing.) + */ + +#ifndef BLINK_H +#define BLINK_H + +#include + +extern volatile uint32_t *GPIO_PORT_BSHR; + +typedef void (*DelayFunction)(unsigned int ms); +extern DelayFunction delay_ms; + +void blink_led(unsigned int times); + +#endif // BLINK_H diff --git a/src/linker_script.ld b/src/linker_script.ld index 04285fc..150dc59 100644 --- a/src/linker_script.ld +++ b/src/linker_script.ld @@ -46,7 +46,7 @@ SECTIONS *(.gnu.linkonce.t.*) /* Include additional object files. */ - *(EXTERN(*)) /* Link against external symbols */ + /* *(EXTERN(*)) /* Link against external symbols */ . = ALIGN(4); } >FLASH AT>FLASH @@ -147,6 +147,13 @@ SECTIONS *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) + + /* Trying to include datasections for external object files.*/ + /* + * *(.data) + * *(.data.*) + */ + . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH diff --git a/src/main.c b/src/main.c index c7e893f..e2cd639 100644 --- a/src/main.c +++ b/src/main.c @@ -1,43 +1,54 @@ #include "ch32fun.h" +#include #include #define ADC_BUFFER_SIZE 32 -//globals +// external defines. +volatile uint32_t *GPIO_PORT_BSHR = &GPIOD->BSHR; + +// globals volatile uint16_t adc_buffer[ADC_BUFFER_SIZE] = {0}; -volatile uint16_t avg = 0; +volatile uint16_t avg = 0; -//Function Prototypes. -void ADC_DMA_Init(void); +// Function Prototypes. +void ADC_DMA_Init(void); -void GPIO_Init(void); -void DMA_Init(void); -void ADC_Init(void); +void GPIO_Init(void); +void DMA_Init(void); +void ADC_Init(void); -uint16_t ADC_Read(void) { - //while (!(ADC1->STATR & ADC_FLAG_EOC)); // Wait for conversion to complete +uint16_t ADC_Read(void) +{ + // while (!(ADC1->STATR & ADC_FLAG_EOC)); // Wait for conversion to complete return ADC1->RDATAR; // Return ADC value } - int main(void) { SystemInit(); - + printf("DMA ADC TESTING\r\n"); DMA_Init(); - GPIO_Init(); - ADC_Init(); - + GPIO_Init(); + ADC_Init(); + + // set delay fp. + // delay_ms = Delay_Ms; + + blink_led(5); + uint16_t old_value = UINT16_MAX; printf("DMA_Channel1->CNTR: %d\r\n", (uint16_t)DMA1_Channel1->CNTR); - if(!(ADC1->STATR & ADC_FLAG_EOC)){ + if (!(ADC1->STATR & ADC_FLAG_EOC)) + { printf("ADC1 Status register EOC: False\r\n"); } - if(!(DMA1_Channel1->CFGR & DMA_CFGR1_EN)){ + if (!(DMA1_Channel1->CFGR & DMA_CFGR1_EN)) + { printf("DMA1 Channel1 isn't enabled!\r\n"); } @@ -50,24 +61,27 @@ int main(void) } */ - while(1){ + while (1) + { printf("ADC_BUFFER: "); - for(int i = 0; i < ADC_BUFFER_SIZE; i++){ - printf("%d ", adc_buffer[i]); + for (int i = 0; i < ADC_BUFFER_SIZE; i++) + { + printf("%d ", adc_buffer[i]); } printf("\r\n"); } - while(1){ - //printf("ADC reading: %d\r\n", avg); - //Delay_Ms(1000); - if(avg != old_value){ + while (1) + { + // printf("ADC reading: %d\r\n", avg); + // Delay_Ms(1000); + if (avg != old_value) + { old_value = avg; printf("ADC reading: %d\r\n", avg); Delay_Ms(500); } } - } void GPIO_Init(void) @@ -76,14 +90,12 @@ void GPIO_Init(void) // Enable the clock for the GPIO port it's on RCC->APB2PCENR |= RCC_APB2Periph_GPIOC; - + // Configure the GPIO pin C4 as analog input. bits[19:16] // CFN(config): Analog, Mode: Input - GPIOC->CFGLR &= ~(0xf<<(4*4)); - + GPIOC->CFGLR &= ~(0xf << (4 * 4)); } - void ADC_Init(void) { printf("ADC_Init()\r\n"); @@ -95,44 +107,43 @@ void ADC_Init(void) RCC->APB2PRSTR |= RCC_APB2Periph_ADC1; RCC->APB2PRSTR &= ~RCC_APB2Periph_ADC1; - //I don't change the prescaler, because I'm not using an external crystal. - //RCC->CFGR |= (0x1F<<11); //Sets the prescaler for div128. + // I don't change the prescaler, because I'm not using an external crystal. + // RCC->CFGR |= (0x1F<<11); //Sets the prescaler for div128. // Enable ADC scanning - ADC1->CTLR1 |= ADC_SCAN; + ADC1->CTLR1 |= ADC_SCAN; - // Configure the ADC + // Configure the ADC // -- Set the ADON bit. - ADC1->CTLR2 |= (1<<0); + ADC1->CTLR2 |= (1 << 0); // -- Set the External selection to SWSTART ADC1->CTLR2 |= ADC_EXTSEL; // -- Enable DMA for the ADC DMA_Enable --> bit8 - ADC1->CTLR2 |= (1<<8); - + ADC1->CTLR2 |= (1 << 8); + // -- Set the ADC conversion for continuous - ADC1->CTLR2 |= (1<<1); + ADC1->CTLR2 |= (1 << 1); // -- Set ADC sample time. 3 offset, channel 2 // Sets the sampling to 3 cycles. - ADC1->SAMPTR2 &= ~(0xf<<(3*2)); + ADC1->SAMPTR2 &= ~(0xf << (3 * 2)); // Select ADC channel - ADC1->RSQR1 = 0; // RSQR1 L num ch conversions = 1 - ADC1->RSQR2 = 0; + ADC1->RSQR1 = 0; // RSQR1 L num ch conversions = 1 + ADC1->RSQR2 = 0; ADC1->RSQR3 = 2; // Start ADC conversion SWSTART bit 22 - ADC1->CTLR2 |= (1<<22); + ADC1->CTLR2 |= (1 << 22); } - void DMA_Init(void) { - //NOTE: Most of this could be a single line for the CFGR but this is more - //explicit. - //NOTE: See page 66 in the RM for figuring out the needed DMA channel. + // NOTE: Most of this could be a single line for the CFGR but this is more + // explicit. + // NOTE: See page 66 in the RM for figuring out the needed DMA channel. printf("DMA_Init()\r\n"); @@ -149,54 +160,54 @@ void DMA_Init(void) DMA1_Channel1->CNTR = ADC_BUFFER_SIZE; // Set the DMA channel priority, bits[13:12] - DMA1_Channel1->CFGR = 0; //clear it. - DMA1_Channel2->CFGR &= ~((1<<12)|(1<<13)); //sets PL to low + DMA1_Channel1->CFGR = 0; // clear it. + DMA1_Channel2->CFGR &= ~((1 << 12) | (1 << 13)); // sets PL to low // Set the direction of data transfer, mode and datawidth for src & dst // along with th, tc and te interrupt enable bits. - + // Set the mem2mem as false. - DMA1_Channel1->CFGR &= ~(1<<14); + DMA1_Channel1->CFGR &= ~(1 << 14); // Set dir as Peripheral to memory. - DMA1_Channel1->CFGR &= ~(1<<4); + DMA1_Channel1->CFGR &= ~(1 << 4); // Set the datawidth for source and destination as 16bits. - //DMA1_Channel1->CFGR |= (1<<10); - //DMA1_Channel1->CFGR |= (1<<8); + // DMA1_Channel1->CFGR |= (1<<10); + // DMA1_Channel1->CFGR |= (1<<8); DMA1_Channel1->CFGR |= DMA_PeripheralDataSize_HalfWord; DMA1_Channel1->CFGR |= DMA_MemoryDataSize_HalfWord; // Set circular mode. - DMA1_Channel1->CFGR |= (1<<5); + DMA1_Channel1->CFGR |= (1 << 5); // Enable memory address increment. - DMA1_Channel1->CFGR |= (1<<7); + DMA1_Channel1->CFGR |= (1 << 7); - //Enable IRQ - //NVIC_EnableIRQ(DMA1_Channel1_IRQn); + // Enable IRQ + // NVIC_EnableIRQ(DMA1_Channel1_IRQn); // Set the transfer complete interrupt. - DMA1_Channel1->CFGR |= (1<<1); + DMA1_Channel1->CFGR |= (1 << 1); // Set the enable bit in DMA_CCRx register to start channel x - DMA1_Channel1->CFGR |= (1<<0); - + DMA1_Channel1->CFGR |= (1 << 0); } - void DMA1_Channel1_IRQHandler(void) __attribute__((interrupt)); void DMA1_Channel1_IRQHandler() { - if(DMA1->INTFR & DMA1_FLAG_TC1) { + if (DMA1->INTFR & DMA1_FLAG_TC1) + { DMA1->INTFCR = DMA_CTCIF1; printf("DMA ISR!\r\n"); - //current_write_buffer = current_read_buffer; + // current_write_buffer = current_read_buffer; avg = 0; - for(int i = 0; i < ADC_BUFFER_SIZE; i++){ + for (int i = 0; i < ADC_BUFFER_SIZE; i++) + { avg += adc_buffer[i]; } - //Divide it by 32 + // Divide it by 32 avg = avg >> 5; DMA_Init(); } diff --git a/tests/AllTests.cpp b/tests/AllTests.cpp index 2d7a3f0..8552708 100644 --- a/tests/AllTests.cpp +++ b/tests/AllTests.cpp @@ -5,6 +5,7 @@ IMPORT_TEST_GROUP(simple_test); IMPORT_TEST_GROUP(test_ADC); IMPORT_TEST_GROUP(test_RegEdit); +IMPORT_TEST_GROUP(test_blink); //START: main int main(int argc, char** argv) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1662553..c309afd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,7 @@ project(Tests) # TEST_DIRS +add_subdirectory(blink) add_subdirectory(MockRegEdit) add_subdirectory(RegEdit) add_subdirectory(simple_test) @@ -19,6 +20,7 @@ target_link_libraries(AllTests ${CPPUTEST_LIBRARIES}/libCppUTest.a ${CPPUTEST_LIBRARIES}/libCppUTestExt.a # TEST_LINKS + test_blink test_ADC test_RegEdit simple_test diff --git a/tests/blink/CMakeLists.txt b/tests/blink/CMakeLists.txt new file mode 100644 index 0000000..031b018 --- /dev/null +++ b/tests/blink/CMakeLists.txt @@ -0,0 +1,10 @@ +# TEST_RUNNER +add_library(test_blink + test_blink.cpp +) + +target_link_libraries(test_blink + ${CPPUTEST_LIBRARIES}/libCppUTest.a + ${CPPUTEST_LIBRARIES}/libCppUTestExt.a + blink +) diff --git a/tests/blink/test_blink.cpp b/tests/blink/test_blink.cpp new file mode 100644 index 0000000..d5792ed --- /dev/null +++ b/tests/blink/test_blink.cpp @@ -0,0 +1,61 @@ +/* + * Author: username + * Date: todays_date + * filename: test_blink.c + * description: module_purpose + */ + +#include "CppUTest/CommandLineTestRunner.h" + +extern "C" +{ +#include "blink.h" +} + +volatile uint32_t fake_bshr_reg = 0; +volatile uint32_t* GPIO_PORT_BSHR = &fake_bshr_reg; + +unsigned int called; +void fake_delay(unsigned int ms) +{ + called += 1; + return; +} + +TEST_GROUP(test_blink) +{ + void setup() + { + fake_bshr_reg = 0; + called = 0; + } + void teardown() + { + + } +}; + + +TEST(test_blink, UninitializedFuncPointer) +{ + blink_led(5); + CHECK_EQUAL(0, fake_bshr_reg); +} + +TEST(test_blink, BlinkChangesReg) +{ + //Set the function pointer. + delay_ms = fake_delay; + + blink_led(1); + + CHECK_EQUAL_TEXT(2, called, "Delay function not called expeced number of times"); + + CHECK(fake_bshr_reg & (1<<0)); + CHECK(fake_bshr_reg & (1<<(0+16))); + + //Unset function pointer + delay_ms = 0; +} + +