From afe12bca23b106a18796bf6ed793ff1389bdddb2 Mon Sep 17 00:00:00 2001 From: Damien Date: Sat, 19 Oct 2013 18:13:48 +0100 Subject: [PATCH] Fix IRQ priority issue to give working USB; and some cleanup. --- stm/Makefile | 5 +- stm/lib/usb_bsp.c | 12 +-- stm/lib/usbd_storage_msd.c | 9 ++- stm/lib/usbd_usr.c | 16 ++-- stm/main.c | 161 ++++--------------------------------- stm/mma.c | 128 +++++++++++++++++++++++++++++ stm/mma.h | 7 ++ stm/storage.c | 8 ++ stm/storage.h | 2 + stm/systick.c | 1 + 10 files changed, 185 insertions(+), 164 deletions(-) create mode 100644 stm/mma.c create mode 100644 stm/mma.h diff --git a/stm/Makefile b/stm/Makefile index a305a9bcab..b7e565e9aa 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -18,6 +18,7 @@ SRC_C = \ lcd.c \ flash.c \ storage.c \ + mma.c \ string0.c \ malloc0.c \ systick.c \ @@ -29,10 +30,10 @@ SRC_S = \ startup_stm32f40xx.s \ PY_O = \ -# nlrthumb.o \ + nlrthumb.o \ malloc.o \ qstr.o \ -# misc.o \ + misc.o \ lexer.o \ parse.o \ scope.o \ diff --git a/stm/lib/usb_bsp.c b/stm/lib/usb_bsp.c index 293ee95e20..c4839bdf96 100644 --- a/stm/lib/usb_bsp.c +++ b/stm/lib/usb_bsp.c @@ -106,8 +106,8 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) { GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG1_FS); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG1_FS); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG_FS); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG_FS); /* Configure VBUS Pin (or disable VBUS_SENSING_ENABLED) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; @@ -123,16 +123,16 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) { /** * @brief USB_OTG_BSP_EnableInterrupt -* Enabele USB Global interrupt +* Enable USB Global interrupt * @param None * @retval None */ void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) { + // this assumes we use NVIC_PriorityGroup_4 NVIC_InitTypeDef NVIC_InitStructure; - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } diff --git a/stm/lib/usbd_storage_msd.c b/stm/lib/usbd_storage_msd.c index 47790bb110..afdd47865d 100644 --- a/stm/lib/usbd_storage_msd.c +++ b/stm/lib/usbd_storage_msd.c @@ -28,6 +28,9 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_msc_mem.h" #include "usb_conf.h" + +#include "misc.h" +#include "storage.h" #include "diskio.h" /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY @@ -198,9 +201,9 @@ int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_si */ - *block_size = 512; + *block_size = storage_get_block_size(); //*block_num = SDCardInfo.CardCapacity / 512; - *block_num = 256 + 128; + *block_num = storage_get_block_count(); return (0); @@ -305,7 +308,7 @@ int8_t STORAGE_Write (uint8_t lun, while (SD_GetStatus() != SD_TRANSFER_OK); #endif */ - disk_write(0, buf, blk_addr, blk_len); + //disk_write(0, buf, blk_addr, blk_len); return (0); } diff --git a/stm/lib/usbd_usr.c b/stm/lib/usbd_usr.c index 844a3ed7f5..a5a7fb7ffb 100644 --- a/stm/lib/usbd_usr.c +++ b/stm/lib/usbd_usr.c @@ -46,8 +46,8 @@ USBD_Usr_cb_TypeDef USR_cb = { * @retval None */ void USBD_USR_Init() { - printf("USB OTG FS\n"); - printf("USB device start\n"); + //printf("USB OTG FS\n"); + //printf("USB device start\n"); } /** @@ -57,7 +57,7 @@ void USBD_USR_Init() { * @retval None */ void USBD_USR_DeviceReset(uint8_t speed) { - printf("USB reset %d\n", speed); + //printf("USB reset %d\n", speed); } /** @@ -67,7 +67,7 @@ void USBD_USR_DeviceReset(uint8_t speed) { * @retval Staus */ void USBD_USR_DeviceConfigured() { - printf("USB dev config\n"); + //printf("USB dev config\n"); } /** @@ -77,7 +77,7 @@ void USBD_USR_DeviceConfigured() { * @retval None */ void USBD_USR_DeviceSuspended() { - printf("USB dev suspend\n"); + //printf("USB dev suspend\n"); } /** @@ -87,7 +87,7 @@ void USBD_USR_DeviceSuspended() { * @retval None */ void USBD_USR_DeviceResumed() { - printf("USB dev resume\n"); + //printf("USB dev resume\n"); } @@ -98,7 +98,7 @@ void USBD_USR_DeviceResumed() { * @retval Staus */ void USBD_USR_DeviceConnected() { - printf("USB dev connect\n"); + //printf("USB dev connect\n"); } @@ -109,7 +109,7 @@ void USBD_USR_DeviceConnected() { * @retval Staus */ void USBD_USR_DeviceDisconnected() { - printf("USB dev disconn\n"); + //printf("USB dev disconn\n"); } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/stm/main.c b/stm/main.c index ca14d1ce9d..e06e119a55 100644 --- a/stm/main.c +++ b/stm/main.c @@ -9,6 +9,7 @@ #include "led.h" #include "lcd.h" #include "storage.h" +#include "mma.h" #include "usb.h" static void impl02_c_version() { @@ -26,137 +27,6 @@ static void impl02_c_version() { } } -void set_bits(__IO uint32_t *addr, uint32_t shift, uint32_t mask, uint32_t value) { - uint32_t x = *addr; - x &= ~(mask << shift); - x |= (value << shift); - *addr = x; -} - -void gpio_init() { - RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOAEN; -} - -/* -void gpio_pin_af(GPIO_TypeDef *gpio, uint32_t pin, uint32_t af) { - // set the AF bits for the given pin - // pins 0-7 use low word of AFR, pins 8-15 use high word - set_bits(&gpio->AFR[pin >> 3], 4 * (pin & 0x07), 0xf, af); -} -*/ - -static void mma_init() { - // XXX - RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1 - //gpio_pin_init(GPIOB, 6 /* B6 is SCL */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */); - //gpio_pin_init(GPIOB, 7 /* B7 is SDA */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */); - //gpio_pin_af(GPIOB, 6, 4 /* AF 4 for I2C1 */); - //gpio_pin_af(GPIOB, 7, 4 /* AF 4 for I2C1 */); - - // get clock speeds - RCC_ClocksTypeDef rcc_clocks; - RCC_GetClocksFreq(&rcc_clocks); - - // disable the I2C peripheral before we configure it - I2C1->CR1 &= ~I2C_CR1_PE; - - // program peripheral input clock - I2C1->CR2 = 4; // no interrupts; 4 MHz (hopefully!) (could go up to 42MHz) - - // configure clock control reg - uint32_t freq = rcc_clocks.PCLK1_Frequency / (100000 << 1); // want 100kHz, this is the formula for freq - I2C1->CCR = freq; // standard mode (speed), freq calculated as above - - // configure rise time reg - I2C1->TRISE = (rcc_clocks.PCLK1_Frequency / 1000000) + 1; // formula for trise, gives maximum rise time - - // enable the I2C peripheral - I2C1->CR1 |= I2C_CR1_PE; - - // set START bit in CR1 to generate a start cond! -} - -static uint32_t i2c_get_sr() { - // must read SR1 first, then SR2, as the read can clear some flags - uint32_t sr1 = I2C1->SR1; - uint32_t sr2 = I2C1->SR2; - return (sr2 << 16) | sr1; -} - -static void mma_restart(uint8_t addr, int write) { - // send start condition - I2C1->CR1 |= I2C_CR1_START; - - // wait for BUSY, MSL and SB --> Slave has acknowledged start condition - while ((i2c_get_sr() & 0x00030001) != 0x00030001) { - } - - if (write) { - // send address and write bit - I2C1->DR = (addr << 1) | 0; - // wait for BUSY, MSL, ADDR, TXE and TRA - while ((i2c_get_sr() & 0x00070082) != 0x00070082) { - } - } else { - // send address and read bit - I2C1->DR = (addr << 1) | 1; - // wait for BUSY, MSL and ADDR flags - while ((i2c_get_sr() & 0x00030002) != 0x00030002) { - } - } -} - -static void mma_start(uint8_t addr, int write) { - // wait until I2C is not busy - while (I2C1->SR2 & I2C_SR2_BUSY) { - } - - // do rest of start - mma_restart(addr, write); -} - -static void mma_send_byte(uint8_t data) { - // send byte - I2C1->DR = data; - // wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted) - int timeout = 1000000; - while ((i2c_get_sr() & 0x00070084) != 0x00070084) { - if (timeout-- <= 0) { - printf("mma_send_byte timed out!\n"); - break; - } - } -} - -static uint8_t mma_read_ack() { - // enable ACK of received byte - I2C1->CR1 |= I2C_CR1_ACK; - // wait for BUSY, MSL and RXNE (byte received) - while ((i2c_get_sr() & 0x00030040) != 0x00030040) { - } - // read and return data - uint8_t data = I2C1->DR; - return data; -} - -static uint8_t mma_read_nack() { - // disable ACK of received byte (to indicate end of receiving) - I2C1->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK); - // last byte should apparently also generate a stop condition - I2C1->CR1 |= I2C_CR1_STOP; - // wait for BUSY, MSL and RXNE (byte received) - while ((i2c_get_sr() & 0x00030040) != 0x00030040) { - } - // read and return data - uint8_t data = I2C1->DR; - return data; -} - -static void mma_stop() { - // send stop condition - I2C1->CR1 |= I2C_CR1_STOP; -} - #define PYB_USRSW_PORT (GPIOA) #define PYB_USRSW_PIN (GPIO_Pin_13) @@ -200,7 +70,6 @@ void __fatal_error(const char *msg) { #include "compile.h" #include "runtime.h" -#if 0 py_obj_t pyb_delay(py_obj_t count) { sys_tick_delay_ms(rt_get_int(count)); return py_const_none; @@ -218,14 +87,13 @@ py_obj_t pyb_sw() { return py_const_false; } } -#endif #include "ff.h" FATFS fatfs0; +#include "nlr.h" /* -#include "nlr.h" void g(uint i) { printf("g:%d\n", i); if (i & 1) { @@ -262,7 +130,7 @@ void fatality() { led_state(PYB_LED_G2, 1); } -static const char *fresh_boot_py = +static const char fresh_boot_py[] = "# boot.py -- run on boot-up\n" "# can run arbitrary Python, but best to keep it minimal\n" "\n" @@ -316,9 +184,14 @@ static void board_info() { int main() { // TODO disable JTAG + // set interrupt priority config to use all 4 bits for pre-empting + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); + + // enable the CCM RAM and the GPIO's + RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; + // basic sub-system init sys_tick_init(); - gpio_init(); led_init(); // turn on LED to indicate bootup @@ -330,8 +203,8 @@ int main() { storage_init(); // Python init - //qstr_init(); - //rt_init(); + qstr_init(); + rt_init(); // print a message printf(" micro py board\n"); @@ -356,8 +229,8 @@ int main() { __fatal_error("could not create LFS"); } - // keep LED on for at least 100ms - sys_tick_wait_at_least(stc, 100); + // keep LED on for at least 200ms + sys_tick_wait_at_least(stc, 200); led_state(PYB_LED_R2, 0); } else { __fatal_error("could not access LFS"); @@ -390,8 +263,8 @@ int main() { // TODO check we could write n bytes f_close(&fp); - // keep LED on for at least 100ms - sys_tick_wait_at_least(stc, 100); + // keep LED on for at least 200ms + sys_tick_wait_at_least(stc, 200); led_state(PYB_LED_R2, 0); } } @@ -419,7 +292,6 @@ int main() { //printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init //sys_tick_delay_ms(1000); - #if 0 // Python! if (0) { //const char *pysrc = "def f():\n x=x+1\nprint(42)\n"; @@ -570,7 +442,6 @@ int main() { } } } - #endif // benchmark C version of impl02.py if (0) { @@ -663,7 +534,7 @@ int main() { led_state(PYB_LED_G1, 0); } if (sys_tick_has_passed(stc, 500)) { - stc = sys_tick_counter; + stc += 500; led_toggle(PYB_LED_G2); } } diff --git a/stm/mma.c b/stm/mma.c new file mode 100644 index 0000000000..e56608ef4c --- /dev/null +++ b/stm/mma.c @@ -0,0 +1,128 @@ +#include + +#include +#include +#include + +#include "mma.h" + +void mma_init() { + RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1 + //gpio_pin_init(GPIOB, 6 /* B6 is SCL */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */); + //gpio_pin_init(GPIOB, 7 /* B7 is SDA */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */); + //gpio_pin_af(GPIOB, 6, 4 /* AF 4 for I2C1 */); + //gpio_pin_af(GPIOB, 7, 4 /* AF 4 for I2C1 */); + // XXX untested GPIO init! (was above code) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; + GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); + + // get clock speeds + RCC_ClocksTypeDef rcc_clocks; + RCC_GetClocksFreq(&rcc_clocks); + + // disable the I2C peripheral before we configure it + I2C1->CR1 &= ~I2C_CR1_PE; + + // program peripheral input clock + I2C1->CR2 = 4; // no interrupts; 4 MHz (hopefully!) (could go up to 42MHz) + + // configure clock control reg + uint32_t freq = rcc_clocks.PCLK1_Frequency / (100000 << 1); // want 100kHz, this is the formula for freq + I2C1->CCR = freq; // standard mode (speed), freq calculated as above + + // configure rise time reg + I2C1->TRISE = (rcc_clocks.PCLK1_Frequency / 1000000) + 1; // formula for trise, gives maximum rise time + + // enable the I2C peripheral + I2C1->CR1 |= I2C_CR1_PE; + + // set START bit in CR1 to generate a start cond! +} + +static uint32_t i2c_get_sr() { + // must read SR1 first, then SR2, as the read can clear some flags + uint32_t sr1 = I2C1->SR1; + uint32_t sr2 = I2C1->SR2; + return (sr2 << 16) | sr1; +} + +void mma_restart(uint8_t addr, int write) { + // send start condition + I2C1->CR1 |= I2C_CR1_START; + + // wait for BUSY, MSL and SB --> Slave has acknowledged start condition + while ((i2c_get_sr() & 0x00030001) != 0x00030001) { + } + + if (write) { + // send address and write bit + I2C1->DR = (addr << 1) | 0; + // wait for BUSY, MSL, ADDR, TXE and TRA + while ((i2c_get_sr() & 0x00070082) != 0x00070082) { + } + } else { + // send address and read bit + I2C1->DR = (addr << 1) | 1; + // wait for BUSY, MSL and ADDR flags + while ((i2c_get_sr() & 0x00030002) != 0x00030002) { + } + } +} + +void mma_start(uint8_t addr, int write) { + // wait until I2C is not busy + while (I2C1->SR2 & I2C_SR2_BUSY) { + } + + // do rest of start + mma_restart(addr, write); +} + +void mma_send_byte(uint8_t data) { + // send byte + I2C1->DR = data; + // wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted) + int timeout = 1000000; + while ((i2c_get_sr() & 0x00070084) != 0x00070084) { + if (timeout-- <= 0) { + printf("mma_send_byte timed out!\n"); + break; + } + } +} + +uint8_t mma_read_ack() { + // enable ACK of received byte + I2C1->CR1 |= I2C_CR1_ACK; + // wait for BUSY, MSL and RXNE (byte received) + while ((i2c_get_sr() & 0x00030040) != 0x00030040) { + } + // read and return data + uint8_t data = I2C1->DR; + return data; +} + +uint8_t mma_read_nack() { + // disable ACK of received byte (to indicate end of receiving) + I2C1->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK); + // last byte should apparently also generate a stop condition + I2C1->CR1 |= I2C_CR1_STOP; + // wait for BUSY, MSL and RXNE (byte received) + while ((i2c_get_sr() & 0x00030040) != 0x00030040) { + } + // read and return data + uint8_t data = I2C1->DR; + return data; +} + +void mma_stop() { + // send stop condition + I2C1->CR1 |= I2C_CR1_STOP; +} diff --git a/stm/mma.h b/stm/mma.h new file mode 100644 index 0000000000..88efa3ef25 --- /dev/null +++ b/stm/mma.h @@ -0,0 +1,7 @@ +void mma_init(); +void mma_restart(uint8_t addr, int write); +void mma_start(uint8_t addr, int write); +void mma_send_byte(uint8_t data); +uint8_t mma_read_ack(); +uint8_t mma_read_nack(); +void mma_stop(); diff --git a/stm/storage.c b/stm/storage.c index 89dbd97c6a..ce89bdf6fe 100644 --- a/stm/storage.c +++ b/stm/storage.c @@ -53,6 +53,14 @@ void storage_init() { } } +uint32_t storage_get_block_size() { + return BLOCK_SIZE; +} + +uint32_t storage_get_block_count() { + return FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS; +} + void storage_flush() { cache_flush(); } diff --git a/stm/storage.h b/stm/storage.h index 542329e4ba..e7895fd510 100644 --- a/stm/storage.h +++ b/stm/storage.h @@ -1,4 +1,6 @@ void storage_init(); +uint32_t storage_get_block_size(); +uint32_t storage_get_block_count(); void storage_flush(); bool storage_read_block(uint8_t *dest, uint32_t block); bool storage_write_block(const uint8_t *src, uint32_t block); diff --git a/stm/systick.c b/stm/systick.c index 172b754040..9464132e2d 100644 --- a/stm/systick.c +++ b/stm/systick.c @@ -8,6 +8,7 @@ void sys_tick_init() { // sys-tick interrupt called at 1ms intervals sys_tick_counter = 0; SysTick_Config(SystemCoreClock / 1000); + NVIC_SetPriority(SysTick_IRQn, 0); // make it highest priority } // called on SysTick interrupt