void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) { uint8_t x; #ifdef MAX7456_DMA_CHANNEL_TX while (dma_transaction_in_progress); #endif while (max7456_lock); max7456_lock = 1; ENABLE_MAX7456; // disable display max7456_send(VM0_REG, video_signal_type); max7456_send(MAX7456ADD_CMAH, char_address); // set start address high for(x = 0; x < 54; x++) { max7456_send(MAX7456ADD_CMAL, x); //set start address low max7456_send(MAX7456ADD_CMDI, font_data[x]); #ifdef LED0_TOGGLE LED0_TOGGLE; #else LED1_TOGGLE; #endif } // transfer 54 bytes from shadow ram to NVM max7456_send(MAX7456ADD_CMM, WRITE_NVR); // wait until bit 5 in the status register returns to 0 (12ms) while ((max7456_send(MAX7456ADD_STAT, 0) & STATUS_REG_NVR_BUSY) != 0x00); max7456_send(VM0_REG, video_signal_type | 0x0C); DISABLE_MAX7456; max7456_lock = 0; }
void max7456_draw_screen(void) { if (!max7456_lock) { #ifdef MAX7456_DMA_CHANNEL_TX max7456_send_dma(max7456_screen, NULL, max_screen_size * 2 + 10); #else uint16_t xx; max7456_lock = 1; ENABLE_MAX7456; max7456_send(MAX7456ADD_DMAH, 0); max7456_send(MAX7456ADD_DMAL, 0); max7456_send(MAX7456ADD_DMM, 1); for (xx = 0; xx < max_screen_size; ++xx) { max7456_send(MAX7456ADD_DMDI, SCREEN_BUFFER[xx]); SCREEN_BUFFER[xx] = MAX7456_CHAR(' '); } max7456_send(MAX7456ADD_DMDI, 0xFF); max7456_send(MAX7456ADD_DMM, 0); DISABLE_MAX7456; max7456_lock = 0; #endif } }
void max7456_init(uint8_t video_system) { uint8_t max_screen_rows; uint8_t srdata = 0; uint16_t x; #ifdef MAX7456_SPI_CS_PIN max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN)); #endif IOInit(max7456CsPin, OWNER_OSD, RESOURCE_SPI_CS, 0); IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG); //Minimum spi clock period for max7456 is 100ns (10Mhz) spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_CLOCK_STANDARD); delay(1000); // force soft reset on Max7456 ENABLE_MAX7456; max7456_send(VM0_REG, MAX7456_RESET); delay(100); srdata = max7456_send(0xA0, 0xFF); if ((0x01 & srdata) == 0x01) { //PAL video_signal_type = VIDEO_MODE_PAL; } else if ((0x02 & srdata) == 0x02) { //NTSC video_signal_type = VIDEO_MODE_NTSC; } // Override detected type: 0-AUTO, 1-PAL, 2-NTSC switch(video_system) { case PAL: video_signal_type = VIDEO_MODE_PAL; break; case NTSC: video_signal_type = VIDEO_MODE_NTSC; break; } if (video_signal_type) { //PAL max_screen_size = VIDEO_BUFFER_CHARS_PAL; max_screen_rows = VIDEO_LINES_PAL; } else { // NTSC max_screen_size = VIDEO_BUFFER_CHARS_NTSC; max_screen_rows = VIDEO_LINES_NTSC; } // set all rows to same charactor black/white level for(x = 0; x < max_screen_rows; x++) { max7456_send(MAX7456ADD_RB0 + x, BWBRIGHTNESS); } // make sure the Max7456 is enabled max7456_send(VM0_REG, OSD_ENABLE | video_signal_type); DISABLE_MAX7456; delay(100); for (x = 0; x < max_screen_size; x++) SCREEN_BUFFER[x] = MAX7456_CHAR(' '); #ifdef MAX7456_DMA_CHANNEL_TX max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8)); max7456_screen[1] = (uint16_t)(MAX7456ADD_DMAL | (0 << 8)); max7456_screen[2] = (uint16_t)(MAX7456ADD_DMM | (1 << 8)); max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8)); max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8)); dmaSetHandler(MAX7456_DMA_IRQ_HANDLER_ID, max7456_dma_irq_handler, NVIC_PRIO_MAX7456_DMA, 0); #endif }